2

I am confused as to why updating an ui element in a handler, asynctask, or runOnUiThread IF YOU ARE ON UI THREAD ALREADY consider the following snippets, numbered from 1 to 4: (for demo purpose, might have syntax error)

// 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!!");
           }
          });
}

as you can see from examples #1 - #4, i don't see why you need to use #2, #3, or #4, becuase #1 you are already on UI thread!!!

in other words, i am saying #1-#4 are the same -- i.e. you want to execute something on the UI THREAD/MAIN THREAD, so tell me why you would use #2, #3, or #4, if #1 is already on UI thread.

what is the difference between each one?

please provide any citation of documentation or real use cases

thank you!!

XyzNullPointer
  • 275
  • 6
  • 11

3 Answers3

0

There is no need to use runOnUiThread or any of the other cases you described if you are already on the UI thread. These are provided for cases when you're NOT in the UI Thread.

Read up here on the developer guide. It includes examples explaining what can go wrong if you try to perform actions on the UI outside the UI thread and explains the various options to avoid them.

But in your examples, put simply, you are in an activity and you havent spawned any other threads, so you are in the UI thread and dont need any special methods to access the UI.

Akash
  • 631
  • 1
  • 8
  • 16
  • sure thanks for your answer, but in a lot of cases, a lot of examples i see online, they don't have new thread either, but they use these #2-#4 to update, i have no clue why. so i am skeptical to your answer, but i could be wrong. – XyzNullPointer Apr 23 '13 at 05:11
0

I find it a bit hard to tell what exactly your question is, but a few notes regarding your thesis.

No, #1 to #4 are not the same.

  • Validity: Yes, if you are on the UI thread already and have no expensive computations or lengthy I/O operations to do, then there's no need to choose from #2 to #4.
  • Timing: Depending on circumstances, the effects of #2 to #4 have a certain probability of appearing a bit later than #1.
  • Complexity/waiting: Only #4 will in general enable you to cleanly wait for blocking I/O or do a lengthy calculation. Depending on the Handler, #2 may also work, but that's not what Handlers are made for.
  • Handlers: In your #2, there is no guarantee that you are using the main/UI thread handler at all. The code could well run on a non-main/UI thread.
  • 3 is a convenience method.

So no, they are far from being the same in general.

P.S.

  • Priority: Depending on what kind of Thread your code ends up when you use a Handler, and in any default case for doInBackground() of AsyncTask, your code will run with background priority and have to live with 10% CPU time together with all other background threads on the system unless you adjust the priority. For a detailed discussion, see here.

P.P.S.

Since you asked "the other way round" in a comment:

  • 1 is the most effective and direct if you are sure you're on the UI thread and don't do calculations and/or I/O

  • 2 is only valid if the handler uses the main/UI thread. WHy use it? If you're somewhere in your code, detached from any available Context or View, you can still do newHandler(Looper.getMainLooper()) and that gives you a Handler for the UI thread.

  • 3 refers to View and Context related convenience methods. As soon as you have one of those objects at hand, you can use them to do something on the UI thread.

  • 4 must be used if you're doing expensive operations or waiting. However, AsyncTask is only a convenience class for this purpose and intended for relatively short operations.

Community
  • 1
  • 1
class stacker
  • 5,357
  • 2
  • 32
  • 65
  • given the example above, where we are just changing the text field of the textview, why would #2 to #4 appear later? – XyzNullPointer Apr 23 '13 at 05:16
  • @XyzNullPointer The setting of the text, like other UI property changes, has no immediate effect. It would be too inefficient for a UI to render everything immediately (also, it would end up flickering). Hence, on the UI thread, there's a UI entity which triggers re.rendering. In #1, you immediately give it reason to do something. In #2 to #3, you first schedule something which will give it a cause to do something. In your trivial example, you won't notice much of a difference, of course. – class stacker Apr 23 '13 at 05:38
  • @XyzNullPointer Saw one of your comments and updated my answer. – class stacker Apr 23 '13 at 06:23
  • Hi Class Stacker, thank you so much. can you explain case #5 that i added? – XyzNullPointer Apr 23 '13 at 17:13
  • @XyzNullPointer #5 I already explained; those are convenience functions of `View`s which I mentioned in my P.P.S. for #3. Often, you have `View` objects at hand and they are created in a `Context` so it`s easy for them to provide these methods for your convenience. – class stacker Apr 23 '13 at 17:55
0

1 This is the correct and most direct way to update UI as you are in UI Thread

  • If you want to simply update UI you don't need #2 #3 and #4

2 Handlers are specifically used when we need to perform a task in separate thread

3 runonUI() is never used in oncreate() as you are already on UI thread.It is used to update UI from non UI thread eg from doinbackground() of async task

4 Async Tasks should never be used to update just the UI elements ,there main purpose is to perform tasks in background of a activity only.Although pre and post execute functions can update UI .

Rachita Nanda
  • 4,509
  • 9
  • 42
  • 66