Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
HandlerThread案例学习,希望能够帮助你!!!。
在Android
的消息机制中,如果需要在子线程中创建Hanlder
来处理消息,那么很经典的代码如下:
new Thread(new Runnable() {
@Override public void run() {
Looper.prepare(); handler = new Handler(Looper.myLooper()){
@Override public void handleMessage(@NonNull Message msg) {
} }; Looper.loop(); } }).start
这样处理比较繁琐,有点类似于Service
中的意图服务的意思。因为自己创建比较繁琐,故而官方就提供了一套封装。
回顾一下:使用意图服务的时候,只需要自定义一个继承自IntentService
的类,复写onHandleIntent
方法即可,然后可在该方法中进行耗时操作,且操作完成后自动销毁Service
。
那么在使用HandlerThread
的时候,应该如何?
HandlerThread
是一个包含Looper
的Thread
,我们可以直接使用这个Looper
创建Handler
。
HandlerThread
所做的就是在新开的子线程中创建了 Looper
,那它的使用场景就是 前面提到的需要在子线程中创建Handler
,来处理消息的场景。
这里不妨看下这个类的构成:
public class HandlerThread extends Thread {
int mPriority; int mTid = -1; Looper mLooper; private @Nullable Handler mHandler; ... public void run() {
mTid = Process.myTid(); Looper.prepare(); synchronized (this) {
mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; } public Handler getThreadHandler() {
if (mHandler == null) {
mHandler = new Handler(getLooper()); } return mHandler; } }
在上面可以看见HandlerThread
是一个线程类,且在run
方法中初始化了对应的Looper
对象,在getThreadHandler
方法中创建一个和Looper
关联的Handler
对象。
那么,我们在使用的时候应该如何使用?不妨看看下面的简单案例:
public class MainActivity extends AppCompatActivity {
private Handler workHandler; @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = findViewById(R.id.id_mybutton); // 【开启子线程】开启一个子线程来处理消息 Looper+Thread+Handler HandlerThread handlerThread = new HandlerThread("MyHandlerThread"); handlerThread.start(); workHandler = new Handler(handlerThread.getLooper()){
@Override public void handleMessage(@NonNull Message msg) {
// 【子线程处理消息】 String channelId = "weizu"; // 1. 创建通知管理器 NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // 2. 创建通道 NotificationChannel channel = new NotificationChannel(channelId, "Simple Test", NotificationManager.IMPORTANCE_DEFAULT); manager.createNotificationChannel(channel); // 3. 创建通知对象 Notification.Builder builder = new Notification.Builder(MainActivity.this, channelId); Intent intent = new Intent(getApplicationContext(), MainActivity.class); PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0); Notification notification = builder.setContentTitle("Info") .setContentText((String) msg.obj) .setContentIntent(pi) .setSmallIcon(R.drawable.ic_baseline_bluetooth_24) .setAutoCancel(true) .build(); // 4. 发送通知 manager.notify(1, notification); } }; button.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
// 【主线程】点击事件来发送消息 Message msg = Message.obtain(); msg.what = 1; msg.obj = "Hello"; workHandler.sendMessage(msg); } }); } }
在上面的结果中,我们在子线程HandlerThread
中也可以在状态栏显示通知,进行了消息的处理。
需要注意的是,子线程中不可进行更新UI
操作,显然,这里的Notification
不属于更新UI
操作。
注意到在run
中调用了Looper.loop
方法,故而是一个无限循环。
也就是说这个HandlerThread
方法不会自动停止,我们需要显示的调用quit
方法,当不需要的时候,可以结束线程,即workHandler.quit();
。
另在IntentService
类中也有HandlerThread
的影子:
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper); } @Override public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } ... public void onCreate() {
super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }
在个方法中类似的关联了Looper
对象、Handler
对象,以及前面提到的HandlerThread
线程对象。且在onCreate
周期函数中的使用方式和我们的案例中类似。
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章