您的位置:首页 > 移动开发 > Android开发

HandlerThread的学习心得

2015-12-14 09:57 447 查看
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());  来得到UI线程的ID!

然后在handleMessage方法中使用了 Log.i(TAG2,"HandlerThread---->"+Thread.currentThread().getId());
来得到消息处理线程的ID,最后打印结果如下所示:



果然!消息处理线程和UI线程不是同一个线程,这样我们的目的就达到了!这样以来,消息处理的时候就不会打扰UI界面的更新操作了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息