1

MainActivityでは、x秒ごとに新しいAsyncTaskを作成し、execute withを呼び出しnew RTask(this).execute(param);て、サーバーに非同期でデータを送信します。新しいタスクを作成すると、メモリリークが頻繁に発生する可能性があると思います。では、ガベージコレクターがメモリを解放するときに、タスク参照をnullに設定して、それを収集できるようにするにはどうすればよいですか?this.cancel(true);内で使用しようとしましonPostExecute()たが、Androidフレームワークのバグのため、onpostが呼び出されないことを読みました。任意の提案をいただければ幸いです。

ありがとう

4

2 に答える 2

5

実際には、からの参照を保持するか、内部でメモリリークを生成AsyncTaskしない限り、リサイクルに問題はありません。paramdoInBackground()

したがって、長時間実行されるAsyncTaskを多数作成している場合は、メモリの問題が発生する可能性があると思われるかもしれません。実際にはそうではありません(少なくとも最新のAndroidバージョンでは)。AsyncTask ソースコードはそれを示しています

  • シングルトンバウンドエグゼキュータを使用します。

    private static final int CORE_POOL_SIZE = 5;
    private static final int MAXIMUM_POOL_SIZE = 128;
    private static final int KEEP_ALIVE = 1;
    
    public static final Executor THREAD_POOL_EXECUTOR
        = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
    

    つまり、エグゼキュータは同時に128を超えるAsyncTasksを実行しません(私の理解では128はそれほど大きくありません)。

  • エグゼキュータに制限付きクエリを使用します。

    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(10);
    

したがって、上記の点に基づいて、同時に作成および実行される数AsyncTasksは制限されており、それほど多くはありません。したがって、内部のコードでAsyncTaskメモリリークが発生しない場合は、私の理解では問題はありません。同時に、Androidはあなたが自分自身をスパムすることを許可しませんAsyncTasksThreadPoolExecutorsの説明をチェックアウトして、メモリの管理方法を理解してください(同時に作成されたスレッドが多すぎることを心配している場合)。

特にあなたの場合、前のリクエストがまだ終了していないときにサーバーに対して別のリクエストを実行するのは良い考えではないと思います(同様のリクエストの場合)。また、頻繁に小さなリクエストを多数実行する意味はありません-あなたのアプリこの場合、バッテリーの消耗が速すぎます。

通話に関しては、 AsyncTaskのAndroidドキュメントにcancel()基づいています:

タスクをキャンセルする

cancel(boolean)を呼び出すことにより、タスクをいつでもキャンセルできます。このメソッドを呼び出すと、isCancelled()への後続の呼び出しはtrueを返します。このメソッドを呼び出した後、doInBackground(Object [])が戻った後、onPostExecute(Object)の代わりにonCancelled(Object)が呼び出されます。タスクができるだけ早くキャンセルされるようにするには、可能であれば、doInBackground(Object [])からisCancelled()の戻り値を定期的にチェックする必要があります(たとえば、ループ内)。

cancel()したがって、から呼び出された場合は何の関係もありませんが、「onPostExecute()内でthis.cancel(true);を使用しようとしました」という意味かどうかはわかりませんonPostExecute()。からAsyncTaskまたはから呼び出すことができます。ループがある場合は、一度呼び出されると実行を停止するためにisCancelled()doInBackground()を呼び出すことをお勧めします。AsyncTaskcancel()

于 2013-03-21T11:45:24.510 に答える
1

ガベージコレクタがAsyncTaskに割り当てられたメモリを解放する方法

他のクラスのメモリを解放するように。AsyncTaskについて特別なことは何もありません。タスクが完了すると、他のクラスがそれを参照しない限り、ガベージコレクションが行われます。タスク参照をnullに設定すると役立ちます。

于 2013-03-21T12:11:47.253 に答える