【问题标题】:Async task in public static method returns null公共静态方法中的异步任务返回 null
【发布时间】:2012-11-01 16:54:01
【问题描述】:

所以我有一个异步任务,我将它放在一个公共静态方法中,以避免挂起 UI 线程(因为它执行网络调用),同时仍然能够从我的应用程序的几个部分调用它。 Async 任务成功运行并返回一个 JSONOBJECT(我已经记录了部分代码以确认这一点)。但是问题是因为我使用公共静态方法,它应该有一个返回类型(在可能的情况下应该返回 JSONOBJECT)但它总是返回 null ..我怎样才能重新编写我的代码才能返回我的异步任务获取的 JSONOBJECT。代码如下。

public class JSONmethod {
    static InputStream is = null;
    static String res = "";
    static JSONObject jArray = null;
public static JSONObject getJSONfromURL(final String url){


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

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

    try{
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();



    }
    catch(Exception e){
            Log.e("log_tag", "Error in http connection "+e.toString());
    }


    try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
            }
            is.close();
            res=sb.toString();
    }
    catch(Exception e){
            Log.e("log_tag", "Error converting result "+e.toString());
    }
    Log.i("Result BG ", res);
    try{

        jArray = new JSONObject(res);            
    }catch(JSONException e){
            Log.e("log_tag", "Error parsing data "+e.toString());
    }
    return jArray; //at this point the JSONOBJECT has been fetched

     }



    }.execute();
    return jArray;  //Always null
 }

}

【问题讨论】:

  • 当然是空的。在 getJSONfromURL 返回之后,doInBackground 会被调用很多次。

标签: android json android-asynctask


【解决方案1】:

如果您的方法应该是异步的,那么它现在无法返回 JSON 结果...

你可以做的是为你的异步任务提供一个回调,当结果可用时将被调用:

    public class JSONmethod {
    static InputStream is = null;
    static String res = "";
    static JSONObject jArray = null;

    public static interface JSONCallback {
        public void onResult(JSONObject result);
    }

    public static void getJSONfromURL(final String url, final JSONCallback callback) {

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

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

                try {
                    HttpClient httpclient = new DefaultHttpClient();
                    HttpPost httppost = new HttpPost(url);
                    HttpResponse response = httpclient.execute(httppost);
                    HttpEntity entity = response.getEntity();
                    is = entity.getContent();

                } catch (Exception e) {
                    Log.e("log_tag",
                            "Error in http connection " + e.toString());
                }

                try {
                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(is, "iso-8859-1"), 8);
                    StringBuilder sb = new StringBuilder();
                    String line = null;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                    is.close();
                    res = sb.toString();
                } catch (Exception e) {
                    Log.e("log_tag",
                            "Error converting result " + e.toString());
                }
                Log.i("Result BG ", res);
                try {

                    jArray = new JSONObject(res);
                } catch (JSONException e) {
                    Log.e("log_tag", "Error parsing data " + e.toString());
                }

                callback.onResult(jArray);

                return jArray; // at this point the JSONOBJECT has been
                                // fetched

            }

        }.execute();
    }
}

你会这样使用它:

    JSONmethod.getJSONfromURL(url, new JSONCallback() {

        @Override
        public void onResult(JSONObject result) {
            // Do whatever you want with the result
        }
    });

【讨论】:

    【解决方案2】:

    异步任务的基础是,在调用方法作为返回值后,您不会立即得到它的结果。

    您的调用(无论是否静态)只会执行创建任务的过程(不执行它!)并立即返回。系统可能不会立即执行真正的任务流程代码(可能队列中有一些先前的任务等)。一旦它完成 AsyncTask.doInBackground() 方法,并在调用 AsyncTask.onPostExecute() 之后,任务将完成。默认情况下,它不会调用您的任何方法。在 AsyncTask.onPostExecute() 方法上更新 UI 是您的责任。

    【讨论】:

    • +1。好的方法确实是使用您在onPostExecute() 中的结果来更新用户界面
    • @fiddler 我尝试使用 onPostExecute() 但它永远不会被调用。我觉得这很奇怪。让我试试你之前的方法,看看是否有效
    • @fiddler 我刚刚尝试使用您的解决方案,但仍然无法正常工作,返回的结果仍然为空,未返回 JSONOBJECT
    • 您需要了解您的 getJSONfromURL 不能直接返回 JSON 对象,因为它将在后台计算。这就是提供回调的全部意义,该回调将在 JSON 数据可用时接收
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    相关资源
    最近更新 更多