【问题标题】:Issues with JSONObject in AsyncTaskAsyncTask 中 JSONObject 的问题
【发布时间】:2014-06-25 18:09:19
【问题描述】:

我似乎无法解决我遇到的这个问题。在我的 MainActivity 中,我将设备的应用程序数据库与我的后端数据库同步在几个 Asynctasks 中,每个表一个。由于我有很多不同的表,因此我在 AsyncTask 上进行了一般设置,并传入一个参数来确定要同步的表,如下所示:

protected void onResume() {
    if(isOnline()){
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ FORENINGAR });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ INFO });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ KALENDER });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ KAMPEN });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ KARTA });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ KONTAKT });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ MEDDELANDEN });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ OVRIGINFO });
        new loadFromBackendAndPlaceInDB().execute(new Integer[]{ SANGBOK });
    }
}

实际的 AsyncTask 如下所示:

class loadFromBackendAndPlaceInDB extends AsyncTask<Integer, String, String> {

    protected String doInBackground(Integer... params) {

        int activity = params[0];
        String url = urlList.get(activity);
        String json = null;

        try {
            URL urlObject = new URL(url);
            HttpURLConnection con = (HttpURLConnection) urlObject.openConnection();
            con.setConnectTimeout(15000);
            con.setReadTimeout(15000);
            json = readStream(con.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(json != null){
            JSONObject jObj = null;
            try {
                // THIS IS WHERE I'M STARTING GETTING A PROBLEM
                // LINE 536
                jObj = new JSONObject(json);
            } catch (JSONException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            try {

                // THIS IS WHERE THE RUNTIME ERROR OCCURS BECAUSE OF THE PROBLEM AT ROW 536
                // LINE 546 
                int success = jObj.getInt(TAG_SUCCESS);

                if (success == 1) {
                    JSONArray jsonArray = null;
                    jsonArray = jObj.getJSONArray(getActivityTag(activity));

                    getContentResolver().delete(getContentUri(activity), null, null);
                    for (int i = 0; i < jsonArray.length(); i++) {

                        JSONObject c = jsonArray.getJSONObject(i);

                        ContentValues values = new ContentValues();
                        for(int k = 0; k < getColumns(activity).size(); k++){
                            String TAG = getTags(activity).get(k);
                            String VALUE = c.getString(TAG);
                            String COLUMN = getColumns(activity).get(k);

                            values.put(COLUMN, VALUE);
                        }

                        getContentResolver().insert(getContentUri(activity), values);
                    }
                } else {
                    Log.d("No Success", getActivityTag(activity));
                }


            } catch (JSONException e) {
                e.printStackTrace();
            }

        }else{

        }

        return null;
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
    }

}

以及 AsyncTask 中使用的方法 readStream:

private String readStream(InputStream in) {
    BufferedReader reader = null;
    StringBuilder sb = null;
    String json = "";
    try {
        reader = new BufferedReader(new InputStreamReader(in));
        sb = new StringBuilder();
        String line = "";
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try {
                reader.close();
                in.close();
                json = sb.toString();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return json;
}

这是我的 LogCat:

06-25 18:43:18.089: W/System.err(3942): org.json.JSONException: End of input at character 0 of 
06-25 18:43:18.113: W/System.err(3942):     at org.json.JSONTokener.syntaxError(JSONTokener.java:446)
06-25 18:43:18.113: W/System.err(3942):     at org.json.JSONTokener.nextValue(JSONTokener.java:93)
06-25 18:43:18.113: W/System.err(3942):     at org.json.JSONObject.<init>(JSONObject.java:154)
06-25 18:43:18.113: W/System.err(3942):     at org.json.JSONObject.<init>(JSONObject.java:171)
06-25 18:43:18.113: W/System.err(3942):     at se.nollekollen.main.MainActivity$loadFromBackendAndPlaceInDB.doInBackground(MainActivity.java:536)
06-25 18:43:18.113: W/System.err(3942):     at se.nollekollen.main.MainActivity$loadFromBackendAndPlaceInDB.doInBackground(MainActivity.java:1)
06-25 18:43:18.113: W/System.err(3942):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
06-25 18:43:18.113: W/System.err(3942):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
06-25 18:43:18.117: W/System.err(3942):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
06-25 18:43:18.117: W/System.err(3942):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
06-25 18:43:18.117: W/System.err(3942):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
06-25 18:43:18.117: W/System.err(3942):     at java.lang.Thread.run(Thread.java:1019)
06-25 18:43:18.121: W/dalvikvm(3942): threadid=13: thread exiting with uncaught exception (group=0x40015578)
06-25 18:43:18.125: E/AndroidRuntime(3942): FATAL EXCEPTION: AsyncTask #5
06-25 18:43:18.125: E/AndroidRuntime(3942): java.lang.RuntimeException: An error occured while executing doInBackground()
06-25 18:43:18.125: E/AndroidRuntime(3942):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.lang.Thread.run(Thread.java:1019)
06-25 18:43:18.125: E/AndroidRuntime(3942): Caused by: java.lang.NullPointerException
06-25 18:43:18.125: E/AndroidRuntime(3942):     at se.nollekollen.main.MainActivity$loadFromBackendAndPlaceInDB.doInBackground(MainActivity.java:546)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at se.nollekollen.main.MainActivity$loadFromBackendAndPlaceInDB.doInBackground(MainActivity.java:1)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
06-25 18:43:18.125: E/AndroidRuntime(3942):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
06-25 18:43:18.125: E/AndroidRuntime(3942):     ... 4 more

问题似乎从第 536 行开始,然后导致第 546 行的最终运行时错误。

该错误只是有时会发生,有时会很好。当我快速输入和输入 MainActivity 时,它似乎会发生 - 当我在整个应用程序中导航得更慢时,它通常很好。

发生了什么,为什么会出现此错误以及解决方案是什么?感谢所有答案!

【问题讨论】:

    标签: android android-asynctask android-json


    【解决方案1】:

    我遇到了多个 AsyncTask 相互损坏的问题(尽管我在您的代码中没有看到任何明显的错误)。

    我通常的解决方案是在 IntentService 中进行这样的操作,并通过广播意图将更新传达给 Activity。

    这意味着我在 Activity 中保留了一个 BroadcastReceiver 来捕捉意图并更新 UI。

    祝你好运。

    【讨论】:

      【解决方案2】:

      而不是触发多个 AsyncTask 为什么不只是将具有所有值的单个整数数组作为参数发送给一个,并且在 AsyncTask 内部只需实现 for 循环以逐个遍历整数数组条目。

      【讨论】:

      • 当您从 Activity 的 onResume 方法启动调用时,当您导航进/出 mainactivity 时,将导致 AsyncTask 组的多次调用初始化,从而导致数据库锁定或其他导致到未处理的运行时错误。当您缓慢浏览整个应用程序时,您的 asynctasks 有足够的执行时间和更新数据库。所以我建议,当数据库更新开始时,放置一个进度对话框来禁用任何用户交互。
      猜你喜欢
      • 2021-09-14
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      相关资源
      最近更新 更多