0

入力が有効かどうかを確認する必要がある場合に、AsyncTaskからの結果を同期する際に問題が発生します。

私のアプリケーションは、ユーザーにプロモーションコードをEditTextに入力するように求めています。プロモーションコードがデータベースにある場合、プロモーションコードに有効なラベルを付けたい。入力されたプロモーションコードがデータベースにない場合は、無効としてラベル付けされます。

これはボタンリスナーのコードです

        // Listens for Add button presses
    addButton.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            String promo_code = (String) PromotCodeEditText.getText().toString();

            // Start AsyncTask that will store true or false in checkCodeInDatabase variable
            // depending if PromoCode is in database. We use checkCodeInDatabase in else if check below.
            new CheckCodeDatabase().execute(promo_code);

            // Check if Promo Code that user typed is in database
            // checkCodeInDatabase is false if course is not in database
            if (!checkCodeInDatabase) {
                // Display No code in database alert dialog
                showMsgDialog(getString(R.string.noCodeDBTitle),
                        getString(R.string.noCodeDBMessage));

                courseCodeEditText.setText("");

            } else {
                // Add promo code user typed in EditText
                addCode(promo_code);
            }
        }
    });

私の考えでは、ユーザーが[追加]ボタンを押すと、プロモーションコードを追加するために、データベースに対してクエリを実行するAsyncTaskを開始します。AsyncTaskは、静的変数checkCodeInDatabaseにtrueまたはfalseを格納します。

AsyncTaskのコードは次のとおりです。

private class CheckCodeDatabase extends AsyncTask<String, Object, Boolean> {

    DataBaseHelper myDbHelper = new DataBaseHelper(MainActivity.this);

    @Override
    protected Boolean doInBackground(String... params)
    {
        try {
            myDbHelper.createDataBase();
        } catch (IOException ioe) {
            throw new Error("Unable to create database");
        }

        try {
            myDbHelper.openDataBase();
        } catch (SQLException sqle) {
            throw sqle;
        }

        // This returns true or false if params[0], which is a promo code,
        // is in in PromoCodes table in database.
        return myDbHelper.checkCourseInDatabase(params[0]);
    }

    @Override
    protected void onPostExecute(Boolean result) {
        // Store true or false in checkCodeInDatabase which is a static variable.
        // This variable will be used to check if code is valid in add button listener.
        checkCodeInDatabase = result;
        myDbHelper.close();
    }

問題:

問題は、AsyncTaskが時間どおりにcheckCodeInDatabase変数に値を格納しないことです。つまり、追加ボタンリスナーで実行されるifステートメントの場合、ifステートメントが追加ボタンリスナーで実行される前にAsyncTaskにデータベースクエリを実行してcheckCodeInDatabase変数を更新する十分な時間がないため、checkCodeInDatabaseの値は古い値です。

したがって、追加ボタンリスナーをAsyncTaskがcheckCodeInDatabaseを更新するのを待ってから、checkの場合に実行するようにする方法。

前もって感謝します!

ps私はAndroid開発に不慣れです。Android開発に関する本を読んだところ、アプリが応答しなくなるのを防ぐために、データベースに対するクエリはすべてAsyncTasksで実行する必要があるとのことです。たぶん、AsyncTasksで私が望むことを達成することは不可能です。どんな提案でも大歓迎です。

4

1 に答える 1

1

全体を委任する必要があります

        if (!checkCodeInDatabase) {
            // Display No code in database alert dialog
            showMsgDialog(getString(R.string.noCodeDBTitle),
                    getString(R.string.noCodeDBMessage));

            courseCodeEditText.setText("");

        } else {
            // Add promo code user typed in EditText
            addCode(promo_code);
        }

AsyncTaskのonPostExecuteをブロックします。

これにより、結果をフェッチし、UIスレッドで実行していることを確認できます。

于 2013-01-02T21:11:30.127 に答える