我正在使用 JSONparser 在远程 mySQL 数据库中获取一些值,在我在 Android 3.0+ (Honeycomb) 中测试它之前它一直工作正常,它有 Guardian 不允许进程执行在其主线程上进行网络操作。
所以我发现我需要一个Asynctask:How to fix android.os.NetworkOnMainThreadException?
并尝试了这个主题:
Get returned JSON from AsyncTask
Return JSON Array from AsyncTask
How to return data from asynctask
好吧,现在我知道 asynctask 不能返回值,但我需要获取这个 json 值,因为我在不同的 Activity 中有许多调用等待处理和/或在屏幕上显示信息(我想这就是我不能在 OnPostExecute 中执行此操作的原因)。
以下是类,对我的旧 JsonParser 进行了一些改编。
JSONParser.java
public class JSONParser extends AsyncTask<List<NameValuePair>, Void, JSONObject> {
static InputStream is = null;
static JSONObject jObj = null;
static JSONObject result = null;
static String json = "";
private static String jsonURL = "http://192.168.1.119/Server/db/json/";
private ProgressDialog progressDialog;
// constructor
public JSONParser() {
}
@Override
protected void onPreExecute() {
//progressDialog = new ProgressDialog();
progressDialog.setMessage("Aguarde...");
progressDialog.show();
}
protected JSONObject doInBackground(List<NameValuePair>... params) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(jsonURL);
httpPost.setEntity(new UrlEncodedFormEntity(params[0]));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
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();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
protected void onPostExecute(JSONObject jObj) {
result = jObj;
progressDialog.dismiss();
}
public JSONObject getJson(List<NameValuePair> params){
this.execute(params);
return result;
}
}
UserFunctions.java(一些调用示例)
(...)
public UserFunctions(){
JSONParser jsonParser = new JSONParser();
}
public JSONObject loginUser(String email, String password){
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", login_tag));
params.add(new BasicNameValuePair("email", email));
params.add(new BasicNameValuePair("password", password));
JSONObject json = jsonParser.getJson(params);
//JSONObject json = jsonParser.execute(params); //doesn't return
return json;
}
public JSONObject listProjects(String email){
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", list_projects));
params.add(new BasicNameValuePair("email", email));
JSONObject json = jsonParser.getJson(params);
return json;
}
public JSONObject setDisp(String dispID, String disp, String comment){
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", set_disp));
params.add(new BasicNameValuePair("dispID", dispID));
params.add(new BasicNameValuePair("disp", disp));
params.add(new BasicNameValuePair("comment", comment));
JSONObject json = jsonParser.getJson(params);
return json;
}
(...)
我试图将值传递给 var(JSONObject 结果),但没有效果。 (NullPointerException,我猜它会在异步完成之前尝试访问 var,因为,好吧,它是“异步的”)
我需要做什么来获取这些值?有什么想法吗?
非常感谢你们!
最佳答案
习惯使用AsyncTask
,你会非常需要它。
如果你需要在任务完成时触发一些东西,广播。每个感兴趣的人(包括其他 Activity )都需要为广播注册一个接收器。
你的AsyncTask
,
new AsyncTask<Void,Void,List<Result>>() {
@Override
public List<Result> doInBackground(Void... voids) {
final List<Result> results = ...; // get from network, or whatever
}
@Override
public void onPostExecute(List<Result> results) {
Intent intent = new Intent("com.my.action.RESULTS_READY"); // or whatever
intent.putExtra("com.my.extra.RESULTS", new ArrayList<Result>(results);
sendBroadcast(intent);
}
}.execute();
现在,在您的其他 Activity 中,在 onCreate()
和 onDestroy()
中为此注册/取消注册。我假设您想在暂停时接收广播并更新一些实例数据。
请注意还有其他选项。例如,您可以将结果写入数据库,然后只广播结果已准备就绪,并期望每个相关方在需要时从数据库中检索它们。这可能会更好,因为它不依赖于接收广播来获得有效数据(这也是一个更长的例子,所以我会把这个乐趣留给你)。
关于android - Asynctask + JSON(如何获取一些值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19012246/