我是 Android 编程新手,对它只有非常基本的了解。我正在尝试了解基本的多线程。
我按照教程创建了一个基本线程并显示了一个progressDialog,它只是在单击按钮时将500条记录添加到数据库中。
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 类应该是静态的,否则可能会发生泄漏。
我还有 2 个按钮查看和清除,我为每个按钮使用相同的代码,只是 UpdateDB(); 成为 ViewDB(); 和 ClearDB();
代码编译并且 AddClick 工作完美,但如果我尝试使用 ViewClick 或 ClearClick 然后我的应用程序崩溃,在查看有时对话框显示几秒钟然后我的应用程序崩溃。
是不是资源泄露造成的?有人可以向我展示一个如何使处理程序静态的示例,以便我在使用它时避免问题。
该活动的完整源代码在这里:
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();
}
}
感谢您的时间。