歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android裡子線程真的不能刷新UI嗎?

Android裡子線程真的不能刷新UI嗎?

日期:2017/3/1 11:11:55   编辑:Linux編程
如果你在網上搜索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

Copyright © Linux教程網 All Rights Reserved