发布网友 发布时间:2022-04-21 17:41
共1个回答
热心网友 时间:2023-09-27 23:39
》,会回答:不能。那么到底能不能呢?呵呵,其实是能的了。那么《Android里子线*的不能刷新UI吗? 》里写错了吗?嗯,没有。呵呵,相信大家看到这里一定是一头雾水,认为笔者自相矛盾了。让我们看个实例吧:package com.david.test.helloworld; importAndroid.app.Activity;import android.os.Bundle;import android.widget.Button; public class TestActivity extends Activity { Button btn = null; /** Called when the activity is first created. */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.Button01); TestThread2 t = new TestThread2(btn); t.start(); } class TestThread2 extends Thread { Button btn = null; public TestThread2(Button btn) { this.btn = btn; } @Override public void run() { btn.setText("TestThread2.run"); } }}建立一个工程,将上述代码拷贝进去,运行看看吧! Btn的文本一定改变为"TestThread2.run"了。那么这到底是怎么回事呢?当我发现这个问题时,也困惑了。经过一番调查后,*大白。现在和大家分享一下。奥秘在于ViewRoot的建立时间,它是在ActivityThread.java的final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward)里创建的。看看代码吧: final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheleGcIdler(); ActivityRecord r = performResumeActivity(token, clearHide); if (r != null) { final Activity a = r.activity; if (localLOGV) Slog.v( TAG, "Resume " + r + " started activity: " + a.mStartedActivity + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished); final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; // If the window hasn't yet been added to the window manager, // and this guy didn't finish itself or start another activity, // then go ahead and add the window. boolean willBeVisible = !a.mStartedActivity; if (!willBeVisible) { try { willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( a.getActivityToken()); } catch (RemoteException e) { } } if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; wm.addView(decor, l); } // If the window has already been added, but ring resume // we started another activity, then don't yet make the // window visible. } else if (!willBeVisible) { if (localLOGV) Slog.v( TAG, "Launch " + r + " mStartedActivity set"); r.hideForNow = true; } // The window is now visible if it has been added, we are not // simply finishing, and we are not starting another activity. if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null) { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " + r.newConfig); performConfigurationChanged(r.activity, r.newConfig); r.newConfig = null; } if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); WindowManager.LayoutParams l = r.window.getAttributes(); if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) { l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit; if (r.activity.mVisibleFromClient) { ViewManager wm = a.getWindowManager(); View decor = r.window.getDecorView(); wm.updateViewLayout(decor, l); } } r.activity.mVisibleFromServer = true; mNumVisibleActivities++; if (r.activity.mVisibleFromClient) { r.activity.makeVisible(); } } r.nextIdle = mNewActivities; mNewActivities = r; if (localLOGV) Slog.v( TAG, "Scheling idle handler for " + r); Looper.myQueue().addIdleHandler(new Idler()); } else { // If an exception was thrown when trying to resume, then // just end this activity. try { ActivityManagerNative.getDefault() .finishActivity(token, Activity.RESULT_CANCELED, null); } catch (RemoteException ex) { } }}呵呵,相信到了这里,看过《Android里子线*的不能刷新UI吗? 》的读者一定明白了。答案就是在Activity.onResume前,ViewRoot实例没有建立,所以没有ViewRoot.checkThread检查。而btn.setText时设定的文本却保留了下来,所以当ViewRoot真正去刷新界面时,就把"TestThread2.run"刷了出来!最后,提个问题结束吧:activity.onStart里通过线程刷新UI能成功吗?别回答太快哟!好好想想!