你好,游客 登录 注册 搜索
背景:
阅读新闻

Android里子线程真的不能刷新UI吗?

[日期:2011-10-17] 来源:Linux社区  作者:imyfriend [字体: ]
如果你在网上搜索CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views. 那么你肯定能看到很多文章说Android里子线程不能刷新UI。这句话不能说错,只是有些不太严谨。其实线程能否刷新UI的关键在于ViewRoot是否属于该线程。

       让我们一起看看代码吧!

       首先,CalledFromWrongThreadException这个异常是有下面的代码抛出的:

    void checkThread() {

        if (mThread != Thread.currentThread()) {

            throw new CalledFromWrongThreadException(

                    "Only the original thread that created a view hierarchy can touch its views.");

        }

}

该段代码出自 framework/base/core/java/android/view/ViewRoot.java

       其次,看看RootView的构造函数:

    public ViewRoot(Context context) {

        super();

 

        if (MEASURE_LATENCY && lt == null) {

            lt = new LatencyTimer(100, 1000);

        }

 

        // For debug only

        //++sInstanceCount;

 

        // Initialize the statics when this class is first instantiated. This is

        // done here instead of in the static block because Zygote does not

        // allow the spawning of threads.

        getWindowSession(context.getMainLooper());

       

        mThread = Thread.currentThread();

        mLocation = new WindowLeaked(null);

        mLocation.fillInStackTrace();

        mWidth = -1;

        mHeight = -1;

        mDirty = new Rect();

        mTempRect = new Rect();

        mVisRect = new Rect();

        mWinFrame = new Rect();

        mWindow = new W(this, context);

        mInputMethodCallback = new InputMethodCallback(this);

        mViewVisibility = View.GONE;

        mTransparentRegion = new Region();

        mPreviousTransparentRegion = new Region();

        mFirst = true; // true for the first time the view is added

        mAdded = false;

        mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, this);

        mViewConfiguration = ViewConfiguration.get(context);

        mDensity = context.getResources().getDisplayMetrics().densityDpi;

    }

       最后,我们看看ViewRoot.checkThread的调用顺序:

com.david.test.helloworld.MainActivity$TestThread2.run

  -> android.widget.TextView.setText

    -> android.widget.TextView.checkForRelayout

      -> android.view.View.invalidate

        -> android.view.ViewGroup.invalidateChild

          -> android.view.ViewRoot.invalidateChildInParent

            -> android.view.ViewRoot.invalidateChild

              -> android.view.ViewRoot.checkThread

linux
相关资讯       Android基础教程  Android开发教程 
本文评论   查看全部评论 (1)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款
第 1 楼
* 匿名 发表于 2013/2/15 11:04:42
111