Я передаю обработчик, созданный по потоку mainUI от Activity
, и передается потоку, который выполняет некоторую сетевую операцию, и когда я получаю результат, я возвращаю результат к активности с помощью обработчика ,Экземпляр действия все еще существует даже после того, как onDestroy() называется
Этот подход имел проблему утечки памяти, когда я прошел через эти ссылки:
Inner ClassHandler Memory Leak
Android Developers
Так я осуществил WeakReference
и сохранил экземпляр активности с помощью WeakReference
. Но я все еще вижу Activity
экземпляр живой даже после уничтожения активности.
Я создал объект Handler
внутри действия и передал экземпляр активности как слабое отношение к обработчику.
К моменту, когда мой Handler
отвечает сообщением, переданным ему через 10 секунд, уничтожается Activity
. Но слабая ссылка все еще имеет экземпляр Activity
, и я вижу Toast
, после того как Activity
уничтожен.
Есть ли там, где мое понимание не так?
Может кто-нибудь объяснить, как обрабатывать сообщения, доставленные обработчику, но пользовательский интерфейс не вокруг?
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();;
}
}
}
}
На основе ответа, полученного, я обновляя ответ здесь. Вы можете сделать это так, как вам понравилось. Но это один из способов.
Добавлена ниже функции в SingleParamHandler
public void clear() {
mActivityReference.clear();
}
И активность OnDestroy()
public void onDestroy() {
super.onDestroy();
System.out.println("######## Activity onDestroy() ###### ");
handler.clear();
}
Спасибо за логику. Могу ли я знать, что заставляет вас сказать, что слабое отношение не требуется, потому что ссылка, которую я разместил, говорит, что обработчик должен быть статичным и делать слабую ссылку на активность или услугу и проверять перед обработкой сообщения? разве это не противоречит? Ваши знания об этом будут оценены. !! – Mani
@Mani Это предложение идет в том же направлении, что и мое (регистрация/незарегистрирование действий). Я делал меньше допущений. Дэвид, я все еще думаю в этом простом сценарии, было бы легче, если Handler проверит вместо 'Activity.isDestroyed()', потому что 'onDestroy()' не гарантируется выполнение? –
В статье, в которой вы ссылались, содержится конкретная ситуация, и я не согласен со всем, что там написано. Рассматриваемый случай - это сообщение с задержкой, отправленное в «Обработчик». В статье описывается случай, когда сообщение отправляется в «Обработчик», который будет отправлен через 10 минут. Это сообщение имеет ссылку на «Handler», а «Handler» имеет ссылку на «Activity», и это означает, что «Handler» или «Activity» не смогут быть удалены сборщиком мусора **, в то время как это сообщение все еще находится в очереди **. –