上面的API 11的AsyncTask使应用程序崩溃

时间:2013-08-18 20:07:35

标签: android android-asynctask

我正在使用AsyncTaskgson来解析Feed,一切正常。但在一个fragment中,我在API 11上面的设备上被迫关闭我的应用程序。在API 11以下的设备中可以正常使用。这是我的代码:

public class LatestSubmissions extends SherlockListFragment {

    SharedPreferences prefs;
    LatestSubmissionsAdapter adapter = null;
    ArrayList<HashMap<String, String>> submissions = new ArrayList<HashMap<String, String>>();
    private GetSubmissionsListTask submissionTask = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        ConnectionDetector cd = new ConnectionDetector(getSherlockActivity());
        if (cd.isConnectingToInternet()) {
            prefs = getSherlockActivity().getSharedPreferences(
                    CommonUtils.PREFERENCE_NAME, 0);
            submissionTask = new GetSubmissionsListTask();
            submissionTask.execute(CommonUtils.USER_SUBMISSION_URL
                    + prefs.getString(CommonUtils.KEY_USER_ID, "339") + "/10");
        } else {
            MainActivity.networkAvailabilityNotice(getSherlockActivity());
        }
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    protected class GetSubmissionsListTask extends
            AsyncTask<String, Void, InputStreamReader> {

        @Override
        protected InputStreamReader doInBackground(String... params) {
            return new JSONDownloader().getJSONStringFromUrl(params[0]);
        }

        @Override
        protected void onPostExecute(InputStreamReader isr) {
            if (isr != null) {
                MainActivity activity = (MainActivity) getSherlockActivity();
                JsonReader reader = new JsonReader(isr);
                try {
                    reader.beginObject();
                    reader.nextName(); // name
                    reader.skipValue();
                    reader.nextName(); // uname
                    reader.skipValue();
                    String subs = reader.nextName(); // subs
                    if (subs.equals(CommonUtils.KEY_SUBMISSION)) {
                        reader.beginArray();
                        while (reader.hasNext()) {
                            HashMap<String, String> map = new HashMap<String, String>();
                            reader.beginArray();
                            reader.skipValue(); // submission id
                            String txt = "Latest problem";
                            Problems obj = MainActivity.problems.get(reader
                                    .nextInt());
                            if (obj != null) {
                                txt = obj.getProblemsInfo();
                            }
                            map.put(CommonUtils.KEY_PROBLEM_ID, txt);
                            Verdict verdict = activity.verdicts.get(reader
                                    .nextString()); // verdict id
                            map.put(CommonUtils.KEY_VERDICT_COLOR,
                                    verdict.verdictColorHex);
                            map.put(CommonUtils.KEY_VERDICT_ID, verdict.name);
                            Double execTime = reader.nextDouble() / 1000; // execution
                                                                            // time
                            map.put(CommonUtils.KEY_RUNTIME,
                                    execTime.toString() + "s");
                            reader.skipValue(); // submission time
                            map.put(CommonUtils.KEY_LANGUAGE_ID,
                                    activity.languageCode.get(reader
                                            .nextString())); // lanugage
                                                                // id
                            map.put(CommonUtils.KEY_SUBMISSION_RANK,
                                    reader.nextString()); // rank
                            submissions.add(map);
                            reader.endArray();
                        }
                        reader.endArray();
                    }
                    reader.endObject();
                    reader.close();
                } catch (IOException e) {
                    if (CommonUtils.isDebuggable) {
                        Log.e("GSON Parser",
                                "Error parsing data " + e.toString());
                    }
                }
                Collections.reverse(submissions);
                adapter = new LatestSubmissionsAdapter(getSherlockActivity(),
                        submissions);
                setListAdapter(adapter);
            }
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (submissionTask != null
                && submissionTask.getStatus() != AsyncTask.Status.FINISHED) {
            submissionTask.cancel(true);
        }
    }
}

我已经在几个具有不同API级别的设备和模拟器中进行了测试,并且它总是在我的两个带有ICS和Jellybean的设备中被迫关闭。 这是我的日志猫:

08-19 01:57:16.961: E/AndroidRuntime(710): FATAL EXCEPTION: main
08-19 01:57:16.961: E/AndroidRuntime(710): android.os.NetworkOnMainThreadException
08-19 01:57:16.961: E/AndroidRuntime(710):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
08-19 01:57:16.961: E/AndroidRuntime(710):  at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
08-19 01:57:16.961: E/AndroidRuntime(710):  at libcore.io.IoBridge.recvfrom(IoBridge.java:503)
08-19 01:57:16.961: E/AndroidRuntime(710):  at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
08-19 01:57:16.961: E/AndroidRuntime(710):  at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
08-19 01:57:16.961: E/AndroidRuntime(710):  at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
08-19 01:57:16.961: E/AndroidRuntime(710):  at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
08-19 01:57:16.961: E/AndroidRuntime(710):  at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
08-19 01:57:16.961: E/AndroidRuntime(710):  at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:174)
08-19 01:57:16.961: E/AndroidRuntime(710):  at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
08-19 01:57:16.961: E/AndroidRuntime(710):  at java.io.InputStreamReader.read(InputStreamReader.java:244)
08-19 01:57:16.961: E/AndroidRuntime(710):  at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1263)
08-19 01:57:16.961: E/AndroidRuntime(710):  at com.google.gson.stream.JsonReader.nextQuotedValue(JsonReader.java:1005)
08-19 01:57:16.961: E/AndroidRuntime(710):  at com.google.gson.stream.JsonReader.nextString(JsonReader.java:811)
08-19 01:57:16.961: E/AndroidRuntime(710):  at me.kaidul.uhunt.RankList$GetRankListTask.onPostExecute(RankList.java:85)
08-19 01:57:16.961: E/AndroidRuntime(710):  at me.kaidul.uhunt.RankList$GetRankListTask.onPostExecute(RankList.java:1)
08-19 01:57:16.961: E/AndroidRuntime(710):  at android.os.AsyncTask.finish(AsyncTask.java:602)
08-19 01:57:16.961: E/AndroidRuntime(710):  at android.os.AsyncTask.access$600(AsyncTask.java:156)
08-19 01:57:16.961: E/AndroidRuntime(710):  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
08-19 01:57:16.961: E/AndroidRuntime(710):  at android.os.Handler.dispatchMessage(Handler.java:99)
08-19 01:57:16.961: E/AndroidRuntime(710):  at android.os.Looper.loop(Looper.java:137)
08-19 01:57:16.961: E/AndroidRuntime(710):  at android.app.ActivityThread.main(ActivityThread.java:4424)
08-19 01:57:16.961: E/AndroidRuntime(710):  at java.lang.reflect.Method.invokeNative(Native Method)
08-19 01:57:16.961: E/AndroidRuntime(710):  at java.lang.reflect.Method.invoke(Method.java:511)
08-19 01:57:16.961: E/AndroidRuntime(710):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-19 01:57:16.961: E/AndroidRuntime(710):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-19 01:57:16.961: E/AndroidRuntime(710):  at dalvik.system.NativeStart.main(Native Method)

