简体   繁体   中英

How is the correct way of an AsyncTask class wait for another AsyncTask class to finish its processes

I'm doing an app that access a Web Service and with the JSON I get from it I create an object and use it in my code. Even though my app is working I don't know it is well written and flawless.

I'll explain what I have then put some Sample codes to demonstrate... First of all I created an Activity with a EditText and a Button, where the user will type a code and click in the button to access my database and check if it exists. The main is here: In my button.OnClickListener I check if the EditText has something on it and if I have internet connection <- (I've never had any problem on this) and after that I call my class RestClient that is extended from AsyncTask, that access the WebService in background and get a object from it. And only after this I will get the result from this RestClient. My solution was to start a new AsyncTask that waits my RestClient and then start the process to get the object.

here is the sample of my code my restClient that Return an Generic Object from my webservice:

public class RestClient<t>  extends AsyncTask<String, String, String> {

private Class<t> tClass;
private t ObjReturn;

public RestClient(Class<t> tClass)
{
    this.tClass = tClass; 
}

public Object getObjectResponse(){
    return ObjetoDeRetorno;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... OnlyTheURL) {
    String urlString = OnlyTheURL[0];
    String error = null;
    WebApiDeRetorno = new WebApiRetorno();
    try {
        Log.i("RestClient","Starting connection");

        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        connection.connect();

        String result = convertStreamToString(connection.getInputStream());

        connection.disconnect();

        JSONObject jsonObject = new JSONObject(result);

        String obj = jsonObject.get("returnObject").toString();

        Gson gson = new Gson();
        ObjReturn = gson.fromJson(obj, tClass);


    } catch (IOException | JSONException e) {
        e.printStackTrace();
        return error;
    }
    return null;
}

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    }
}

my buttom function:

buttonConfirmar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {


            restClient = new RestClient<>(MyObject.class);

            restClient.execute(getString(R.string.WebServiceURL));
            new WhenWebServiceConnectionFinished().execute();

        }
    });

The other AsyncTask Class that is executed AFTER RestClient and needs to Wait it finish:

private class WhenWebServiceConnectionFinished extends AsyncTask<String, Void, Boolean> {
    @Override
    protected void onPreExecute() {
        progressDialog.show();
        super.onPreExecute();
    }

    @Override
    protected Boolean doInBackground(String... params) {

        //THIS IS WHAT I DON'T KNOW IF IT'S OK TO DO:
        do {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (restClient.getStatus() != AsyncTask.Status.FINISHED);
        //WAITING THE restClient.getStatus CHANGE TO FINISHED WITH Thread.sleepS.

        if (checkWebApiRetorno()) {
            objectReturnFromWebApi = (MyObject) restClient.getObjectResponse();

            Intent intent = new Intent(thisActivity, NewActivity.class);
            startActivity(intent);
            finish();
            return true;
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean success) {
        if (progressDialog.isShowing())
            progressDialog.dismiss();

        if (!success)
            dialogBuilder.create().show();

        super.onPostExecute(success);
    }
}

Add callback to first AsyncTask and run second only after onPostExecute fired by first AsyncTask

Something like

public interface AsyncFinishedCallback{
    public void onAsyncFinished();
}

and in first AsyncTask do constructor like this

public RestClient(Class<t> tClass, AsyncFinishedCallback callback)
{
    this.tClass = tClass; 
    this.callback = callback; //declare it somewhere as a field
}

and than

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    if(callback!=null)
        callback.onAsyncFinished();
    }
}

Than in button function

buttonConfirmar.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {


        restClient = new RestClient<>(MyObject.class, new AsyncFinishedCallback(){
    @Override
    public void onAsyncFinished(){
            new WhenWebServiceConnectionFinished().execute();
    }
});

        restClient.execute(getString(R.string.WebServiceURL));

try this: start another task when u get result from first Async task use AsyncTask<String, String, Boolean>

    public class RestClient<t>  extends AsyncTask<String, String, Boolean> {

private Class<t> tClass;
private t ObjReturn;

public RestClient(Class<t> tClass)
{
    this.tClass = tClass; 
}

public Object getObjectResponse(){
    return ObjetoDeRetorno;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected Boolean doInBackground(String... OnlyTheURL) {
    String urlString = OnlyTheURL[0];
    String error = null;
    WebApiDeRetorno = new WebApiRetorno();
    try {
        Log.i("RestClient","Starting connection");

        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        connection.connect();

        String result = convertStreamToString(connection.getInputStream());

        connection.disconnect();

        JSONObject jsonObject = new JSONObject(result);

        String obj = jsonObject.get("returnObject").toString();

        Gson gson = new Gson();
        ObjReturn = gson.fromJson(obj, tClass);
        return true;

    } catch (IOException | JSONException e) {
        e.printStackTrace();
        return  false;;
    }
  return true;
}

@Override
protected void onPostExecute(Boolean result) {
    if (result) {
            //success occurs task finish
             new WhenWebServiceConnectionFinished().execute();
         } else {
                //error occurs 
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM