问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Android子线程在没有ViewRoot的情况下能刷新UI吗?

发布网友 发布时间: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能成功吗?别回答太快哟!好好想想!
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
怎样打开oppor8315的移动磁盘,我想下点小说都不行 op手机r8315质量好不 酷狗音乐会员怎么开通划算?不同渠道价格对比 酷狗透视卡是什么意思 装甲输送车性能 M59履带式装甲人员输送车性能数据 车厘子和草莓是寒性水果吗-车厘子和草莓是凉性的吗 我想了解国寿鑫福临门年金保险 安卓手机如何把数据迁移到iPhone13上?最详细操作方法,小白都会 BIOS里的CSM是什么啊? 广西钦州市灵山县的风景名胜区“六峰山”分别指哪六... 健康险包括哪些保险呢 关于中西方餐桌上的礼仪差异 android中如何实现循环更新UI,延迟时间为1秒? ISO2000具体是什么? 广西灵山县那里比较好玩一点? 西餐礼仪 健康险都包含哪些啊?买的时候要怎么选啊? Android的handler机制的原理? 灵山景点简介 什么是iso20000标准,it服务管理体系认证 android 怎么刷新UI组件 iso20000是什么管理体系 健康险是不是险种很多,那具体健康险包括哪些有知... 广西灵山那边有什么旅游景点,或好玩 有特色的地方?... Android更新Ui的几种方法和见解 关于西方的餐桌礼仪 人寿健康险100种疾病包括哪些疾病呢 灵山附近有哪些景区 饭桌上哪个位置是上座 西餐礼仪细节 健康险包括哪些种类? 上饶灵山风景名胜区的介绍 健康险包括哪些疾病 ISO20000认证需要准备哪些资料? 灵山自然风景区怎么样?能不能说说? ISO20000认证需要什么条件? 健康保险包括哪些险种? ISO20000需要什么条件才可以做? ISO20000标准的介绍 谁知道健康险都保哪些疾病呢? 初中生怎样学好历史? ISO20000的流程是什么? 怎样学好初中历史??? ISO20000标准的简介 合众人寿健康险都包括哪些重大疾病? 怎么才能学好初中历史 ISO20000的介绍 健康保险主要有哪些类型? 怎样学好初一的历史