已经有很久很久没有更新日志啦,没办法,人的惰性嘛,想想自己在这一行整整一年多了,学到的都是一些零散的知识点,一个完整的项目经验还没有,说来惭愧...好啦,废话不多说了,最近有好好的研究了一下Android中的Handler一些用法,在这里记录一下,一来是给自己加深印象,再者就是所谓的分享精神,这里所介绍的并不涉及很深的层次,就是一些细节上解释以及代码示例,那么接下来进入正题吧.....
一.Handler的基本使用
一般我们使用Handler的场景:在某个条件下,在主线程中通过发送一个信号,然后在子线程执行相应的逻辑,然后将处理完后的结果返回给主线程并更新相应的UI之类的(这是比较主要的),那我们来写个示例吧:
<span style="font-size:18px;">public class MainActivity extends Activity {
private Handler mMainHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Log.e("tag", "MainHandler in the " + Thread.currentThread().getName());
String str = (String) msg.obj;
Log.e("tag","Message from " + str);
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyThread myThread = new MyThread();
myThread.start();
}
class MyThread extends Thread{
@Override
public void run() {
Message msg = mMainHandler.obtainMessage();
msg.what = 1;
msg.obj = "I am from " + Thread.currentThread().getName();
mMainHandler.sendMessage(msg);
}
}
}</span>
这里新建子线程并调用Handler.sendMessage()方法向主线程发送消息,这里可以通过打印日志可以看出,这是一个线程中的通信。
因为java语言独特的传址特性,主要在相应的地方,将Handler作为参数传入方法内,就可以进行通信啦。
二.如何在子线程中使用Handler
这里小伙伴就说了,子线程使用hanler不就是在子线程new Handler()么?其实不完全是这样的,这里有个知识点来普及下,每个线程中有且只有一个Looper对象,并且每个Looper对象维护一个消息队列,但是若两个Handler创建时使用同一个Looper对象,是不是就可以共用handMessage()方法呢,那么,我可以负责人的告诉你,并不是这么理解的,那么进入主题,如何在子线程中使用Handler呢,那么看下示例代码:
<span style="font-size:18px;">class MyThread extends Thread{
@Override
public void run() {
Looper.prepare();
Looper looper = Looper.myLooper();
Handler firstHandler = new Handler(looper){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Log.e("tag", "From first handler");
break;
default:
break;
}
}
};
Handler secondHandler = new Handler(looper);
firstHandler.sendEmptyMessage(1);
looper.loop();
}
}</span>
那有的小伙伴又会有疑问,在主线程中没有调用Looper.prepare()呢,那么根据源码,主线程会自动调用 Looper.prepare();
三.Handler中的Post()方法使用
在Handler.post()方法中,其中传入的参数为runnable对象,那么根据runnable的特性,其并不是创建子线程并执行相关的逻辑,而是根据runnable创建的所在线程所决定的,那么由此得来,由主线程创建的Handler对象,调用post方法时,则在主线程中执行相应的逻辑(可以更新UI界面),那么示例代码如下:
MyRunnable r = new MyRunnable();
Handler handler = new Handler();
handler.post(r);
class MyRunnable implements Runnable{
@Override
public void run() {
Log.e("TAG", "OnRunning"+Thread.currentThread().getName());
}
}
四.HandlerThread的使用方法
照例,先简单的介绍一下HandlerThread,由HandlerThread中获取的Looper对象生成的Handler,通过sendMessage()方法时,其handleMessage()方法是在子线程中执行的,那么我们继续来看一下示例代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HandlerThread mHandlerThread = new HandlerThread("TestHandlerThread");
mHandlerThread.start();
Looper looper = mHandlerThread.getLooper();
Handler handler = new Handler(looper){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Log.e("tag", "HandlerThread -->"+Thread.currentThread().getName());
break;
default:
break;
}
}
};
handler.sendEmptyMessage(1);
}
最后,介绍一个小小的优化方法,一般我们生成一个Message对象时,是直接new的,然后各种赋值,当然这不算比较好的方法,那么,通过handler.obtainMessage()方法来生成一个messsage对象比较好,为什么呢?留给大家看源码咯~
如果文中还有什么补充或者是不严谨的地方,还望指出哦 ~谢谢