2

私はアクティビティ内でプライベート内部クラスとして多くのAsyncTasksを使用します。最初から私を困惑させているのは、onPostExecute()内でどのようなコンテキストを取得するかということです。

以下に示す簡略化された例を見ると、onPostExecute()内でgetString()を使用できます。その呼び出しにはどのコンテキストが使用されますか?アクティビティはdoInBackground(OrientationChangeなど)中に変更された可能性があるため、そのコンテキストにすることはできません。

現在、アクティビティコンテキスト(task.context = this)にパッチを適用し、その特定のコンテキスト(context.getString())を使用しています。

私の質問:周囲のアクティビティのコンテキストを使用せずに、内部クラスAsyncTaskのonPostExecute()内でgetString()を使用することは保存されますか?

よろしくお願いします。

public class MyActivity extends Activity {

    /* package */ MyActivity context;

    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

        public MyAsyncTask(final MyActivity context) {
            super();

            this.context = context;
        }

        @Override
        protected Cursor doInBackground(/* ... */) {
            // ...
        }

        @Override
        protected void onPostExecute(/* ... */) {
            if (context != null) {
                // Currently I do use that
                String s = context.getString(R.string.mytext);
                context.task = null;
            }

            // Would this be save?
            String s2 = getString(R.string.mytext);
        }

        @Override
        protected void onPreExecute (/* ... */) {
            // ...
        }
    }

    /* package */ MyAsyncTask  task;

    @Override
    public void onCreate(final Bundle bundle) {
        // ...

        Bundle bundleExtras = getIntent().getExtras();
        if (bundleExtras != null) {
            task = (MyAsyncTask) getLastNonConfigurationInstance();
            if (task != null) {
                task.context = this;
                // ...
            } else {
                task = new MyAsyncTask(this);
                task.execute();
            }
        }
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        if (task != null) {
            // ...
            task.context = null;
        }

        return task;
    }
}
4

2 に答える 2

1

周囲のアクティビティのコンテキストを使用せずに、内部クラス AsyncTask の onPostExecute() 内で getString() を使用することは保存されますか?

いいえ、安全ではありません。そのアクティビティの内部クラスであるため、クラスが作成されたときにMyAsyncTask参照できます。MyActivityしたがって、MyActivityが何らかの理由 (回転など) で強制終了された場合、onPostExecuteコールバックで、強制終了されたインスタンスMyAsyncTaskの参照を保持することになります。MyActivity

への参照を使用すると、Activity常に の有効なインスタンスを指すようにその参照を更新できるため、より安全ですMyActivityActivityおそらく、有効な参照が得られるまで直接を無効にしてonRetainNonConfigurationInstance、 ( が に達した場合はを再度セットアップするまで)null 触れないようにすることもできます。MyAsyncTaskonPostExecuteMyActivity

于 2012-05-18T10:19:19.197 に答える
1

MyAsyncTask()次のthisポインタを使用して のインスタンスを初期化しています。

task = new MyAsyncTask(this);

提供されたポインターで初期化されたクラスメンバーにonPostExecuteアクセスしています。contextあなたのコンテキストは、囲んでいるクラスのコンテキストですMyActivity

于 2012-05-18T10:07:07.527 に答える