您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
三六零分类信息网 > 贵港分类信息网,免费分类信息发布

HandlerThread源码详解之Android实例

2025/5/30 13:47:12发布8次查看
今天给大家带来的文章是通过实例代码分析android中handlerthread的用法以及步骤,需要的朋友参考学习下吧。
handlerthread 简介:
我们知道thread线程是一次性消费品,当thread线程执行完一个耗时的任务之后,线程就会被自动销毁了。如果此时我又有一
个耗时任务需要执行,我们不得不重新创建线程去执行该耗时任务。然而,这样就存在一个性能问题:多次创建和销毁线程是很耗
系统资源的。为了解这种问题,我们可以自己构建一个循环线程looper thread,当有耗时任务投放到该循环线程中时,线程执行耗
时任务,执行完之后循环线程处于等待状态,直到下一个新的耗时任务被投放进来。这样一来就避免了多次创建thread线程导致的
性能问题了。也许你可以自己去构建一个循环线程,但我可以告诉你一个好消息,aandroid sdk中其实已经有一个循环线程的框架
了。此时你只需要掌握其怎么使用的就ok啦!当然就是我们今天的主角handlerthread啦!接下来请handlerthread上场,鼓掌~~
handlerthread的父类是thread,因此handlerthread其实是一个线程,只不过其内部帮你实现了一个looper的循环而已。那么我们
先来了解一下handler是怎么使用的吧!
handlerthread使用步骤:
1.创建实例对象
handlerthread handlerthread = new handlerthread("handlerthread");
以上参数可以任意字符串,参数的作用主要是标记当前线程的名字。
2.启动handlerthread线程
handlerthread.start();
到此,我们就构建完一个循环线程了。那么你可能会怀疑,那我怎么将一个耗时的异步任务投放到handlerthread线程中去执行呢?当然是有办法的,接下来看第三部。
3.构建循环消息处理机制
handler subhandler = new handler(handlerthread.getlooper(), new handler.callback() { @override public boolean handlemessage(message msg) { //实现自己的消息处理 return true; } });
第三步创建一个handler对象,将上面handlerthread中的looper对象最为handler的参数,然后重写handler的callback接口类中的
handlermessage方法来处理耗时任务。
总结:以上三步顺序不能乱,必须严格按照步骤来。到此,我们就可以调用subhandler以发送消息的形式发送耗时任务到线程
handlerthread中去执行。言外之意就是subhandler中callback接口类中的handlermessage方法其实是在工作线程中执行的。
handlerthread实例:
package com.example.handlerthread; import android.app.activity; import android.os.bundle; import android.os.handler; import android.os.handlerthread; import android.os.message; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.textview; public class mainactivity extends activity { private handler msubhandler; private textview textview; private button button; private handler.callback msubcallback = new handler.callback() { //该接口的实现就是处理异步耗时任务的,因此该方法执行在子线程中 @override public boolean handlemessage(message msg) { switch (msg.what) { case 0: message msg1 = new message(); msg1.what = 0; msg1.obj = java.lang.system.currenttimemillis(); muihandler.sendmessage(msg1); break; default: break; } return false; } }; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); textview = (textview) findviewbyid(r.id.textview); button = (button) findviewbyid(r.id.button); handlerthread workhandle = new handlerthread("workhandlethread"); workhandle.start(); msubhandler = new handler(workhandle.getlooper(), msubcallback); button.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { //投放异步耗时任务到handlerthread中 msubhandler.sendemptymessage(0); } }); } }
handlerthread源码分析
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. */ public class handlerthread extends thread { //线程优先级 int mpriority; //当前线程id int mtid = -1; //当前线程持有的looper对象 looper mlooper; //构造方法 public handlerthread(string name) { //调用父类默认的方法创建线程 super(name); mpriority = process.thread_priority_default; } //带优先级参数的构造方法 public handlerthread(string name, int priority) { super(name); mpriority = priority; } ............... }
分析:该类开头就给出了一个描述:该类用于创建一个带looper循环的线程,looper对象用于创建handler对象,值得注意的是在创建handler
对象之前需要调用start()方法启动线程。这里可能有些人会有疑问?为啥需要先调用start()方法之后才能创建handler呢?后面我们会解答。
上面的代码注释已经很清楚了,handlerthread类有两个构造方法,不同之处就是设置当前线程的优先级参数。你可以根据自己的情况来设置优先
级,也可以使用默认优先级。
handlerthrad的run方法
public class handlerthread extends thread { /** * call back method that can be explicitly overridden if needed to execute some * setup before looper loops. */ protected void onlooperprepared() { } @override public void run() { //获得当前线程的id mtid = process.mytid(); //准备循环条件 looper.prepare(); //持有锁机制来获得当前线程的looper对象 synchronized (this) { mlooper = looper.mylooper(); //发出通知,当前线程已经创建mlooper对象成功,这里主要是通知getlooper方法中的wait notifyall(); } //设置当前线程的优先级 process.setthreadpriority(mpriority); //该方法实现体是空的,子类可以实现该方法,作用就是在线程循环之前做一些准备工作,当然子类也可以不实现。 onlooperprepared(); //启动loop looper.loop(); mtid = -1; } }
分析:以上代码中的注释已经写得很清楚了,以上run方法主要作用就是调用了looper.prepare和looper.loop构建了一个循环线程。值得一提的
是,run方法中在启动loop循环之前调用了onlooperprepared方法,该方法的实现是一个空的,用户可以在子类中实现该方法。该方法的作用是
在线程loop之前做一些初始化工作,当然你也可以不实现该方法,具体看需求。由此也可以看出,google工程师在编写代码时也考虑到代码的可扩展性。牛b!
handlerthread的其他方法
getlooper获得当前线程的looper对象
/** * this method returns the looper associated with this thread. if this thread not been started * or for any reason is isalive() returns false, this method will return null. if this thread * has been started, this method will block until the looper has been initialized. * @return the looper. */ public looper getlooper() { //如果线程不是存活的,则直接返回null if (!isalive()) { return null; } // if the thread has been started, wait until the looper has been created. //如果线程已经启动,但是looper还未创建的话,就等待,知道looper创建成功 synchronized (this) { while (isalive() && mlooper == null) { try { wait(); } catch (interruptedexception e) { } } } return mlooper; }
分析:其实方法开头的英文注释已经解释的很清楚了:该方法主要作用是获得当前handlerthread线程中的mlooper对象。
首先判断当前线程是否存活,如果不是存活的,这直接返回null。其次如果当前线程存活的,在判断线程的成员变量mlooper是否为null,如果为
null,说明当前线程已经创建成功,但是还没来得及创建looper对象,因此,这里会调用wait方法去等待,当run方法中的notifyall方法调用之后
通知当前线程的wait方法等待结束,跳出循环,获得mlooper对象的值。
总结:在获得mlooper对象的时候存在一个同步的问题,只有当线程创建成功并且looper对象也创建成功之后才能获得mlooper的值。这里等待方法wait和run方法中的notifyall方法共同完成同步问题。
quit结束当前线程的循环
/** * quits the handler thread's looper. * <p> * causes the handler thread's looper to terminate without processing any * more messages in the message queue. * </p><p> * any attempt to post messages to the queue after the looper is asked to quit will fail. * for example, the {@link handler#sendmessage(message)} method will return false. * </p><p class="note"> * using this method may be unsafe because some messages may not be delivered * before the looper terminates. consider using {@link #quitsafely} instead to ensure * that all pending work is completed in an orderly manner. * </p> * * @return true if the looper looper has been asked to quit or false if the * thread had not yet started running. * * @see #quitsafely */ public boolean quit() { looper looper = getlooper(); if (looper != null) { looper.quit(); return true; } return false; } //安全退出循环 public boolean quitsafely() { looper looper = getlooper(); if (looper != null) { looper.quitsafely(); return true; } return false; }
分析:以上有两种让当前线程退出循环的方法,一种是安全的,一中是不安全的。至于两者有什么区别? quitsafely方法效率比quit方法标率低一点,但是安全。具体选择哪种就要看具体项目了。
总结:
1.handlerthread适用于构建循环线程。
2.在创建handler作为handlerthread线程消息执行者的时候必须调用start方法之后,因为创建handler需要的looper参数是从handlerthread类中获得,而looper对象的赋值又是在handlerthread的run方法中创建。
相信看了这些案例你已经掌握了方法,更多精彩请关注其它相关文章!
相关阅读:
php如何实现栈数据结构以及括号匹配算法的代码示例详解
php中最简单的字符串匹配算法,php匹配算法_php教程
最简单的php中字符串匹配算法教程
以上就是handlerthread源码详解之android实例的详细内容。
贵港分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product