一.什么是handler
android中 只有主线程才能更新ui,handler通知ui更新 耗时操作,(文件读取,网络数据获取 )
Message 传递的是消息 MessageQueue 消息队列
二.handler的使用方法
image.pngimage.png
image.png
1.post(runnable)
image.pngpost 最终调用的也是hander方法
public class MainActivity extends BaseActicity {
//hander 绑定的是ui线程
private Handler mHandler = new Handler();
public static void show(Context context) {
context.startActivity(new Intent(context, MainActivity.class));
}
@Override
protected int getContentLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initWidget() {
super.initWidget();
}
@Override
protected void initData() {
super.initData();
//启动线程
DownLoadThread downLoadThread = new DownLoadThread();
downLoadThread.start();
}
class DownLoadThread extends Thread{
@Override
public void run() {
Logger.show("文件","开始下载");
try {
Thread.sleep(5000);
Logger.show("文件","下载完成");
Runnable runable = new Runnable() {
@Override
public void run() {
//todo 可以在主线程 更新ui
Logger.show("文件","下载完成");
}
};
//这里 执行的结果是在 UI线程
mHandler.post(runable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.sendMessage(message)
public class MainActivity extends BaseActicity {
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
// 进行ui操作
break;
}
}
};
public static void show(Context context) {
context.startActivity(new Intent(context, MainActivity.class));
}
@Override
protected int getContentLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initData() {
super.initData();
DownLoadThread downLoadThread = new DownLoadThread();
downLoadThread.start();
}
class DownLoadThread extends Thread{
@Override
public void run() {
Logger.show("文件","开始下载");
try {
Thread.sleep(5000);
Logger.show("文件","下载完成");
Message msg = new Message();
// msg = Message.obtain();
//产生一个Message对象,可以new ,也可以使用Message.obtain()方法;两者都可以,但是更建议使用obtain方法,因为Message内部维护了一个Message池用于Message的复用,避免使用new 重新分配内存。
msg.what=1;
// msg.arg1
mHandler.sendMessage(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
三. hander 机制的原理
参考博文 :Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系http://blog.csdn.net/lmj623565791/article/details/38377229
Handler 、 Looper 、Message 这三者都与Android异步消息处理线程相关的概念
那么什么叫异步消息处理线程呢?
异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环。若消息队列为空,线程则会阻塞等待。
其实Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息,而消息的创建者就是一个或多个Handler 。
image.png
Handler不仅可以更新UI,你完全可以在一个子线程中去创建一个Handler,然后使用这个handler实例在任何其他线程中发送消息,最终处理消息的代码都会在你创建Handler实例的线程中运行。
mHandler = new Handler(context.getMainLooper()) 运行在主线程
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
四.hander引起的内存泄漏和解决办法
创建hander 不是静态内部类 会隐匿持有外部activity对象
解决方法:
- 把hander 定义为静态内部类
如果需要调用activity 需要使用弱引用的方式
- mHandler.removeCallbacks(Thread);
public class HandlerActivity extends AppCompatActivity {
private final static int MESSAGECODE = 1 ;
private static Handler handler ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
findViewById( R.id.finish ).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
//创建Handler
handler = new MyHandler( this ) ;
//创建线程并且启动线程
new Thread( new MyRunnable() ).start();
}
private static class MyHandler extends Handler {
WeakReference<HandlerActivity> weakReference ;
public MyHandler(HandlerActivity activity ){
weakReference = new WeakReference<HandlerActivity>( activity) ;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if ( weakReference.get() != null ){
// update android ui
Log.d("mmmmmmmm" , "handler " + msg.what ) ;
}
}
}
private static class MyRunnable implements Runnable {
@Override
public void run() {
handler.sendEmptyMessage( MESSAGECODE ) ;
try {
Thread.sleep( 8000 );
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage( MESSAGECODE ) ;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//如果参数为null的话,会将所有的Callbacks和Messages全部清除掉。
handler.removeCallbacksAndMessages( null );
}
}
网友评论