web-dev-qa-db-ja.com

リークせずにサービスからAsyncTaskにコンテキストを渡す

Serviceがあり、そこから特定のタイマーからAsyncTaskを開始して、バックグラウンドタスクを実行します。私の必要性は、ネットワーキングタスクの短いバーストを必要とするため、AsyncTaskを使い続けています。

AsyncTaskから、Contextを必要とするいくつかの操作(通知の起動など)を実行しています。 ContextAsyncTaskを初期化すると、「このフィールドはコンテキストオブジェクトをリークします。

同じことに関して多くの質問を見てきましたが、それらはすべてActivity/Fragment。だから私の質問は、どのようにContextAsyncTask(トップレベルのクラス)で使用したらよいですかリークせずに

12
Mustansir

特定のタイマーからAsyncTaskを開始してバックグラウンドタスクを実行するサービスがあります。

AsyncTaskは使用しないでください。スレッドを使用します。または、タイミングコンポーネントにScheduledExecutorServiceを使用すると、バックグラウンドスレッドでタスクが実行されます。 AsyncTaskonlyバックグラウンド部分が完了したときにメインアプリケーションスレッドで作業を行う必要がある場合に適していますが、サービスではほとんど必要ありません。

また、プロセスが終了すると、タイマーが機能しなくなることに注意してください。

だから私の質問は、AsyncTask(最上位クラス)のコンテキストをリークすることなくどのように使用できるのですか?

ServicegetApplicationContext()を呼び出し、そのContextを使用します。

4
CommonsWare

アクセスしようとしているオブジェクトに対して、WeakReferenceAsyncTaskの静的内部クラスを使用してみることができます。このようなもの:

class MyServiceWhichDoesNotLeak extends Service {

    View view;
    AsyncTask task;

    //Your onCreate and stuff


    private static class BackgroundTask extends AsyncTask<Void, Void, String> {

        private final WeakReference<View> viewReference;

        public BackgroundTask(View view) {
            this.viewReference = new WeakReference<>(view);
        }

        @Override
        protected String doInBackground(Void... params) {
            // Background stuff
            return "something";
        }

        @Override
        protected void onPostExecute(String result) {
            View view = viewReference.get();
            if (view != null) {
                //Use your view
            }
        }
    }
}
7
Divya Vikash

WeakReference をAsyncTaskに渡すことができます。次に例を示します。

public class MyAsynctask extends AsyncTask<Void, Void, Void> {

   private WeakReference<Context> mWeakContext;

   public MyAsynctask (WeakReference<Context> reference) {
        mWeakContext = reference;
   }

   // when you need context use mWeakContext.get();
}

お役に立てれば。

6
Cochi