android - Asynctask + JSON(如何获取一些值)

标签 android json android-asynctask


我正在使用 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/

相关文章:

java - 如何在一个类中执行多个AsyncTask

java - 为什么我的ArrayList在AsyncTask Android Studio中突然丢失所有数据

php - 将 android JSONObject 发布到 PHP 的问题

android - Android 和 Vuforia 的相机方向错误

c# - .NET core 3 : Order of serialization for JsonPropertyName (System. 文本.Json.序列化)

java - jackson .databind.JsonMappingException : getWriter() has already been called

java - Android:如何从蓝牙设备控制音乐服务播放/暂停?

Android Twitter 对我公司时间表的 Intent

c# - 基于 .Net 中的字段反序列化 json (C#)

java - Android:如何在另一个包的 Activity 中显示异步任务的进度对话框?