我在网上找到了一个优秀的JSON解析器,我想在我的项目中使用它。会有很多JSON请求,所以我希望能够重用代码。这是JSON解析器:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
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();
}
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();
} 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;
}
}
在我的主要活动中,我需要一种方法来检索解析器返回的JSONObject。但是,它需要在后台线程中完成。
我无法弄清楚如何从Asynctask返回一个对象。我正在考虑将解析器类包装在Asynctask中,并在完成时将其返回,但这会带来同样的难题。
有人可以帮忙吗?
答案 0 :(得分:5)
您可以将已编写的课程改为AsyncTask
doInBackground()
方法返回JSONObject
。在AsyncTask
land中,从doInBackground()
返回的值(在后台线程上调用的方法)将传递给在主线程上调用的onPostExecute()
。您可以使用onPostExecute()
通知您的Activity
操作已完成,并通过您定义的自定义回调界面直接传递对象,或者仅通过Activity
调用AsyncTask.get()
当操作完成后,返回解析的JSON。因此,例如,我们可以使用以下内容扩展您的类:
public class JSONParser extends AsyncTask<String, Void, JSONObject> {
public interface MyCallbackInterface {
public void onRequestCompleted(JSONObject result);
}
private MyCallbackInterface mCallback;
public JSONParser(MyCallbackInterface callback) {
mCallback = callback;
}
public JSONObject getJSONFromUrl(String url) { /* Existing Method */ }
@Override
protected JSONObject doInBackground(String... params) {
String url = params[0];
return getJSONFromUrl(url);
}
@Override
protected onPostExecute(JSONObject result) {
//In here, call back to Activity or other listener that things are done
mCallback.onRequestCompleted(result);
}
}
从像这样的Activity中使用它:
public class MyActivity extends Activity implements MyCallbackInterface {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...existing code...
JSONParser parser = new JSONParser(this);
parser.execute("http://my.remote.url");
}
@Override
public void onRequestComplete(JSONObject result) {
//Hooray, here's my JSONObject for the Activity to use!
}
}
另外,作为旁注,您可以在解析方法中替换以下所有代码:
is = httpEntity.getContent();
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();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
有了这个:
json = EntityUtils.toString(httpEntity);
希望有帮助!
答案 1 :(得分:1)
检查AsyncTask文档,第3个泛型类型参数是Result,后台计算结果的类型。
private class MyTask extends AsyncTask<Void, Void, JSONObject> {
protected JSONObject doInBackground(Void... params) {
...
return json;
}
protected void onPostExecute(JSONObject result) {
// invoked on the UI thread
}
}
让您的任务成为活动的内部类,创建活动的成员private JSONObject mJSON = null;
并在onPostExecute()
中进行分配mJSON = result;