I had issues with a previous question where I was unsure whether my code had a memory leak. A few answers were concerned with it being run on the UI thread and so blocking. It is true, it runs on the UI thread and doesn't spawn a new one..
So to solve it I use Thread
instead of Handler
to spawn a new thread outside of UI. The problem now is that I can't manage to delay it like I did with the one ran in the UI thread.
This is my previous question where my original UI thread code is: Is this Runnable safe from memory leak? and the following is the updated code which spawns a new thread:
package com.example.helloworld;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import android.util.Log;
import java.lang.ref.WeakReference;
public class HelloWorldActivity extends Activity
{
private static TextView txtview;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtview = (TextView) findViewById(R.id.mainview);
Thread t = new Thread(new WeakRunnable(txtview));
t.start();
}
private static final class WeakRunnable implements Runnable {
private final WeakReference<TextView> mtextview;
protected WeakRunnable(TextView textview){
mtextview = new WeakReference<TextView>(textview);
}
@Override
public void run() {
TextView textview = mtextview.get();
if (textview != null) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
int test = 5*5;
txtview.setText("Hola Mundo"+test);
}
Log.d("com.example.helloworld", "" + Thread.currentThread().getName()); // Outputs "Thread-<num>" if not running on UI thread
}
}
}
It just sets the view text and appends the result of 5*5
.
As soon as I start the app it quits itself and I don't get why. Something tells me I'm delaying it the wrong way or using runOnUiThread
wrong. Even changing txtview.setText("Hola Mundo"+test);
to runOnUiThread( txtview.setText("Hola Mundo"+test) );
doesn't compile giving error: 'void' type not allowed here
.
In a nutshell: Computation (5*5
in this case) should be done on a separate thread to avoid blocking the main (UI) thread, and the text should be set on the UI taking the computated item from the separate thread. A simple example of your own would be fine too.
UPDATE
I have posted an answer to my own question implementing AsyncTask
.
As @Axxiss said, this case is better suited to
AsyncTask
. I updated my code to useAsyncTask
with aWeakReference
to avoid memory leaks:doInBackground
executes the code in a separate thread, while you can later catch the result withonPostExecute
and execute it in the main (UI) thread without any frills.You can use condition until it is met instead of using thread.sleep();
Use postDelayed method found in the Handler class and Views
change,
to :
Then remove the following sleep clause in your runnable as it is no longer needed