Android中有关Handler的好多思想

爱人们本人是心云,今日随着聊怎么样通过市集来促成无本赚钱。既然我们要经过市场来致富,就要先搞通晓怎样是市面?大家先看看百度完善的分解:狭义上的商场是购销双方实行商品沟通的场馆。
广义上的商海是指为了买和卖有些商品而与其余厂商和个人相挂钩的一批厂商和村办。市镇的范畴即商场的分寸,是购买者的食指。
市集是商品交流顺遂举行的尺码,是商流领域壹切商品调换活动的总额。市镇种类是由各种专业市镇,如商品服务市场、金融市场、劳务商场、技术市场、消息市镇、房土地资金财产市场、文化市镇、旅游集镇等组成的欧洲经济共同体体系。同时,在市面类别中的各专业市镇均有其十分效率,它们相互依存、相互制约,共同功效于社经。
你看晕了啊?听着那个所谓的大家讲经营销售,讲市镇,oh my six
gad,反正本人是越看越繁杂,他们总能把3个粗略的东西,说的很高深很复杂!

在头里的博文中,讲过部分和Handler有关的学识,例如:

在此地笔者就用个简易的表达来证明是市面,当然这只是自作者二个狭义上对市镇的诠释,最后解释权归国家全体!哈哈。。只怕你以为没道理,关键是有用,你一看就懂!集镇=人群,不难的来说市镇便是人工不孕症,约等于主顾照旧消费者。市镇是三个广义的面,当然人群也是二个广义的面,我们做其余生意,皆以小覆盖,不容许拥有的人群都以您的主顾。你也许会反驳小编,小编是一家小茶楼,人人都得以来吃,那么作者问您,你在首都开家小食堂能让布宜诺斯艾Liss的人过来吃啊?你的商海到底只是小覆盖,你的餐饮店不得不满足周边的人群,而且不是享有人群,有个指标人群,也正是专业术语中所说的对象市镇!也便是给您带来五分四利润的人流。比如:你这家小茶馆,超过一半顾客都以周围上班一族在那边吃饭,他们给您带来百分之八十的利润,而他们便是你的目的消费者,你不也许引发到业主来吃,就算有也很少,所以您的用力目的是您的目的顾客,你必须以目的消费者的急需为导向!

Android
多线程—-AsyncTask异步任务详解 

那么大家想要通过市场来赚取,我们能够赚钱的商海也不是广义上的商场,而这么些市镇,对于外人来说是供给,也许和你壹起的供给,是你的能源!

Android拾贰线程—-异步音讯处理体制之Handler详解

1、对接市镇须要整合

今天再把Handler的学识回看总括一下。

比如:在游历淡季,有不少环境很好的酒馆工作都很差,那么您就足以找到酒吧,跟组长谈合作,你能够扶助业主带来诸多进食和寄宿的客户,只需免费提供会议场地,因为属于空置能源!然后找担保集团,因为众多保障公司总在搞培养和训练会议,也许窗外集中练习之类的活动,而且她们也要求漫长租用培养和篮球场馆,你可以将从酒吧拿来的议会地方,以比相当低的标价卖给培养和陶冶公司,当然前提是培植公司必须是二天依旧三天以上的培养和陶冶,人数必须是80——玖拾陆人之上!不仅能为保险公司省钱,只要培养和练习就要吃饭,假使是几天的作育大概要过夜,而且能援救旅馆带来客源!

 

若是你认为这几个好无法精晓,那作者就举个最简便易行的例证!在那里,作者首先举个例证:种种城市都有众多茶馆,那么是还是不是种种饭馆都有买菜的要求?是否大抵是各买各家的菜?而商旅须求的怎么?无非正是方便呢?那您是不是能够花较低的价格买到相同品质的菜。你就足以找到种种茶馆的业主,将他们要买的菜集中执会侦查总括局一购销,大家都驾驭,买菜那样的物料,肯定是量越大价钱越低,接完酒楼的订单之后,你就能够去找菜市镇的批发商,就足以以较低的价钱得到货,然后将货送到种种饭馆。你只赚取二个差价,你未有其余风险!而且是内需有个别订多少货,酒店能以较低的价钱买到需求的菜,批发商也能出大批量的货,你也能从中追求利益差价!

本文包涵与Handler有关的以下难点:

为了让大家深切理解,作者在此地享受三个案例,希望你能确实的知情!

  (1)Handler的作用

