Lesson 88. AsyncTask. The final result. get method

Lesson 88. AsyncTask. The final result. get method


In this lesson:

– we use the third parameter
– use the get method to get the result

In the last lesson, we looked at the types of data that we specify in corner brackets when describing the AsyncTask class heir. There are three of them:

1) Type incoming data. This is the data that goes to the AsyncTask login

2) Type intermediate data. Data used to output intermediate results

3) Type are coming back data. What will return AsyncTask after work.

We have already worked with the first two. Now we will use third. This is the type (class) of object we need return with AsyncTask. There are two ways to get this object:

1) It is passed to the input method onPostExecuteThat works after the job is completed

2) The get method returns this object to us

We call the get method to get the result of AsyncTask. But what if the task is not yet completed and we called get? The get method will wait. That is, it simply blocks the thread in which it is executed and does not release until it receives some result or an exception pops up.

There is another implementation of the get method with timeout. In this case, get will wait for the specified time and then generate Exception. If the task has already been completed, then the method will be executed immediately and nothing will be expected.

Let’s look at an example. Let’s create an application, we will start the task, which will hang for 5 seconds, and try calling the get method.

Let’s create a project:

Project name: P0881_AsyncTaskResult
Build Target: Android 2.3.3
Application name: AsyncTaskResult
Package name: en.startandroid.develop.p0881asynctaskresult
Create Activity: MainActivity

strings.xml:



	AsyncTaskResult
	Start
	Result

main.xml:



	
	
	
	
	
	

The Start button will start the task and the Result button will output the result. ProgressBar, which will show that the application is hanging. TextView for displaying information.

MainActivity.java:

package ru.startandroid.develop.p0881asynctaskresult;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

  final String LOG_TAG = "myLogs";
  
  MyTask mt;
  TextView tvInfo;

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    tvInfo = (TextView) findViewById(R.id.tvInfo);
  }

  public void onclick(View v) {
    switch (v.getId()) {
    case R.id.btnStart:
      mt = new MyTask();
      mt.execute();
      break;
    case R.id.btnGet:
      showResult();
      break;
    default:
      break;
    }
  }
  
  private void showResult() {
    if (mt == null) return;
    int result = -1;
    try {
      Log.d(LOG_TAG, "Try to get result");      
      result = mt.get();
      Log.d(LOG_TAG, "get returns " + result);
      Toast.makeText(this, "get returns " + result, Toast.LENGTH_LONG).show();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (ExecutionException e) {
      e.printStackTrace();
    }
  }

  class MyTask extends AsyncTask {
    @Override
    protected void onPreExecute() {
      super.onPreExecute();
      tvInfo.setText("Begin");
      Log.d(LOG_TAG, "Begin");
    }
    
    
    @Override
    protected Integer doInBackground(Void... params) {
      try {
        TimeUnit.SECONDS.sleep(5);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return 100500;
    }
    
    @Override
    protected void onPostExecute(Integer result) {
      super.onPostExecute(result);
      tvInfo.setText("End. Result = " + result);
      Log.d(LOG_TAG, "End. Result = " + result);
      
    }
  }
}

IN onclick we determine which button was clicked. If Start, then we create and run tasks. If Result, then we call the showResult method.

IN showResult we are trying to get the result from the current job using the get method. The result is displayed in the log and on the screen.

In the AsyncTask description, we specified Void for the first two data types and Integer for the third. This third Integer is the type (class) of object that should return to us from AsyncTask. Note that this type is specified as type are coming back data for the method doInBackground and as incoming for the method onPostExecute. That is, we perform tasks in doInBackground, we form result type Integer and we return it as a result of this method. And further this result hits and can be used in onPostExecuteExecuted upon completion of the task. We output it to the log and to the screen.

IN doInBackground we pause in 5 seconds and return the number 100500.

We will save everything and launch the application. press Start

and we wait 5 seconds for the task to complete. The result text appears.

now click Result

AsyncTask gave us the same result that came in onPostExecute. Everything is logical.

Now let’s try to call the get method until the task is completed. To do this, press Start and immediately click Result

press Start, And right after him Result

stopped ProgressBarBecause the main stream blocked by the get method. The get method is waiting for AsyncTask to finish. This continues until what we wrote in is executed doInBackground. The get method then returns the result and releases the stream.

We look at the logs:

13: 06: 27.224: D / myLogs (656): Begin
13: 06: 27.479: D / myLogs (656): Try to get result
13: 06: 32.316: D / myLogs (656): get returns 100500
13: 06: 32.364: D / myLogs (656): End. Result
= 100500

You can see how the task started (Begin). Almost immediately they clicked on the Result and started the get (Try to get result). But it worked (get returns 100500) Get method only after 5 seconds, that is, until the task is completed. All this time he waited and, thus, blocked the stream in which he was running. At about the same time, onPostExecute (End. Result = 100500).

Let’s try adding a timeout. rewrite the method showResult:

  private void showResult() {
    if (mt == null) return;
    int result = -1;
    try {
      Log.d(LOG_TAG, "Try to get result");      
      result = mt.get(1, TimeUnit.SECONDS);
      Log.d(LOG_TAG, "get returns " + result);
      Toast.makeText(this, "get returns " + result, Toast.LENGTH_LONG).show();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (ExecutionException e) {
      e.printStackTrace();
    } catch (TimeoutException e) {
      Log.d(LOG_TAG, "get timeout, result = " + result);
      e.printStackTrace();
    }
  }

The get method has changed. Now it waits one second, and if it doesn’t get the result, it generates TimeoutException. We catch this exception and log the corresponding message.

Save, run. press Start and immediately Result. The app is up again but comes to life in a second. We look at the log:

13: 10: 42.574: D / myLogs (724): Begin
13: 10: 42.875: D / myLogs (724): Try to get result
13: 10: 43.883: D / myLogs (724): get timeout, result = -1
13: 10: 47.615: D / myLogs (724): End. Result
= 100500

You can see how the task started (Begin). Almost immediately they clicked on the Result and started the get (Try to get result). A second later, TimeoutException worked, and we see that get did not return any result (get timeout, result = -1). Well, after 5 seconds, onPostExecute (End. Result = 100500).

In the next lesson:

– cancel the task in progress




Discuss in the forum [44 replies]

Leave a Comment