mainUIスレッドで作成されたハンドラをActivity
から渡して、あるネットワーク操作を実行するスレッドに渡します。結果を取得すると、ハンドラを使用して結果をアクティビティに返します。 Inner ClassHandler Memory Leak
Android DevelopersonDestroy()が呼び出された後でもアクティビティインスタンスが存在する
は、だから私はWeakReference
を実施していた、とWeakReference
を使用して、アクティビティインスタンスを保持:私はこれらのリンクを経由したとき
このアプローチでは、メモリリークで問題がありました。しかし、私はまだ活動が破壊された後でもActivity
インスタンスが生きているのを見ています。
アクティビティ内にHandler
を作成し、アクティビティインスタンスをハンドラに弱参照として渡しました。
Handler
が10秒後に配信されたメッセージで応答するまでには、Activity
は破棄されます。しかし、弱い参照はまだActivity
インスタンスを持っており、Activity
が破棄された後にToast
が表示されています。
私の理解が間違っていますか?
ハンドラに配信されるメッセージをどのように処理するか説明できる人がいますが、UIはありません。を得応答に基づいて
import java.lang.ref.WeakReference;
import android.os.Handler;
import android.os.Message;
public abstract class SingleParamHandler <T> extends Handler
{
private WeakReference<T> mActivityReference;
public SingleParamHandler(T activity) {
mActivityReference = new WeakReference<T>(activity);
}
@Override
public void handleMessage(Message msg) {
if (mActivityReference.get() == null) {
return;
}
handleMessage(mActivityReference.get(), msg);
}
protected abstract void handleMessage(T activity, Message msg);
}
import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.widget.Toast;
public class MainActivity extends Activity {
MyHandler<MainActivity> handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
handler = new MyHandler<MainActivity>(this);
new Thread(new MyRunnable(handler)).start();
}
public void onDestroy() {
super.onDestroy();
System.out.println("######## Activity onDestroy() ###### ");
}
private class MyRunnable implements Runnable {
private Handler mHandler;
public MyRunnable(Handler handler) {
mHandler = handler;
}
public void run() {
try {
Thread.sleep(10000);
mHandler.sendMessage(Message.obtain(handler, 1));
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static class MyHandler<T> extends SingleParamHandler<T> {
public MyHandler(T activity) {
super(activity);
}
@Override
public void handleMessage(T act, Message msg) {
if(msg.what == 1) {
Toast.makeText((MainActivity)act, "Called after activity destroyed", Toast.LENGTH_LONG).show();;
}
}
}
}
、私はここで答えを更新しています。あなたは好きなやり方でそれをするかもしれません。しかし、これは一つの方法です。
は、そうする必要はない場合Androidは本当にメモリからオブジェクトを削除するという保証はありません)SingleParamHandler
public void clear() {
mActivityReference.clear();
}
と活動onDestroy(中に
public void onDestroy() {
super.onDestroy();
System.out.println("######## Activity onDestroy() ###### ");
handler.clear();
}
論理に感謝します。私が知っていることは、weakreferenceが必要ではないと言っていることです。私が投稿したリンクは静的であり、メッセージを処理する前にアクティビティやサービスに弱点を付けて確認する必要があると言うリンクです。それは矛盾していませんか?これに関するあなたの知識は評価されるでしょう.. !! – Mani
@Maniこの提案は、私と同じ方向に進みます(登録/登録解除アクティビティ)。私は仮定を少なくしていました。デビッド、私はまだこの単純なシナリオでは、 'onDestroy()'が実行することが保証されていないので、Handlerが 'Activity.isDestroyed()'をチェックする方が簡単だろうと思いますか? –
リンク先の記事は特定の状況をカバーしており、そこに書かれているすべてのものに同意しません。カバーされるケースは、「ハンドラ」に送信される「遅延メッセージ」です。この記事では、メッセージが10分間で配信される「ハンドラ」に送信されるケースについて説明します。このメッセージは 'Handler'への参照を持ち、' Handler'は 'Activity'への参照を持ち、' Handler'も 'Activity'もガベージコレクタ**で削除できないことを意味します。** whileこのメッセージはまだキューに残っています**。 –