关于培养和磨练网的1个案例

  (②)为啥Android中要规划为只可以在UI线程中去更新UI呢?

第一她对总体行业做了剖析,发现貌似的培养和训练网都相当于三个阳台,类似中华英才网那样的平台,供行业老师发招生新闻的,有培育须求的信用合作社仍旧个体在地点依据须要选老师的情势来做,而且都以索要付费的,通过接受会员费大概音信发表费的方法接受。将来还有众多如此的网址。。

  (三)Handler的七个要命

她首先针对全数网址的架构做了调整!中华培训网针对培养和磨练行业的专家庭教育授,无条件开放,只要透过核查,就积极扶助其免费公布课程音信,活动音信!还免费赞助推广书籍以及影像制品,免费支持做代理渠道。这样做就掀起到了行业类最有质量的教师职员和工人,任网址挑选,把最棒的教师职员和工人都预留了!

  (肆)Handler、Looper MessageQueue之间的涉及(源码角度)

第2,对客户举行会员制!VIP客户430一年,在网址上购买其余产品可分享降价!报任何老师的培养课程,可以拿到比培育集团的标价还要低,还足以加入免费的新颖观点的培育科目,国际大拿老师的解说课程。全数的科目都得以获得最低折扣价,而且网址上的名师都以业类最显赫的教授,口碑最棒的教授,也是教授最多的网址。。

  (五)跟线程相关的Handler,即HandlerThread(源码角度解析)

其3,通过鼓励专家庭教育授在网址上开博客写小说的办法,大大提升网址品质,提高粘合度!不但升高等教学师著名度,而且引发了大批量的读者,潜在客户!大概四个月后中华人民共和国培养和磨炼网在业类小盛名气,然后又找到任何培训网站,专家庭教育授博客协作,以同盟的措施,完成网址流量捆绑,转介绍的艺术,升高网址流量,完毕双赢!首先免费让教学、专家在网址免费发布讲座、课程新闻,而且免费赞助老师代理做渠道销售课程光碟书籍类用品。那样就吸引到了大量的专家庭教育授,然后针对受众,对培养和练习有需要的村办或小卖部VIP会员业务,不仅课程开支比培育公司的低很多,而且有大批量的优化,而且老师多。每年还有定期三次管理新型观点培养和练习。谈下客户,然后跟国际大师谈推广,中华网一遍性请多少人来听老师的公开课,让教授宣传本人,推销自个儿的科目,而且中华网还给老师提供部分费用,就用差不离免费的价位,引入了过多国际大师的学科,以大约免费的价格赠送给了客户。乔吉拉德之类的大师正是中华网引入国内的率先批国外大师!

  (6)主线程往子线程发音讯

市面财富既是将八个有须要的咬合在协同,从而实现双赢或然多赢的范围!市集能源的要紧正是供给,怎样找到有协同需要依旧相互要求的包扎在一齐,那么您就能轻松的赚到钱!小编在举个例子!

 

2、通过交接共同须求

一、Handler的作用:

先是我们明白一下,什么是同步供给?共同供给既四个只怕若干人群或商店,多某样物品恐怕事物有①块的要求!比如:A是卖高档男子手表的,必要针对高端商务汉子做推广,B是开高尔夫俱乐部的,也有1致的供给,C是卖高档越野车的,也急需,D是做匹夫美容的,也1如既往需求!那么A就足以同步BCD甚至EFG和她们有相同须求,顾客群众体育壹样的店堂,1起做二个放大酒会,不但顾客群精准,而且下跌了互相的松开开支,不但能吸收接纳越多的新客户,而且也投其所好了老客户!而且A可以拿B的成品送给老客户,B能够拿D的制品答谢老客户!

(一)在非UI线程中完毕耗费时间操作,在UI线程中去更新UI。

(二)能够在主线程中发送延时音信。

二〇二〇年,王先生开了一家体控理疗店。开首是因为芸芸众生对新闯事物的不打听,生怕受骗受愚,所以生意一贯相当冷静。体控理疗是何许?其实过多少人都以第三回传说。体控理疗就是一种集保健、美容、治疗于一体的新颖理疗方法,效果尤其的正确性。为了尽快展开市集,王先生实行了许多降价措施。如:散发名片、开始展览免费感受、价格优惠等方法,但收效甚微。有1天,王先生突然想起了不久前的1件事。2个有情人给她一张“合理饮食”的常见宣传图。下边图像和文字并茂的写有“40种不能搭配同吃的食品”、“分裂疾病征候人群食品”等文化。

 

