Android为什么要在处理程序或异步任务中更新用户界面
如果您已经在ui线程上,为什么要更新处理程序、asynctask或runOnUiThread中的ui元素,对此我感到困惑 考虑下面的代码段,编号从1到4:(出于演示目的,可能有语法错误) 正如您从示例1到4中所看到的,我不明白您为什么需要使用2、3或4,因为1您已经在UI线程上了 换句话说,我是说#1-#4是一样的——也就是说,你想在UI线程/主线程上执行一些东西,那么告诉我,如果#1已经在UI线程上,为什么要使用#2、#3或#4 它们之间有什么区别 请提供任何文档或实际用例的引用Android为什么要在处理程序或异步任务中更新用户界面,android,android-asynctask,handler,message-queue,Android,Android Asynctask,Handler,Message Queue,如果您已经在ui线程上,为什么要更新处理程序、asynctask或runOnUiThread中的ui元素,对此我感到困惑 考虑下面的代码段,编号从1到4:(出于演示目的,可能有语法错误) 正如您从示例1到4中所看到的,我不明白您为什么需要使用2、3或4,因为1您已经在UI线程上了 换句话说,我是说#1-#4是一样的——也就是说,你想在UI线程/主线程上执行一些东西,那么告诉我,如果#1已经在UI线程上,为什么要使用#2、#3或#4 它们之间有什么区别 请提供任何文档或实际用例的引用 谢谢 如果您
谢谢 如果您已经在UI线程上,则无需使用
runOnUiThread
或您描述的任何其他情况。这些是为您不在UI线程中的情况提供的
阅读《开发者指南》。它包括一些示例,解释了如果您试图在UI线程之外的UI上执行操作,会出现什么问题,并解释了避免这些操作的各种选项
但是在你的例子中,简单地说,你在一个活动中,你没有产生任何其他线程,因此你在UI线程中,不需要任何特殊的方法来访问UI。我发现有点难以说出你的问题到底是什么,但是关于你的论文有一些注释 不,1到4不一样
- 有效性:是的,如果您已经在UI线程上,并且没有昂贵的计算或冗长的I/O操作要做,那么就不需要从#2到#4中进行选择
- 时机:根据具体情况,#2到#4的效果有一定的概率比#1晚一点出现
- 复杂性/等待:通常只有#4可以让您干净地等待阻塞I/O或进行冗长的计算。#2也可以工作,这取决于
,但这不是处理程序的用途处理程序
- 处理程序:在#2中,根本不能保证您使用的是main/UI线程处理程序。代码可以在非main/UI线程上运行
- 3是一种方便的方法。
- 优先级:取决于使用
处理程序时代码的线程类型,以及在
异步任务的
的任何默认情况下,您的代码将以后台优先级运行,并且必须与系统上的所有其他后台线程一起使用10%的CPU时间,除非您调整优先级。一段时间doInBackground()
- 如果您确信自己在UI线程上并且不进行计算和/或I/O,那么1是最有效和最直接的
- 2仅在处理程序使用main/UI线程时有效。为什么要用它?如果您在代码中的某个地方,与任何可用的
或上下文
分离,您仍然可以执行视图
,这将为UI线程提供一个newHandler(Looper.getMainLooper())
。处理程序
- 3指
和查看
相关便利方法。只要手头有一个对象,就可以使用它们在UI线程上执行某些操作。上下文
- 如果您正在进行昂贵的操作或等待,则必须使用4。然而,
只是一个方便的类,用于相对较短的操作。AsyncTask
- 如果您只想简单地更新UI,则不需要2和4
4不应仅用于更新UI元素,其主要目的是仅在活动的后台执行任务。虽然执行前和执行后功能可以更新UI。当然感谢您的回答,但在很多情况下,我在网上看到的很多示例中,它们也没有新线程,但它们使用这些#2-#4进行更新,我不知道为什么。因此,我对你的答案表示怀疑,但我可能是错的。鉴于上述示例,我们只是更改textview的文本字段,为什么稍后会出现#2到#4?@XyzNullPointer文本设置与其他UI属性更改一样,不会立即生效。对于UI来说,立即呈现所有内容的效率太低(而且,它最终会闪烁)。因此,在UI线程上,有一个UI实体触发重新渲染。在#1中,你立即给它做某事的理由。在第二到第三节中,你首先安排一些事情,让它有理由做一些事情。当然,在您的小例子中,您不会注意到有多大的不同。@XyzNullPointer看到了您的一条评论并更新了我的答案。嗨,Class Stacker,非常感谢您。你能解释一下我添加的案例5吗?@XyzNullPointer#5我已经解释过了;这些是我在第3页的P.P.s.中提到的
View
s的便利功能。通常,您手头有视图
对象,它们是在上下文中创建的
,所以它们很容易为您的方便提供这些方法。您对#3的回答对我来说毫无意义,我的意思是rununuithread是一种活动方法,如何从另一个线程调用它…?另一个线程表示非UI线程,例如异步任务的doinbackground()
// in MainActivity.java #1
public void onCreate(Bundle bundle) {
setContentView(R.layout.main);
TextView name = (TextView)findViewById(R.id.name);
name.setText("Name Changed!!");
}
// in MainActivity.java #2
public void onCreate(Bundle bundle) {
setContentView(R.layout.main);
TextView name = (TextView)findViewById(R.id.name);
handler.post(new Runnable() {
public void run() {
name.setText("Name Changed!!");
}
});
}
// in MainActivity.java #3
public void onCreate(Bundle bundle) {
setContentView(R.layout.main);
TextView name = (TextView)findViewById(R.id.name);
runOnUiThread(new Runnable() {
public void run() {
name.setText("Name Changed!!");
}
});
}
// in MainActivity.java #4
public void onCreate(Bundle bundle) {
setContentView(R.layout.main);
...same thing,...update textview in AsyncTask
}
// in MainActivity.java #5
public void onCreate(Bundle bundle) {
setContentView(R.layout.main);
TextView name = (TextView)findViewById(R.id.name);
name.post(new Runnable() {
public void run() {
name.setText("Name Changed!!");
}
});
}