Handler多线程内部实现机制
在Android开发中,我们经常会遇到这样一种情况:在UI界面上进行某项操作后要执行一段很耗时的代码,比如我们在界面上点击了一个”下载“按钮,那么我们需要执行网络请求,这是一个耗时操作,因为不知道什么时候才能完成。为了保证不影响UI线程,所以我们会创建一个新的线程去执行我们的耗时的代码。当我们的耗时操作完成时,我们需要更新UI界面以告知用户操作完成了。
注意一下的Handler写法会导致内存泄漏!!!!!!!!!!:
package com.example.kaifaceshi;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
}
//handler登场!!!
Handler h=new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 100:
tv.setText("下载完成!");
break;
}
}
};
public void button1(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//注意:不能再非主线程内调用UI控件
//发送一个空消息
h.sendEmptyMessage(100);
//获取一个消息对象
Message msg=h.obtainMessage();
msg.obj="hello";
msg.what=100;
h.sendMessage(msg);
//在指定时间发送
h.sendEmptyMessageAtTime(100,System.currentTimeMillis()+300);
//延迟发送
h.sendEmptyMessageDelayed(100,200);
}
}).start();
}
}
正确标准的写法应该是:!!!!!!!!!!!!!!!
package com.example.kaifaceshi;
import java.lang.ref.WeakReference;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
/*
* 总之Handler导致内存泄漏的原因就是:
* 主Activity已经退出了,Handler依然引用着主Activity的资源,以导致内存泄漏
*/
public class MainActivity extends Activity {
private static TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
}
myHandler myHandler=new myHandler(this);
//**************************
static class myHandler extends Handler{
WeakReference<MainActivity> weak;
public myHandler (MainActivity Activity) {
weak=new WeakReference<MainActivity>(Activity);
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
MainActivity activity=weak.get();
if(activity!=null) {
TextView v=(TextView) activity.findViewById(R.id.tv);
v.setText("下载完成!");
}
}
}
//**************************
}