1

私は 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();
    }

}

お時間をいただきありがとうございます。

4

2 に答える 2