简体   繁体   中英

Android anonymous asyncTask return value in method

Now in my app i try to do http parsing from url, but i didn't carry about threads, before this time...

I have such class and method:

public class TwitterOAuthHelper {
public String httpQueryToApi(String url) {
        HttpGet get = new HttpGet(url);
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setUseExpectContinue(params, false);
        get.setParams(params);
        String response = null;
        try {
            SharedPreferences settings = context.getSharedPreferences("my_app", 0);
            String userKey = settings.getString("user_key", "");
            String userSecret = settings.getString("user_secret", "");
            consumer.setTokenWithSecret(userKey, userSecret);
            consumer.sign(get);
            DefaultHttpClient client = new DefaultHttpClient();
            response = client.execute(get, new BasicResponseHandler());
        } catch (Exception e) {
            displayToast("Failed to get data.");
        }
        return response;
    }

}

and now i try to move this logic into asyncTask:

String result;
public String httpQueryToApi(String url) {
    new AsyncTask<String,Void,String>(){

        @Override
        protected String doInBackground(String... params) {
            HttpGet get = new HttpGet(String.valueOf(params));
            HttpParams param = new BasicHttpParams();
            HttpProtocolParams.setUseExpectContinue(param, false);
            get.setParams(param);
            String response = null;
            try {
                SharedPreferences settings = context.getSharedPreferences("my_app", 0);
                String userKey = settings.getString("user_key", "");
                String userSecret = settings.getString("user_secret", "");
                consumer.setTokenWithSecret(userKey, userSecret);
                consumer.sign(get);
                DefaultHttpClient client = new DefaultHttpClient();
                response = client.execute(get, new BasicResponseHandler());
            } catch (Exception e) {
                displayToast("Failed to get data.");
            }
            result = response;
            return response;
        }
    }.execute(url);
    return result;
    }

but how can i return my response result value to method?

what is the best practice of doing that?

do smth like this:

@Override
protected void onPostExecute(String result) {
    //result is your returned value from doInBackground
}

If you want a callback to antoher method it should be interface

public interface ResultInterface {
     public void resultFromHttp(String result);
}

then your method

public String httpQueryToApi(String url, final ResultInterface ri){
      //as bove
    @Override
    protected void onPostExecute(String result) {
        if(ri!=null)
            ri.resultFromHttp(result);
    }

}

implement ResultInterface for your Activity/Fragment/wahtever is calling httpQueryToApi

You can't since the Task will be executed in another thread.

However you could use a callback to get the result. Take a look at: https://stackoverflow.com/a/19520293/4299154 .

Initially your function returned a string which you then further processed. Fine. But you can not use threading like that. You can not return result from the function, because it has not been set yet (well you can but it will return null). The correct way of doing this is

public void httpQueryToApi(String url) {

    new AsyncTask<String,Void,String>(){

        @Override
        protected String doInBackground(String... params) {
            HttpGet get = new HttpGet(String.valueOf(params));
            HttpParams param = new BasicHttpParams();
            HttpProtocolParams.setUseExpectContinue(param, false);
            get.setParams(param);
            String response = null;
            try {
                SharedPreferences settings = context.getSharedPreferences("my_app", 0);
                String userKey = settings.getString("user_key", "");
                String userSecret = settings.getString("user_secret", "");
                consumer.setTokenWithSecret(userKey, userSecret);
                consumer.sign(get);
                DefaultHttpClient client = new DefaultHttpClient();
                response = client.execute(get, new BasicResponseHandler());
            } catch (Exception e) {
                displayToast("Failed to get data.");
            }
            return response;
        }

        @Override
        protected void onPostExecute(String s) {

            //here s is the response string, do what ever you want
            super.onPostExecute(s);
        }
    }.execute(url);              
}

You will have to shift your further processing logic to onPostExecute, no other way :) If you want do dig a little deeper look into Future<>

1) Create separate class for you Async (not anonymous).

2) Create interface class.

public interface AsyncResponse {
    void onProcessFinish(String output);
}

3) In your Async class, you need to declare it (interface : AsyncResponse):

public class MyAsyncTask extends AsyncTask<String,Void,String>(){
   public AsyncResponse listener = null;    

   public MyAsyncTask(AsyncResponse l) {
        this.listener = l;
    }
   {...}
   @Override
        protected String doInBackground(String... params) {
            HttpGet get = new HttpGet(String.valueOf(params));
            HttpParams param = new BasicHttpParams();
            HttpProtocolParams.setUseExpectContinue(param, false);
            get.setParams(param);
            String response = null;
            try {
                SharedPreferences settings = context.getSharedPreferences("my_app", 0);
                String userKey = settings.getString("user_key", "");
                String userSecret = settings.getString("user_secret", "");
                consumer.setTokenWithSecret(userKey, userSecret);
                consumer.sign(get);
                DefaultHttpClient client = new DefaultHttpClient();
                response = client.execute(get, new BasicResponseHandler());
            } catch (Exception e) {
                displayToast("Failed to get data.");
            }
            result = response;
            return response;
        }


   @Override
   protected void onPostExecute(String result) {
      listener.onProcessFinish(result);
   }
}

4) In your class (where you call AssyncClass, for example in your Activity) you need to implements interface you created earlier AsyncResponse.

public class MainActivity implements AsyncResponse{



  {...}
   void onProcessFinish(String output){
     //this you will received result fired from async class of onPostExecute(result) method.
   }
}

6) now you can call in MainActivity:

new MyAsyncTask(this).execute("your_url");

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