乘胜生活档次不断增加,人们的例行意识进一步强,而“合理饮食”又是大千世界用得上,家家必备之物。于是,为了方便保存、教导和查阅,王先生将那张宣传图改编成了5开的小册子。小册子设计得老安顺想,封面上方是三口之家的人物图片,下方印着“合理饮食,均衡营养”多少个明显大字;封底上印成居家庭服务务普通电话,如:清洁公司、搬家公司、电脑维修公司、物理疗法服务等。

贰、为啥Android中要规划为只幸而UI线程中去更新UI呢?

bwin亚洲必赢5566,引导销售学认为:当客户将有价值的资料保存下来后,就有了为对方服务的机会,
这本来就能赚到钱。

(1) style=”color: #0000ff;”>解决10二线程并发难题(根本原因)

(二)升高界面更新的质量问题

(叁)框架结构划设想计的归纳

唯独洋洋政工都以谈起来简单做起来难。单印刷宣传材料陆仟册,就要求6000多元,对于刚先生创业的王先生来说,也是一笔十分大的开发,这如何是好吧?为了节约花费,花小钱办大事,王先生想到了去整合家居服务行业的同行们,让同行们来援助其伙同承担开销,于是王先生写好同盟协议书后立时行动了起来。第1家整合的小卖部,是在王先生在报纸上找的一家计算机维修公司。王先生先通过电话简要与信用合作社理事挂钩后,维修公司登时就让王先生去信用合作社详谈。到商行谈了供不应求陆分钟,该公司就签订同盟协议,交费成交。

你大概会说,既然是放心不下拾2线程并发难题,那笔者在子线程中加锁举行更新UI好依然倒霉吧?你这么想的话,会不难造成UI卡顿的,而且品质也倒霉。

首战告捷,王先生有了庞大的信念,用相同的主意驱动别的集团,极快聚集了十5家居服务集团。精美的宣扬小册子十分的快诞生了。那样1来,原来由王先生1位负担的四千多元宣传制作费,成了十多人联合负责,一下子节约了93%的开支。王先生自然高兴的不行了。但咋样将宣传小册子送到城里人手中,并保管它的实用行使呢?免费派送的法子,被人用烂了,未有人会重视,肯定是收效甚微的。所以王先生就违背,偏偏采纳了卖的主意。一册二元,买二册安慕希,价格不高,人人都能接受。好了,心云的享受就到此地了,欢迎有两样观点的恋人,留下您的宝贵意见!

注一:大部分面试者很难去说出一个令面试官满意的答案。

注贰:关于多线程,那里举四个例证,比如说银行取款的题材。不荒谬情况下,银行卡余额无法简单取款金额,即便二十八线程举行取款的话,就会促成线程不安全。

注三:Android中因故说架构不难,是因为帮大家封装了很多更新UI的操作。

 

三、Handler的四个可怜:

在利用Handler时,平时会并发以下多个要命:

(一)CalledFromWrongThreadException:那种相当是因为尝试在子线程中去更新UI,进而发生10分。

(2)Can’t create handle inside thread that ha not called Looper.prepared:是因为我们在子线程中去创设Handler,而发出的十三分。

咱俩接下去通过代码来把那多少个可怜演示一下。

一、子线程中更新UI的这多少个:

(1)activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"/>

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮"/>

</RelativeLayout>

 上方代码中,三个文本,两个按钮,代码比较简单。

(2)MainActivity.java:

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.view.View;
 4 import android.widget.Button;
 5 import android.widget.TextView;
 6 
 7 public class MainActivity extends Activity {
 8 
 9     private TextView tv;
10     private Button btn;
11 
12     @Override
13     protected void onCreate(Bundle savedInstanceState) {
14         super.onCreate(savedInstanceState);
15         setContentView(R.layout.activity_main);
16         tv = (TextView) findViewById(R.id.tv);
17         btn = (Button) findViewById(R.id.btn);
18 
19         //点击按钮后,尝试在子线程中更新UI
20         btn.setOnClickListener(new View.OnClickListener() {
21             @Override
22             public void onClick(View v) {
23 
24                 new Thread(new Runnable() {
25                     @Override
26                     public void run() {
27                         tv.setText("smyhvae");  //子线程中更新UI
28                     }
29                 }).start();
30 
31             }
32         });
33     }
34 }

