Reputation: 219
I'm facing this issue. I want my main thread to resume its execution only when other threads complete their execution. But my main thread is not executing even if other threads have done with their execution.
My code is as below:
public class MainActivity extends ActionBarActivity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text_test);
TestLocalHost th = new TestLocalHost();
Thread exe = new Thread(th);
exe.start();
try {
exe.join();
}
catch (InterruptedException e){
e.printStackTrace();
}
mTextView.setText("MainThread");
}
private class TestLocalHost implements Runnable {
@Override
public void run() {
final String s = JSONParser.doGet("http://<My system ip>/GetResult.ashx?op=getInfo",null);
runOnUiThread(new Runnable() {
@Override
public void run()
{
mTextView.setText(s);
}
});
}
}
}
I'm setting the value of mTextView
with a value from exe
thread. I need my main thread overwrite the mTextView
with "Main thread"
after it executes. I used a join()
function to exe
thread which will ensures main thread will wait till this thread completes execution. But once this thread completes exectuion my main thread is not writing into mTextView
. What mistake am I doing?
Upvotes: 2
Views: 570
Reputation: 39406
This has to do with how runOnUiThread
works.
In android, the main thread has a Looper
. That Looper
holds a queue of runnable to run, one at a time.
When you call runOnUiThread
, the Runnable
is enqueued to the looper, meaning it will be executed after the current thing being run by the looper is done, and the queue is empty.
In your case, the Looper is executing onCreate
when you call join
. That means that your runOnUiThread
will be enqueued for after that.
In terms of sequencing, that means that the following order of calls issue:
Upvotes: 3
Reputation: 19969
The reason for the "main thread not writing into mTextView
" is that Thread exe
terminates earlier than the one started by the runOnUiThread()
method. And since join()
waits only for Thread exe
to finish (not the other one), you appearentely get "MainThread" of mTextView
overwritten with String s set on the other thread.
You can check it by, for example, seeing Log
:
...
mTextView.setText("MainThread");
Log.d("THREAD", mTextView.getText().toString());
Upvotes: 1
Reputation: 8023
Try using AsyncTask. It is meant for exactly this purpose.
private class GetDataFromNetwork extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
//Get Data using url
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
//Update UI Here. This runs on the UI Thread.
}
}
Upvotes: -2