Android - How to work with AsyncTasks in a class

I am creating an application that links to API

. I have put all the API communication and data handling code in one API class

, so that every time I want to use the API, I have a central place where all the logic lies.

The point is that for is HTTPRequests

highly recommended to use AsyncTasks

. As shown in the examples, you create AsyncTask

by calling the entire class.

My class consists of functions that need to be asynchronous due to HTTP calls. Others don't.

My question is, am I just fetching my entire API class from AsyncTask, or will I split my API class again in the regular and asynchronous part?

+3


source to share


3 answers


Create an interface with two types of methods that don't execute on other threads and others. Use async methods to get a callback object to notify when they are done. Example:

public interface MyAPI {
 //--this method runs an AsyncTask and calls supplied Callback object methods when done
 public void fetchRemoteData(String input, Callback c);

 //--this method just processes input string locally and returns it
 public String doStuff(String input);
}

public interface Callback{
  public void onDone(int doneWhatCode, String result);
}

      

Implementation:



public class MyWebAPI implements MyAPI{
  @Override
  public void fetchRemoteData(String input, final Callback c){
        AsyncTask<String,Void,String> task = new AsyncTask<String,Void,String>(){

            @Override
            protected String doInBackground(String... strings) {
                String i = strings[0];

                //---connect, fetch data ----
                String result = "result";

                return result;
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                c.onDone(1,s);
            }
        };

      task.execute("new Input url");
    }

  @Override
  public String doStuff(String input){
    return input.replace("i","o");
  }
}

      

Let your API be exposed by these interfaces. This way you can keep it all together and also keep the actual implementation for future changes.

+2


source


The point here is that "you can't use this cool form for the UI thread," then you create an AsyncTask. What if you have a service and want to call some API methods? You cannot call AsyncTask from a service thread.
I would leave this class as it is and carry it over to AsyncTask when I would like to call it from the UI.

EDIT: This is an example of porting existing functionality to AsyncTask:

private class GetAuthorisationUrlTask extends AsyncTask<String, Void, String>
{
    private OAuthBuilder oAuthBuilder;
    private GetAuthorisationUrlTaskCallback callback;

    public GetAuthorisationUrlTask(Context context, OAuthBuilder oAuthBuilder, GetAuthorisationUrlTaskCallback callback)
    {
        this.oAuthBuilder = oAuthBuilder;
        this.callback = callback;
    }

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            Log.i(TAG, "Getting authorization url...");
            return oAuthBuilder.getAuthorizationUrl();
        }
        catch (Exception e)
        {
            Log.e(TAG, "Unable to get OAuth authorization url: " + e, e);
            return null;
        }
    }

    @Override
    protected void onPostExecute(String result)
    {
        Log.i(TAG, "Authorisation url: " + result);
        if (result == null)
            Toast.makeText(getApplicationContext(), "Error getting authorization url.", Toast.LENGTH_SHORT).show();
        else
            callback.urlCreated(result);
    }

    static interface GetAuthorisationUrlTaskCallback
    {
        void urlCreated(String url);
    }
}

      



Now you can call AsyncTask and get a callback when the result is ready.

GetAuthorisationUrlTask getAuthorisationUrlTask = new GetAuthorisationUrlTask(this,
        new GetAuthorisationUrlTaskCallback()
        {
            @Override
            public void urlCreated(String url)
            {
                webview.loadUrl(url);
            }
        });
getAuthorisationUrlTask.execute();

      

I know there is so much boiler room code but it completely decouples your interface from your business class logic. Here it only does one task, but expands it to a more general one and does more without introducing new classes easily.

0


source


It's good that it's up to you. You can do 1 AsyncTask

processing of everything and do post updates etc., but if it has many different requests that are not directly related, I would separate them. A good approach might be to think about the use cases and split into different ones AsyncTasks

based on that.

To give an example of a use-based approach:

  • Home Activity

    starts at the beginning AsyncTask

    to initialize.
  • User clicks login / or starts another lengthy operation -> starts second AsyncTask

    .

Then in both cases you will have the old class, but AsyncTasks

will call the api implemented in the old class.

0


source







All Articles