查看原文
其他

子线程为什么不能更新UI线程详解

2017-01-10 于哥 终端研发部
今日要闻

微信小程序来了!低频、简单的App可能在颤抖了……

微信做小程序,本意是想圈住那批低频刚需的轻应用。高频刚需,或者操作复杂的应用,像手机网游,很明显还是通过App操作要体验更好。这里就要讨论到安卓版和苹果版的区别。安卓一直比较开放,小程序也是,用户可以选择直接将小程序添加到桌面,跟之前张小龙朋友圈流出的截图基本一致。但苹果版就不可以添加到桌面。理由很简单,假设桌面上都是小程序了,App自然会降低使用率或者被卸载,那么苹果辛辛苦苦维护的生态就会被打乱,自然是不愿意的。并且,在苹果App Store中,大部分应用内购买是需要跟苹果分成的,而小程序目前是不收费的,这对苹果也是冲击,不知具体是微信跟苹果是怎样协商的,很有可能在小程序内是屏蔽了需要分成的功能。面对小程序的到来,我们AndroidDeveloper开发者要努力了。

文正

于亚豪的博客地址:

http://blog.csdn.net/androidstarjack/article/details/54238073

  • 子线程整的不能更新UI线程吗

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

有时候大家做项目的时候偶尔会碰到这个错误。不用说大家都知道是子线程更新主线程(UI)线程的问题,同样大家也会给出相对应的解法:使用handle+Thread方法通过发送Message进行更新UI线程。 
eg:

此时就会出现一下错误: 

此时我们都知道最简单的一种解决方式就是:

接下来我们就来探究一下:子线程和UI线程之间更新问题。 
首先我们要知道:

  • android应用程序遵循的是按照单线程模式的原则 
    这是因为:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。 
    android的UI线程就是主线程,当成粗第一次启动的时候 Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。这个和Java的运行机制是不同的。 
    andorid在UI中进行绘图和处理事件启动一个监听的作用 ,此时就必须要在UI中时时刻刻的进行相应用户的点击事件和UI操作事件。异步操作以及耗时操作需要另外气一个线程,不然UI线程在5s内未响应用户的操作,系统就会弹出弹出对话框停止程序终止进程的提示。

我们想看看报错的这行代码在ViewRootImpl.java:

mThread是一个线程,如果改线程是当前的线程的时候,则继续向下走,不会抛出异常。大家可以看到,我在onCreate方法,只有一个线程,肯定是当前的线程,那为什么会报错呢?我们接着往下看。 
接下来我们看看checkThread()在那几处用到了,其中有

从报错的点 at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:848)我们可以看到是848行是invalidateChildInParent方法里调用的。我们进一步与发现invalidateChildInParent又在invalidateChild()里调用,在View中那个地方调用了呢?我们进一步向下跟进。

而invalidateInternal方法在invalidate()方法中是这样的

  • 到这里一目了然了。原来View中再重新回执的时候刷新方法里调用了ViewRootImpl的checkThre(),刷新是检查该线程是不是当前的线程,即主线程。

  • 我们根据源码可以知道invalidate()–>checkThread()是一步一步去调用的。

  • android.view.View.setBackground()

  • android.view.View.setBackground()—->setBackgroundDrawable()–> invalidate()–>invalidateInternal()–>invalidateChild()–>checkThread()–>invalidateRectOnScreen()

现在我们清楚了,严格的来说原来子线程是不能刷新UI线程的。 
解决方式: 
第一种方式:

第二中方式:

第三种方式: 利用AsyncTask方法。 
以上都是进程间通讯的几种方式。这里做了一些总结,日积月累方可渐进

如果您觉我的文章对您有所帮助, 欢迎加入终端研发部
QQ交流群 :232203809,欢迎入群 

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:

 
微信公众号:终端研发部 
(欢迎关注学习和交流)

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存