私は Android プログラミングが初めてで、非常に基本的な知識しかありません。基本的なマルチスレッドを理解しようとしています。
基本的なスレッドを作成し、ボタンがクリックされたときにデータベースに 500 レコードを追加するだけの progressDialog を表示するためのチュートリアルに従いました。
public void btnAddClick(View v) {
// Create progress dialog to show status
dialog = ProgressDialog.show(MainActivity.this, "Loading", "Updating database...");
h = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
dialog.dismiss();
}
};
// Create a new thread
new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
// Time consuming task here
try {
Thread.sleep(1);
UpdateDB();
h.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
.start();
//UpdateDB();
}
このコードを使用すると、IDE 内で警告が表示されます。この Handler クラスは静的である必要があります。そうしないと、リークが発生する可能性があります。
View と Clear の 2 つのボタンがあります。それぞれに同じコードを使用し、UpdateDB(); だけを使用します。ViewDB(); になります。および ClearDB();
コードはコンパイルされ、AddClick は完全に機能しますが、ViewClick または ClearClick を使用しようとすると、アプリケーションがクラッシュします。View では、ダイアログが数秒間表示され、アプリケーションがクラッシュすることがあります。
それはリソースリークが原因ですか?誰かがハンドラーを静的にする方法の例を教えてください。使用中の問題を回避できます。
アクティビティの完全なソース コードは次のとおりです。
import android.app.Activity;
import android.app.ProgressDialog;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
protected ProgressDialog dialog;
protected Handler h;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
DBAdapter myDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkDataBase();
}
@Override
protected void onDestroy() {
super.onDestroy();
closeDB();
}
private void openDB() {
myDb = new DBAdapter(this);
myDb.open();
}
private void closeDB() {
myDb.close();
}
private void displayText(String message) {
TextView textView = (TextView) findViewById(R.id.textDisplay);
textView.setText(message);
}
public void btnAddClick(View v) {
// Create progress dialog to show status
dialog = ProgressDialog.show(MainActivity.this, "Please Wait", "Updating database...");
h = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
dialog.dismiss();
}
};
// Create a new thread
new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
// Time consuming task here
try {
Thread.sleep(1);
UpdateDB();
h.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
.start();
//UpdateDB();
}
public void btnClearClick(View v) {
// Create progress dialog to show status
dialog = ProgressDialog.show(MainActivity.this, "Please Wait", "Deleting database...");
h = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
dialog.dismiss();
}
};
// Create a new thread
new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
// Time consuming task here
try {
Thread.sleep(1);
ClearDB();
h.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
.start();
}
public void btnViewClick(View v) {
// Create progress dialog to show status
dialog = ProgressDialog.show(MainActivity.this, "Please Wait", "Displaying records...");
h = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
dialog.dismiss();
}
};
// Create a new thread
new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
// Time consuming task here
try {
Thread.sleep(1);
ViewDB();
h.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
.start();
}
// Display full database inside TextView
private void displayRecordSet(Cursor cursor) {
String message = "";
// populate the message from the cursor
// Reset cursor to start, checking to see if there's data:
if (cursor.moveToFirst()) {
do {
// Process the data:
int id = cursor.getInt(DBAdapter.COL_ROWID);
String make = cursor.getString(DBAdapter.COL_MAKE);
String model = cursor.getString(DBAdapter.COL_MODEL);
String year = cursor.getString(DBAdapter.COL_YEAR);
String tyreSize = cursor.getString(DBAdapter.COL_TYRESIZE);
String front = cursor.getString(DBAdapter.COL_FRONT);
String rear = cursor.getString(DBAdapter.COL_REAR);
// Append data to the message:
message += "id=" + id
+", make=" + make
+", model=" + model
+", year=" + year
+", tyreSize=" + tyreSize
+", front=" + front
+", rear=" + rear
+"\n";
} while(cursor.moveToNext());
}
// Close the cursor to avoid a resource leak.
cursor.close();
displayText(message);
}
// Checks database file exists during OnCreate();
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String DB_FULL_PATH = "/data/data/com.digitak.mytyrepressure/databases/myDb";
checkDB = SQLiteDatabase.openDatabase(DB_FULL_PATH , null,
SQLiteDatabase.OPEN_READONLY);
checkDB.close();
} catch (SQLiteException e) {
// database doesn't exist yet.
System.out.println("Database Doesnt Exist...Creating");
openDB();
}
return checkDB != null ? true : false;
}
// Adds 500 Records to the database for testing purposes
public void UpdateDB() {
int x = 0;
while (x < 500) {
myDb.insertRow("Ford", "KA", "1996-2003", "155/70R13", "31", "26");
x++;
}
}
public void ViewDB() {
Cursor cursor = myDb.getAllRows();
displayRecordSet(cursor);
}
public void ClearDB() {
myDb.deleteAll();
}
}
お時間をいただきありがとうございます。