0

メインアクティビティが開始され、連絡先のリストが入力され、すべての連絡先の今日の評価をユーザーに促し(promptUserForInput)、受け取ったすべての連絡先の評価をすぐに処理する必要があるAndroidアプリを作成しています。すべての連絡先に対してプロンプトを表示し、ユーザーから評価を取得するダイアログ ボックスを使用できると思いました。ただし、メイン スレッドはユーザーがすべてのユーザーの評価を入力し終えるのを待っていないため、以下のコードは失敗します。

これは、すべての連絡先名に対して do while ループのメイン アクティビティで呼び出している関数です。rating はグローバル変数です。

double rating=0;
private synchronized void promptUserForInput(String firstName, String lastName) {

    final String fname = firstName;
    final String lName = lastName;

    AlertDialog.Builder alert = new AlertDialog.Builder(this);
    String custName = firstName + " " + lastName;
    final EditText input = new EditText(this);
    alert.setTitle(custName);
    alert.setView(input);
    Log.v("Diva: in promptUserForInput", "setting positive buton");
    alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface arg0, int arg1) {
            Editable res = input.getText();
            if(res == null) {
                Log.v("Diva..", "In positivebutton..befoer getting rating res is null");
            }
            rating = Double.valueOf(input.getText().toString());
        }
    });

    alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            rating=0;
        }
    });

    alert.show();        

}

これの私の呼び出し元はpromptUserForInput()以下のようになります。

// get list of contacts in a cursor
Cursor cursor = ManageDataBaseActivity.queryDataBase(this,     
ManageDataBaseActivity.CONTACT_INFO_TABLE);

if(cursor.getCount()>0) {

    double totalRatingForStats=0;
    cursor.moveToFirst();
    do {
        String[] colNames = cursor.getColumnNames();
        Log.v("Diva Colum names = ", colNames[0] + " " + colNames[1] + " " + colNames[2] + " " + colNames[3]);

        String firstName = cursor.getString(cursor.getColumnIndex("FirstName"));

        Log.v("Diva ..:", firstName);
        String lastName = cursor.getString(cursor.getColumnIndex("LastName"));
        String key = ManageDataBaseActivity.getDbKey(firstName, lastName, 
                                    date, ManageDataBaseActivity.CUSTOMER_DATA_TABLE);
        promptUserForInput(firstName, lastName);
        double ratingReceived = rating;

        totalRatingForStats = totalRatingForStats+ratingReceived;
        // some more processing

                        ManageDataBaseActivity.insertValueToDB(ManageDataBaseActivity.
                                CONTACT_DATA_TABLE+" ", .....);
    } while(cursor.moveToNext());           
4

2 に答える 2

1

短い答え: しないでください。

長い答え: ユーザー入力を待っている間、GUI プログラムのメイン スレッドをブロックするべきではありません。代わりに、プログラムを続行させるイベントを発生させる続行ボタンを提供する必要があります。これを実現するにはいくつかの方法がありますが、最初に頭に浮かぶのはシグナルとセマフォです。

私は Android プログラミングに精通しているわけではありませんが、おそらくインテントに依存して、API に似たようなものがあるはずです。

于 2013-03-10T14:44:16.260 に答える
1

アクティビティのメイン スレッドでループすることは、一般的にあまり良い考えではありません。ただしpollNext()、カーソルから次のデータセットを取得するメソッドのようなものを実装し、クリック メソッドを次のように変更できます。

@Override
public void onClick(DialogInterface dialog, int which) {
    // do your rating stuff

    // reads the next dataset
    pollNext();

    // shows the next dialog
    // of course, firstName and lastName must be membervariables to make this work
    promptUserForInput(firstName, lastName); 
}

その背後にある考え方は非常に一般的で、MVC パターンでも使用されています。

于 2013-03-10T14:45:00.770 に答える