上面代码中,宗旨代码是第3柒行:点击按钮后,在子线程中更新UI。

运行程序后,点击按钮,效果如下:

bwin亚洲必赢5566 1

那时,大家来看一下后台的log日志:

bwin亚洲必赢5566 2

上海教室中报的荒谬日志正是因为我们在子线程中去更新UI。

 

缓解方案:

  在子线程中开创Message音信,通过Handler发给主线程,之后在Handler的handleMessage方法中收获Message音讯,进而处理更新UI界面。代码如下:

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.os.Handler;
 4 import android.os.Message;
 5 import android.view.View;
 6 import android.view.View.OnClickListener;
 7 import android.widget.Button;
 8 import android.widget.TextView;
 9 
10 public class MainActivity extends Activity implements OnClickListener {
11     public static final int UPDATE_TEXT = 1;
12     private TextView text;
13     private Button changeText;
14 
15     //程序一加载,直接在主线程中创建Handler
16     private Handler handler = new Handler() {
17         public void handleMessage(Message msg) {
18             switch (msg.what) {
19             case UPDATE_TEXT:
20                 text.setText("Nice to meet you");
21                 break;
22             default:
23                 break;
24             }
25         }
26     };
27 
28     @Override
29     protected void onCreate(Bundle savedInstanceState) {
30         super.onCreate(savedInstanceState);
31         setContentView(R.layout.activity_main);
32         text = (TextView) findViewById(R.id.text);
33         changeText = (Button) findViewById(R.id.change_text);
34         changeText.setOnClickListener(this);
35     }
36 
37     @Override
38     public void onClick(View v) {
39         switch (v.getId()) {
40         case R.id.change_text:
41             new Thread(new Runnable() {
42                 @Override
43                 public void run() {
44                     Message message = new Message();
45                     message.what = UPDATE_TEXT;
46                     handler.sendMessage(message);
47                 }
48             }).start();
49             break;
50         default:
51             break;
52         }
53     }
54 }

 上方第四4行代码也足以换来:

Message message = handler.obtainMessage();

  

2、在子线程中创建Handler的12分:

MainActivity.java:

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.os.Handler;
 4 import android.widget.TextView;
 5 
 6 public class MainActivity extends Activity {
 7 
 8     private TextView tv;
 9 
10     @Override
11     protected void onCreate(Bundle savedInstanceState) {
12         super.onCreate(savedInstanceState);
13         setContentView(R.layout.activity_main);
14         tv = (TextView) findViewById(R.id.tv);
15 
16         //尝试在子线程中去创建Handler
17         new Thread(new Runnable() {
18             @Override
19             public void run() {
20                 new Handler();
21             }
22         }).start();
23     }
24 }

 运转程序后, 报错如下:

bwin亚洲必赢5566 3

  

4、Handler、Looper MessageQueue之间的关联:(源码角度)

    假诺要问到Handler,这几个难点宗旨是面试必问的。

原理分析:

Handler是Android类库提供的用来发送、处理新闻或Runnable对象的拍卖类,它结合Message、MessageQueue和Looper类以及当前线程达成了贰个音信循环机制,用于落实职务的异步加载和处理。整个异步消息处理流程的示意图如下图所示:

bwin亚洲必赢5566 4

依照地方的图样,大家昨日来分析一下异步音讯处理体制

  • Message:新闻体,用于装载须要发送的目的。
  • Handler:它直接接轨自Object。功能是:在子线程中发送Message恐怕Runnable对象到MessageQueue中;在UI线程中吸收接纳、处理从MessageQueue分发出来的Message或许Runnable对象。发送音讯1般接纳Handler的sendMessage()方法,而发出去的音信经过处理后最终会传送到Handler的handlerMessage()方法中。
  • MessageQueue:用于存放Message或Runnable对象的新闻队列。它由相应的Looper对象创立,并由Looper对象管理。每种线程中都只会有二个MessageQueue对象。
  • Looper:是种种线程中的MessageQueue的管家,负责接收和分发Message或Runnable的干活。调用Looper.loop()方法,正是多个死循环,不断地从MessageQueue中取音信:假如有消息,就取出,并调用Handler的handlerMessage()方法;假若未有音信阻塞。