我无法弄清楚这是怎么回事。我在其他片段中使用了几乎相同的类型代码并且运行良好。只有两个片段包含这个问题。

2 个答案:

答案 0 :(得分:4)

您需要在doInBackground中完整读取输入流。您现在正在做的就是在doInBackground中打开连接并获取结果的阅读器。但是,您正试图在onPostExecute中实际读取网络中正在主线程上执行的数据。

protected class GetSubmissionsListTask extends
        AsyncTask<String, Void, ArrayList<HashMap<String, String>>> {

    @Override
    protected ArrayList<HashMap<String, String>> doInBackground(String... params) {
        InputStreamReader isr = new JSONDownloader().getJSONStringFromUrl(params[0]);
        ArrayList<HashMap<String, String>> result = null;
        if (isr != null) {
            result = new ArrayList<HashMap<String, String>>();
            MainActivity activity = (MainActivity) getSherlockActivity();
            JsonReader reader = new JsonReader(isr);
            try {
                reader.beginObject();
                reader.nextName(); // name
                reader.skipValue();
                reader.nextName(); // uname
                reader.skipValue();
                String subs = reader.nextName(); // subs
                if (subs.equals(CommonUtils.KEY_SUBMISSION)) {
                    reader.beginArray();
                    while (reader.hasNext()) {
                        HashMap<String, String> map = new HashMap<String, String>();
                        reader.beginArray();
                        reader.skipValue(); // submission id
                        String txt = "Latest problem";
                        Problems obj = MainActivity.problems.get(reader
                                .nextInt());
                        if (obj != null) {
                            txt = obj.getProblemsInfo();
                        }
                        map.put(CommonUtils.KEY_PROBLEM_ID, txt);
                        Verdict verdict = activity.verdicts.get(reader
                                .nextString()); // verdict id
                        map.put(CommonUtils.KEY_VERDICT_COLOR,
                                verdict.verdictColorHex);
                        map.put(CommonUtils.KEY_VERDICT_ID, verdict.name);
                        Double execTime = reader.nextDouble() / 1000; // execution
                                                                        // time
                        map.put(CommonUtils.KEY_RUNTIME,
                                execTime.toString() + "s");
                        reader.skipValue(); // submission time
                        map.put(CommonUtils.KEY_LANGUAGE_ID,
                                activity.languageCode.get(reader
                                        .nextString())); // lanugage
                                                            // id
                        map.put(CommonUtils.KEY_SUBMISSION_RANK,
                                reader.nextString()); // rank
                        result.add(map);
                        reader.endArray();
                    }
                    reader.endArray();
                }
                reader.endObject();
            } catch (IOException e) {
                if (CommonUtils.isDebuggable) {
                    Log.e("GSON Parser",
                            "Error parsing data " + e.toString());
                }
                result = null;
            } finally {
                reader.close(); // always need to close, even after an exception
            }
        }
        if (result != null) Collections.reverse(result);
        return result;
    }

    @Override
    protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
        if (result != null) {
            submissions = result; // do you still need this?
            adapter = new LatestSubmissionsAdapter(getSherlockActivity(),
                    result);
            setListAdapter(adapter);
        }
    }
}

答案 1 :(得分:1)

您应该在后台线程(doInBackground)中同时执行JSON读取和数据处理。实例化流不会将整个流读入存储器,调用从流读取的读取方法,从而在UI线程上执行网络活动,这在&gt;上是非法的。 API级别11。