这期内容当中小编将会给大家带来有关处理程序在Android项目中的运行原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
<强>处理强>
先通过一个例子看一下处理器的用法。
公共类MainActivity延伸AppCompatActivity { 私有静态最终int MESSAGE_TEXT_VIEW=0; 私人TextView mTextView; 私人处理程序mHandler=new处理程序(){ @Override 公共空间handleMessage(消息味精){ 开关(msg.what) { 案例MESSAGE_TEXT_VIEW: mTextView.setText (“UI成功更新“); 默认值: super.handleMessage(味精); } } }; @Override 保护空白>公共处理程序(回调的回调,布尔异步){ 如果(FIND_POTENTIAL_LEAKS) { 最后Class<及# 63;Handler>延伸;klass=getClass (); 如果((klass.isAnonymousClass () | | klass.isMemberClass () | | klass.isLocalClass ()),, (klass.getModifiers (),Modifier.STATIC)==0) { 日志。w(标签,“以下处理程序类应该是静态或泄漏可能发生:“+ klass.getCanonicalName ()); } } mLooper=Looper.myLooper (); 如果(mLooper==null) { 把新的RuntimeException ( “停下来# 39;t创建处理程序内部线程没有叫Looper.prepare ()“); } mQueue=mLooper.mQueue; mCallback=回调; mAsynchronous=异步; }
在构造方法中,通过调用Looper.myLooper()获得了电影对象。如果mLooper为空,那么会抛出异常:“停下来# 39;t创建处理程序内部线程没有叫Looper.prepare()“,意思是:不能在未调用Looper.prepare()的线程创建处理程序。上面的例子并没有调用这个方法,但是却没有抛出异常。其实是因为主线程在启动的时候已经帮我们调用过了,所以可以直接创建处理程序。如果是在其它子线程,直接创建处理程序是会导致应用崩溃的。
在得到处理程序之后,又获取了它的内部变量mQueue,这是MessageQueue对象,也就是消息队列,用于保存处理程序发送的消息。
到此,Android消息机制的三个重要角色全部出现了,分别是处理程序,电影以及MessageQueue。一般在代码我们接触比较多的是处理程序,但电影与MessageQueue却是处理程序运行时不可或缺的。
<强>电影
强>
上一节分析了处理器的构造,其中调用了Looper.myLooper()方法、下面是它的源码:
静态最终ThreadLocalsThreadLocal=new ThreadLocal (); 公共静态@Nullable尺蠖myLooper () { 返回sThreadLocal.get (); }
这个方法的代码很简单,就是从sThreadLocal中获取电影对象.sThreadLocal是ThreadLocal对象,这说明尺蠖是线程独立的。
在处理程序的构造中,从抛出的异常可知,每个线程想要获得电影需要调用准备()方法,继续看它的代码:
私有静态空准备(布尔quitAllowed) { 如果(sThreadLocal.get () !=null) { 把新的RuntimeException(“只有>私人电影(布尔quitAllowed) { mQueue=new MessageQueue (quitAllowed); mThread=Thread.currentThread (); }
现在的问题是,电影看上去很重要的样子,它到底是干嘛的?
回答:电影开启消息循环系统,不断从消息队列MessageQueue取出消息交由处理程序处理。
为什么这样说呢,看一下尺蠖的循环方法:
公共静态无效循环(){ 最后的电影我=myLooper (); 如果(我==null) { 把新的RuntimeException(“没有电影;Looper.prepare()触动他们# 39;t叫>公共布尔sendMessageAtTime(消息味精,长uptimeMillis) { MessageQueue队列=mQueue; 如果队列(==null) { 新RuntimeException RuntimeException e=( +“;sendMessageAtTime()被称为没有mQueue"); Log.w (“Looper" e.getMessage (), e); 返回错误; } 返回enqueueMessage(队列,味精,uptimeMillis); } 私人布尔enqueueMessage (MessageQueue队列、消息味精、长uptimeMillis) { 味精。目标=; 如果(mAsynchronous) { msg.setAsynchronous(真正的); } 返回队列。enqueueMessage(味精、uptimeMillis); }
这个方法就是调用enqueueMessage在消息队列中插入一条消息,在enqueueMessage总中,会把味精。目标设置为当前的处理程序对象。
消息插入消息队列后,电影负责从队列中取出,然后调用处理器的dispatchMessage方法。接下来看看这个方法是怎么处理消息的:
处理程序在Android项目中的运行原理是什么