Android中Handler的使用,一般都在UI主线程中执行,因此在Handler接收消息后,处理消息时,不能做一些很耗时的操作。
为了解决这个问题,Android中专门提供了HandlerThread类,来解决该类问题。HandlerThread类是一个线程专门处理Hanlder的消息,依次从Handler的队列中获取信息,逐个进行处理,保证安全,不会出现混乱引发的异常。
HandlerThread继承于Thread,所以它本质就是个Thread。
我们看android官方关于HandlerThread的描述:
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
这段话的意思是:这个HandlerThread用来开启一个新的线程并且这个线程含有一个looper,这个looper能够用来创造Handler类,同时必须调用start()方法来使能HandlerThread,下面是相关代码:
MainActivity.java
public class MainActivity extends Activity {
private Handler handler;
private Second second;
public final static String TAG = "Indentify";
private static final String TAG1 = "MainActivity";
private static final String TAG2 = "HandlerThread";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG1, "MainActivity---->" + Thread.currentThread().getId());
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
Looper looper = handlerThread.getLooper();
handler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
Log.i(TAG2, "HandlerThread---->"
+ Thread.currentThread().getId());
String receiveString = "";
if (msg.what == 0x11) {
receiveString = msg.getData().getString(MainActivity.TAG);
Toast.makeText(MainActivity.this, receiveString,
Toast.LENGTH_SHORT).show();
}
}
};
//初始化第二个类,把handler参数传递进去
second = new Second(handler);
//开启第二个类的线程
second.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Second.java
public class Second {
private Handler handler;
public Second(Handler handler) {
this.handler = handler;
}
public void start() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
Message message = handler.obtainMessage(0x11);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.TAG, "Second类发来数据");
message.setData(bundle);
handler.sendMessage(message);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
}
那么我们现在肯定会有一个疑问:那么现在处理消息的线程和UI线程是不是同一个线程?如果不是同一个线程,说明这个HandlerThread类和UI线程是分开的,也就是说数据处理和UI线程是分开的,这样就达到了我们的对于HandlerThread的预期作用。所以在以上程序中,我在oncreate方法中使用了
Log.i(TAG1,"MainActivity---->"+Thread.currentThread().getId());
然后在handleMessage方法中使用了
果然!消息处理线程和UI线程不是同一个线程,这样我们的目的就达到了!这样以来,消息处理的时候就不会打扰UI界面的更新操作了!