到现在能够做出如下计算:

(一)Handler负责发送新闻,Looper负责接收Handler发送的音信放到MessageQueue,Looper又将音信回传给Handler本身。

(二)二个Handler对应贰个Looper对象,三个Looper对应三个MessageQueue对象(Looper内部蕴藏四个MessageQueue),二个Handler可以转移多个Message。

(三)Handler就是公然给外部线程的接口,用于线程间的通讯。Looper是由系统支持的用于成立和保管MessageQueue的附属于二个线程的轮回处理指标,而Handler是用来操作线程内部的音信队列的,所以
           Handler也必须依附二个线程,而且不得不是一个线程。

(4)由于Handler是在主线程中创建的,所以那时handleMessage()方法中的代码也会在主线程中运营,于是大家在此间就足以告慰地实行UI操作了

 

活着中的例子:

bwin亚洲必赢5566 5

上图中,可以这么领会:开会时,笔者(Handler)想中途离开去做其余事情,通过sendMessage发音信给长官,领导思想了少时,同意以后,通过Looper.looep()方法将音讯回传给本人,说小编得以离开,然后自身就调用handleMessage方法去做别的事情去了。

注:面试的时候,要是只是从字面包车型客车角度来诠释Handler、Looper
MessageQueue之间的涉嫌,并不可见真的打动面试官,倒比不上再举三个绘影绘声的事例,让面试官觉得您是懂面向对象的构思的。

 

五、跟线程相关的Handler,即HandlerThread(源码角度解析)

其一难题得以看一下那篇博客:

http://blog.csdn.net/lmj623565791/article/details/47079737

 

6、主线程往子线程发音讯:(考查你是或不是真正驾驭Handler机制)

  我们在日常付出的经过中,日常是子线程往主线程中发音信,让主线程更新UI。可是依照实际的种类须要,也可能会须要让你在主线程中往子线程中发新闻。

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.os.Handler;
 4 import android.os.Looper;
 5 import android.os.Message;
 6 import android.util.Log;
 7 import android.view.View;
 8 import android.view.View.OnClickListener;
 9 import android.widget.Button;
10 import android.widget.TextView;
11 
12 public class MainActivity extends Activity implements OnClickListener {
13     public static final int UPDATE_TEXT = 1;
14     private TextView tv;
15     private Button btn;
16     private Handler handler;
17 
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22         tv = (TextView) findViewById(R.id.tv);
23         btn = (Button) findViewById(R.id.btn);
24         btn.setOnClickListener(this);
25         //疑问:为什么这段代码如果写在onClick方法里面会报空指针?
26         new Thread(new Runnable() {
27             @Override
28             public void run() {
29                 //1、准备Looper对象
30                 Looper.prepare();
31                 //2、在子线程中创建Handler
32                 handler = new Handler() {
33                     @Override
34                     public void handleMessage(Message msg) {
35                         super.handleMessage(msg);
36                         Log.i("handleMessage:", Thread.currentThread().getName());
37                         Log.i("后台输出", "收到了消息对象");
38                     }
39                 };
40                 //3、调用Looper的loop()方法,取出消息对象
41                 Looper.loop();
42             }
43         }).start();
44 
45     }
46     @Override
47     public void onClick(View v) {
48         Log.i("onClick:", Thread.currentThread().getName());
49         switch (v.getId()) {
50             case R.id.btn:
51                 Message msg = handler.obtainMessage();
52                 handler.sendMessage(msg);
53                 break;
54 
55             default:
56                 break;
57         }
58     }
59 }

上面包车型客车第壹玖行至41行代码:那是MainThread中发送新闻,在子线程中接受新闻的永恒写法。上面的多个步骤再另行一下:

  • 准备Looper对象
  • 在WorkerThread个中生成五个Handler对象
  • 调用Looper的loop()方法之后,Looper对象将不止地从音讯队列个中取出对象,然后调用handler的handleMessage()方法,处理该音讯对象;假如音讯队列中从不对象,则该线程阻塞

留神,此时handleMessage()方法是在子线程中运作的。

后台运转效果:

bwin亚洲必赢5566 6

微小地总计一下:

  首先实施Looper的prepare()方法,那几个主意有多少个功用:壹是生成Looper对象,而是把Looper对象和近期线程对象形成键值对(线程为键),存放在ThreadLocal个中,然后生成handler对象,调用Looper的myLooper()方法,得到与Handler所对应的Looper对象,那样的话,handler、looper
