如下代码分析:
public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.textView); } private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); while (msg.what ==100){ textView.setText("android Thread"); break; } } }; public void sendTheadCilck(View view){ new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } handler.sendEmptyMessage(100); } }).start(); } }
这个段简单的代码是可以运行的,不会报错,那我们为什么它来作为 Handler内存泄漏的例子呢?
经过网上搜索和以及查看java的内部类知识,我们可以得出:
当我们把 Handler 当作内部类使用的时候,Handler其实可以引用其外部类所有的引用,那为什么会造成内存泄漏呢?
原因就是:如果如以上代码写的内部类,当Activity退出时,Handler其实还没有结束,这就会造成当我们退出这个程序时,Handler还在占用内存(Handler没有随着activity的结束而结束运行),所有造成不必要的内存泄漏。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
所以我们就可以自己写一个Handlerlei类 去extends Handler 来防止内存泄漏
private static class myHandler extends Handler{}
在这个类的内部中,我们需要定义myHandler对Activity的弱引用
private WeakReference<HandlerMemoryActivity> handlerMemoryActivityWeakReference;
弱引用的通俗解释就是(当Activity结束时,其内部类也会随之结束,释放内存) -------强弱引用的原理请查阅java知识
然后定义一个构造方法,把Activity传进去
public myHandler(HandlerMemoryActivity handlerMemoryActivity){
handlerMemoryActivityWeakReference = new WeakReference<>(handlerMemoryActivity);
}
接下来就是重写handMessage()方法,在方法中,我们必须判断Activity是否为空
若不为空,则可以对Ui线程进行访问
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
HandlerMemoryActivity handlerMemoryActivity = handlerMemoryActivityWeakReference.get();
if (handlerMemoryActivity!=null){
if (msg.what==100){
handlerMemoryActivity.textView.setText("handlerMemory");
}
}
}
以上,就是防止handler内存泄漏的正确写法。
程序修改源代码如下:
public class HandlerMemoryActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler_memory); textView = (TextView) findViewById(R.id.textView_HandlerMemory); } //使用Handler正确写法 private static class myHandler extends Handler { private WeakReference<HandlerMemoryActivity> handlerMemoryActivityWeakReference; public myHandler(HandlerMemoryActivity handlerMemoryActivity) { handlerMemoryActivityWeakReference = new WeakReference<>(handlerMemoryActivity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); HandlerMemoryActivity handlerMemoryActivity = handlerMemoryActivityWeakReference.get(); if (handlerMemoryActivity != null) { if (msg.what == 100) { handlerMemoryActivity.textView.setText("handlerMemory"); } } } } private final myHandler handler = new myHandler(this); public void sendNewHandlerCilck(View view) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } handler.sendEmptyMessage(100); } }).start(); } }
以上纯属个人理解的主观观点,不喜勿喷