1

活動や物の破壊に疑問があります。

アクティビティをAsyncTaskにアタッチおよびデタッチしている間、ArrayAdapterをasynctaskから変更しません(コードを参照)。したがって、私が得たのは、複数のアクティビティがアタッチおよびデタッチされ(向きが変わるはずです)、1つのアダプタを実行および変更する1つのタスクだけです。これは、タスクを作成した最初のアクティビティからのものです。したがって、onCreate()でタスクをアタッチするときは、タスクを保持するアダプターをアダプターに設定するだけで、すべての値が処理されます(この例では、数字のダミーリストのみ)。

どうすればこれが可能ですか?onDestroy()はアクティビティ自体とその属性を消去すると思ったので、AsynkTaskから元のアクティビティのArrayAdapterにアクセスしようとすると、nullポインター例外などが発生しますが、以下のコードは機能します。

private static class TestingTask extends AsyncTask<Void, Integer, Void> {

    private TestingActivity mActivity; // extends ListActivity
    private ArrayAdapter<String> mAdapter;
    private boolean mIsFinished;

    private TestingTask(Context activity) {
        attach(activity);
        mAdapter = (ArrayAdapter<String>)mActivity.getListAdapter();
        mIsFinished = false;
    }

    private void attach(Context activity) {
        mActivity = (TestingActivity)activity;
    }

    private void detach() {
        mActivity = null;
    }

    protected Void doInBackground(Void... params) {
        for (int i = 0; i < 100000; i++) {
            publishProgress(i);
        }
        return null;
    }

    protected void onProgressUpdate(Integer... values) {
        if (!isCancelled()) {
            mAdapter.add(values[0].toString());
        }
    }

    // ...
}

これは、タスクがArrayAdapterオブジェクトへのアクティブな参照を保持しているため、削除されないためですか?それとも何か他のものですか?

また、onRetainNonConfigurationInstance()からアクティビティの属性を返した別の「同様のケース」を経験しました。たとえば、A aは、B b(アクティビティの別の属性)を可視化します。次に、aを介してbインスタンスにアクセスしようとすると、問題はなく、2つのインスタンス(aとb)を保持するためのラッパーが必要だと思いました。そうしないと、bにアクセスしようとすると例外が発生します(これは私が行います)。実際には保存しません)。私が利用できないはずだったオブジェクトが実際にそこにある前のケースが関連する幅であるかどうかはわかりません。おそらく、それらへのアクティブな参照が削除を引き起こさないためですか?

ありがとうございました!

4

1 に答える 1

0

私はこれらの質問に対する答えを見つけたと思います、そして私が疑問に思っていたように...それはガベージコレクターと強力な参照の使用に関連しています。

弱参照の理解の記事では、次のように述べられています。

オブジェクトが強力な参照のチェーンを介して到達可能である(強力に到達可能)場合、そのオブジェクトはガベージコレクションの対象にはなりません。ガベージコレクターが作業中のオブジェクトを破壊したくないので、これは通常、まさにあなたが望むものです

別の記事では、 Gargabeコレクションの仕組みについて次のように説明されています。

オブジェクトが別のオブジェクトの参照を保持していて、コンテナオブジェクトの参照をnullに設定すると、子オブジェクトまたは含まれているオブジェクトが自動的にガベージコレクションの対象になります。

だから、私の結論は次のとおりです。

最初のケース:アクティビティをnullに設定しdetach()ているので、メモリリークは発生せず、強力な参照を持つアダプタを除いて、すべてのオブジェクトをガベージコレクションできます。ですから、アダプターを除いて、アクティビティとそれに含まれる他のすべてのオブジェクトが削除されることを理解しています。これが私が実際に望んでいることです。

2番目のケース:コンテナオブジェクト(A a)をで返し、onRetainNonConfigurationInstance()(B b)への強い参照があるため、強い参照のチェーンを介して到達できるため、bインスタンスにもアクセスできます。

これがお役に立てば幸いです。他の誰かが彼/彼女の意見を述べたいならば、それは大歓迎です!

于 2012-01-21T13:01:30.377 に答える