、新闻队列就形成了逐条对应的涉及,然后实施上面包车型地铁第多个步骤,即Looper在新闻队列当中循环的取多少。

除此以外,在本文最初叶的第贰段中,大家在主线程中开创Handler也远非调用Looper.prepare()方法,为啥就不曾崩溃呢?,那是由于在程序运营的时候,系统现已帮大家自行调用了Looper.prepare()方法。查看ActivityThread中的main()方法,代码如下所示:

 1 public static void main(String[] args) {  
 2     SamplingProfilerIntegration.start();  
 3     CloseGuard.setEnabled(false);  
 4     Environment.initForCurrentUser();  
 5     EventLogger.setReporter(new EventLoggingReporter());  
 6     Process.setArgV0("<pre-initialized>");  
 7     Looper.prepareMainLooper();  
 8     ActivityThread thread = new ActivityThread();  
 9     thread.attach(false);  
10     if (sMainThreadHandler == null) {  
11         sMainThreadHandler = thread.getHandler();  
12     }  
13     AsyncTask.init();  
14     if (false) {  
15         Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));  
16     }  
17     Looper.loop();  
18     throw new RuntimeException("Main thread loop unexpectedly exited");  
19 }  

 上方代码中,能够看来,在第7行调用了Looper.prepareMainLooper()方法,而以此艺术又会再去调用Looper.prepare()方法,代码如下所示:

1 public static final void prepareMainLooper() {  
2     prepare();  
3     setMainLooper(myLooper());  
4     if (Process.supportsProcesses()) {  
5         myLooper().mQueue.mQuitAllowed = false;  
6     }  
7 } 

 总括:那样基本就将Handler的制程完全搞精通了,总计一下就是在主线程中能够间接创立Handler对象,而在子线程中要求先调用Looper.prepare()才能创立Handler对象。

 

六、为啥在稍微时候子线程中是能够直接更新UI的:

那道面试题应该是本文中最难的1个面试题了,须求可以理解。为了回应这几个难点,大家需求先通过看源码去打听下边那三个难题:

(壹)Android是怎么着检查评定非UI线程去更新UI的

(2)ViewRootImp是什么?

(三)ViewRootImp是在哪儿创造的?

源码作者就不贴出来了,这里本人只是计算一下。

答案:

  非UI线程真的不能更新UI吗?
是能够的

解释:

  在线程中更新UI时会调用ViewParent.invalidateChild()方法检查当前的thread是不是是Mainthread

切实源码如下:

1 final ViewParent p = mParent;
2     if (p != null && ai != null && l < r && t < b) {
3     final Rect damage = ai.mTmpInvalRect;
4     damage.set(l, t, r, b);
5     p.invalidateChild(this, damage);
6 }

 而ViewParent是一个接口类,其实现类是ViewRootImpl,通过查看invalidateChild()方法里面包车型大巴代码就足以看看会他调用checkThread()方法。checkThread()方法如下:

1 void checkThread() {
2     if (mThread != Thread.currentThread()) {   //检查更新UI的线程是否是MainThread
3         throw new CalledFromWrongThreadException(
4         "Only the original thread that created a view hierarchy can touch its views.");
5     }
6 }

 上边包车型地铁第0二行便是检查:在线程中更新UI时当前线程是不是是MainThread。

但是,ViewRootImpl那几个类是在activity的onResume()方法中成立的。固然在子线程中更新UI,只要在ViewRootImpl制造从前更新UI(比如,程序在执行onCreate方法时,作者就去执行setText方法区更新UI),就能够规避掉checkThread()的自笔者批评。

至于本题,给出以下链接我们去细读一下源码吧:

Android更新Ui进阶精解(1):

http://www.jianshu.com/p/6de0a42a44d6

怎么大家能够在非UI线程中更新UI:

http://blog.csdn.net/aigestudio/article/details/43449123

 

自个儿的大众号

下图是自身的微信公众号(生命团队id:vitateam),欢迎有心人关切。今日头条分享技术,公众号分享心智

我会很谢谢第二群关怀本身的人。那时,年轻的本人和您,一无所得;而后,富裕的你和本人,成绩斐然。

bwin亚洲必赢5566 7

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注