[Android 内存泄漏] 了解 Handler leak

    xiaoxiao2021-03-26  11

    基本的原理就是,内部类 ( 包括匿名内部类 ) 不管有无调用,实际上会持有外部类对象的引用。比如下面的代码 C 类可以取得外部类的变量值。

    public class InnerTest { private String mContent = "hi"; class B { private String mContent = "hi, B"; class C { public void test() { System.out.println(InnerTest.this.mContent); System.out.println(B.this.mContent); } } } public static void main(String[] args) { new InnerTest().new B().new C().test(); } }

    我们来看看会造成 Handler leak 的代码,如下:

    public class MemLeakActivity extends Activity { ... class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { ... } } }所以当我们的内部类 IncomingHandler 发出 Message 后, 根据 Android 异步消息処理机制,Message 会持有 Handler 对象引用,而上面的代码,会持有外部类对象,也就是 MemLeakActivity 对象的引用,导致即使在此 Activity 在调用完 onDestroy( )后,只要 Looper 还没有処理完这个 Message( 比如说这个 Message 是设定为延迟十分钟后再処理),MemLeakActivity 的对象便无法被回收,占用了内存实际上却没有作用,便造成了 Handler Leak 内存泄漏。 解决方法: 使用静态(内部)类 + 弱引用( WeakReference )避免 Activity 被 Message 强引用而无法回收。 public class BaseHandler extends Handler { WeakReference<Callback> mTarget = null; public BaseHandler(Callback cb) { mTarget = new WeakReference<>(cb); } public interface Callback { boolean handleMessage(Message msg); } @Override public void handleMessage(Message msg) { Callback handler = mTarget.get(); if (handler != null) { handler.handleMessage(msg); } } }使用方式 public class HandlerDemoActivity extends Activity implements BaseHandler.Callback, View.OnClickListener{ private BaseHandler mHandler; private final static int MSG_TEST = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_handler_demo); mHandler = new BaseHandler(this); TextView tv = (TextView) findViewById(R.id.tv); tv.setOnClickListener(this); } @Override public boolean handleMessage(Message msg) { final int what = msg.what; if(what == MSG_TEST) { Toast.makeText(this, "TEST", Toast.LENGTH_LONG).show(); } return true; } @Override public void onClick(View v) { mHandler.sendEmptyMessage(MSG_TEST); } } Github 范例

    相关参考文章 refs: http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler

    转载请注明原文地址: https://ju.6miu.com/read-450212.html

    最新回复(0)