Reputation:
I'm trying to use AsyncTask to make a tas run apart from the main thread, thus prevent locking the thread while the task is running. Have I misunderstood the use for AsyncTask?
The calling code from the main thread:
public void onClick(View view) {
int input = Integer.parseInt(editInput.getText().toString());
String out = "";
try {
out = new RunAsyncTask().execute(Integer.toString(input)).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
From the AsyncTask class:
protected String doInBackground(String... params) {
long start, stop;
long result;
String out = "";
int input = Integer.parseInt(params[0]);
// Dalvik (Java) - Recursive:
start = System.currentTimeMillis();
result = FibLib.fibJR(input);
stop = System.currentTimeMillis();
out += String.format("Dalvik (Java) recursive: %d (%d msec)", result, stop - start);
// Dalvik (Java) - Iterative:
start = System.currentTimeMillis();
result = FibLib.fibJI(input);
stop = System.currentTimeMillis();
out += String.format("\nDalvik (Java) iterative: %d (%d msec)", result, stop - start);
return out
From the FibLib class (which is called by the AsyncTask):
public class FibLib {
public static long fibJR(long n) { //
if (n <= 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fibJR(n - 1) + fibJR(n - 2);
}
// Java implementation - iterative:
public static long fibJI(long n) { //
long previous = -1;
long result = 1;
for (long i = 0; i <= n; i++) {
long sum = result + previous;
previous = result;
result = sum;
}
return result;
}
However, when running this, the main GUI thread is still locked and crashes if the task is more than just a small, quick one. What am I misunderstanding here?
Upvotes: 1
Views: 210
Reputation: 40218
You're calling the AsyncTask
's get() method, which really turns an asynchronous call to synchronous, because it waits for the result of the operation. A better way to return the result of the AsyncTask
to the calling Activity
is to use a callback interface. Create a simple interface
, e.g.:
interface OnTaskCompletedListener {
void onTaskCompleted(Object result);
}
Now implement that interface in your Activity
class:
public class MainActivity extends Activity implements OnTaskCompletedListener {}
Now you should pass the MainActivity
to the AsyncTask
object:
AsyncTask task = new RunAsyncTask(onTaskCompletedListener).execute();
And inside the AsyncTask's onPostExecute()
you return the result to the listener:
onTaskCompletedListener.onTaskCompleted(result);
Now you can use the result in your Activity
's onTaskCompleted()
method.
Hope the explanation was clear enough and it will help you.
Upvotes: 4