user1341676
user1341676

Reputation:

Android: AsyncTask - doesn't seem to run asynchroneously

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

Answers (1)

Egor
Egor

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

Related Questions