Welcome 微信登录

首页 / 操作系统 / Linux / Android里子线程真的不能刷新UI吗?

如果你在网上搜索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