首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android已经启动,为什么要在处理程序或异步任务中更新UI

Android已经启动,为什么要在处理程序或异步任务中更新UI
EN

Stack Overflow用户
提问于 2013-04-23 12:55:30
回答 3查看 610关注 0票数 2

我搞不懂为什么在UI线程上更新处理程序、异步任务或runOnUiThread中的ui元素时,已经考虑了以下代码片段(编号从1到4):(出于演示目的,可能存在语法错误)

代码语言:javascript
复制
// 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!!");
           }
          });
}

正如你在示例#1 -#4中看到的,我不明白为什么你需要使用#2、#3或#4,因为#1你已经在UI线程上了!

换句话说,我说的是#1到#4是相同的--也就是说,你想在UI线程/主线程上执行一些东西,所以告诉我,如果#1已经在UI线程上,为什么你会使用#2,#3,或者#4。

它们之间的区别是什么?

请提供任何文档或真实用例的引用

谢谢你!!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-23 13:10:06

我发现很难确切地说出你的问题是什么,但是关于你的论文有几个注释。

不,#1到#4是不同的。

  • #1.
  • Complexity/waiting::是的,如果你已经在UI线程上,并且没有昂贵的计算或冗长的I/O操作要做,那么就不需要从#2到#4之间进行选择。
  • 计时:根据情况,#2到#4的影响有一定的概率比UI线程晚一点出现,只有#4通常才能让你干净利落地等待阻塞I/O或进行冗长的计算。根据Handler的不同,#2也可以工作,但这不是处理程序的目的。
  • 处理程序:在#2中,根本不能保证您使用的是主/UI线程处理程序。代码可以很好地在非main/UI线程上运行。
  • 3是一种方便的方法。

因此,它们在总体上远远不是相同的。

P.S.

  • 优先级:取决于你的代码在使用Handler时结束的Thread类型,在任何默认的doInBackground() of AsyncTask情况下,你的代码将以后台优先级运行,除非你调整优先级,否则你的代码必须与系统上所有其他后台线程一起占用10%的CPU时间。对于detailed discussion, see here.

P.P.S.

既然你在评论中问到了“相反的方向”:

如果您确信自己在UI线程上并且不进行计算和/或I/O,则

  • 1是最有效和最直接的

仅当处理程序使用主/UI线程时,

  • 2才有效。WHy使用它吗?如果您在代码中的某个位置,与任何可用的ContextView分离,您仍然可以执行newHandler(Looper.getMainLooper()),这将为UI线程提供一个Handler

  • 3指的是与ViewContext相关的便利方法。一旦手头有了这些对象之一,就可以使用它们在UI线程上执行某些操作。

如果您正在执行昂贵的操作或等待,则必须使用

  • 4。但是,AsyncTask只是一个用于此目的的方便类,用于相对较短的操作。
票数 0
EN

Stack Overflow用户

发布于 2013-04-23 13:08:47

它们是为不在UI线程中的情况而提供的。

阅读开发人员指南中的here。它包括一些示例,解释了当您尝试在UI线程之外的UI上执行操作时可能出现的错误,并解释了避免这些错误的各种选项。

但是在你的例子中,简单地说,你在一个活动中,你没有产生任何其他线程,所以你在UI线程中,不需要任何特殊的方法来访问UI。

票数 0
EN

Stack Overflow用户

发布于 2013-04-23 13:16:24

1这是在UI线程中更新UI的正确和最直接的方法

  • 如果您想简单地更新UI,则不需要#2 #3和#4

2当我们需要在单独的线程中执行任务时,专门使用2个Handlers

3 runonUI()从不在oncreate()中使用,因为您已经在UI上了。thread.It用于从非UI线程更新UI,例如从异步任务的doinbackground()更新UI

4 Async Tasks永远不应该只用来更新UI元素,主要目的是在活动的后台执行任务only.Although pre和post execute函数可以更新UI。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16161242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档