【问题标题】:Android anonymous asyncTask return value in methodAndroid匿名asyncTask方法中的返回值
【发布时间】:2015-01-25 21:50:10
【问题描述】:

现在在我的应用程序中,我尝试从 url 进行 http 解析,但在此之前我没有携带线程...

我有这样的类和方法:

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;
    }

}

现在我尝试将此逻辑移动到 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;
    }

但是如何将我的响应结果值返回给方法?

这样做的最佳做法是什么?

【问题讨论】:

标签: java android android-asynctask


【解决方案1】:

将下面的方法添加到异步任务主体(doInBackground 方法下面):

@Override
protected void onPostExecute(String result) {
    // result is your returned value from doInBackground
    // now we are in main ui thread
}

如果你想回调另一个方法,它应该是接口

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

然后你的方法

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

}

在您的Activity/Fragment/调用httpQueryToApi 中实现ResultInterface,将this 作为第二个参数传递(ri 接口)

【讨论】:

    【解决方案2】:

    你不能,因为任务将在另一个线程中执行。

    但是,您可以使用回调来获取结果。 看看:https://stackoverflow.com/a/19520293/4299154.

    【讨论】:

      【解决方案3】:

      最初,您的函数返回一个字符串,然后您对其进行进一步处理。美好的。 但是你不能像那样使用线程。你不能从函数返回结果,因为它还没有被设置(你可以,但它会返回 null)。这样做的正确方法是

      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);              
      }
      

      您将不得不将您的进一步处理逻辑转移到 onPostExecute,别无他法:) 如果你想深入了解Future<>

      【讨论】:

        【解决方案4】:

        1) 为您创建单独的异步类(非匿名)。

        2) 创建接口类。

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

        3) 在你的 Async 类中,你需要声明它(接口: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) 在您的类中(您在其中调用 AssyncClass,例如在您的 Activity 中)您需要实现您之前创建的 AsyncResponse 接口。

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

        6) 现在您可以在 MainActivity 中调用:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-05-18
          • 1970-01-01
          • 2019-09-05
          • 1970-01-01
          • 1970-01-01
          • 2016-02-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多