公共静态方法中的异步任务返回 null
Posted
技术标签:
【中文标题】公共静态方法中的异步任务返回 null【英文标题】:Async task in public static method returns 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 会被调用很多次。 【参考方案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 数据可用时接收以上是关于公共静态方法中的异步任务返回 null的主要内容,如果未能解决你的问题,请参考以下文章