0

我在 stackOverflow 中发现了一些与该主题相关的问题,但无法找到合适的答案。在我的应用程序中,我打算通过单独的线程进行网络通信。所以我使用了 asynctask。但即使在使用 asynctask 之后,我也发现了 networkOnMainThreadException。这里是我的代码:

private static final String CATEGORY_ALL_FETCHING_URL = "http://qpon.es/coupon/index.php/welcome/categories/all";
private static final String CATEGORY_IMAGE_URL = "http://qpon.es/images/coupons/";
private static final String TAG_CATEGORY_ID = "id";
private static final String TAG_CATEGORY_NAME = "name";
private static final String TAG_CATEGORY_IMAGE = "img";
private static final String TAG_CATEGORY_CREATE_DATE = "created";
private static final String CATEGORY_INTENT = "category";

private ProgressDialog downloadingStatusIndicator = null;
private ArrayList<Category> categoryList = null;
private CustomCategoryAdapter customAdapter = null;

private class CateoryListDataGenerator extends
        AsyncTask<String, Void, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        downloadingStatusIndicator = new ProgressDialog(getActivity());
        downloadingStatusIndicator.setTitle(R.string.categoryDownloadTitle);
        downloadingStatusIndicator.setMessage("Retrieving Categories...");
        downloadingStatusIndicator.show();

    }

    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub
        String response = "";
        try {

            Log.d("BACK THREAD STARTS", "YES");
            categoryList = new ArrayList<Category>();
            response = JSONParser
                    .getRemoteResponse(CATEGORY_ALL_FETCHING_URL);

            // Thread.sleep(2000);
        } catch (Exception e) {

            Log.d("BACKGROUD", e.getMessage());
        }

        return response;
    }

    @Override
    protected void onPostExecute(String response) {

        JSONArray categoriesJSON = null;
        try {
            categoriesJSON = new JSONArray(response);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        for (int i = 0; i < categoriesJSON.length(); i++) {

            Log.d("LOOP BEGINS", "YES");
            Category eachCategory = new Category();

            JSONObject eachCategoryJSON = null;
            try {
                eachCategoryJSON = categoriesJSON.getJSONObject(i);
                eachCategory.setCategoryName(eachCategoryJSON
                        .getString(TAG_CATEGORY_NAME));
                eachCategory.setCategoryCreateDate(eachCategoryJSON
                        .getString(TAG_CATEGORY_CREATE_DATE));
                eachCategory.setCategoryImagePath(CATEGORY_IMAGE_URL
                        + eachCategoryJSON.getString(TAG_CATEGORY_IMAGE));
                eachCategory.setCategoryID(eachCategoryJSON
                        .getInt(TAG_CATEGORY_ID));
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            categoryList.add(eachCategory);
            Log.d("CATEGORY INSERTED", categoryList.toString());
        }

        Log.d("CATEGORY LIST", categoryList.toString());

        if (categoryList != null || categoryList.size() > 0) {
            customAdapter.notifyDataSetChanged();

            for (int i = 0; i < categoryList.size(); i++) {
                customAdapter.add(categoryList.get(i));

            }

            downloadingStatusIndicator.dismiss();
            customAdapter.notifyDataSetChanged();
        }

        Toast.makeText(getActivity(), response, Toast.LENGTH_SHORT).show();

    }

}

在 JSONParder 的 setRemoteRenponse() 方法中:

boolean isURLFetched = false;

    while(!isURLFetched){

        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse execute = client.execute(httpGet);
            content = execute.getEntity().getContent();
            isURLFetched = true;

        } catch (UnsupportedEncodingException e) {

            Log.d("HERE", "ONE");
            e.printStackTrace();
        } catch (ClientProtocolException e) {

            Log.d("HERE", "TWO");
            e.printStackTrace();
        } catch (IOException e) {

            Log.d("HERE", "THREE");
            e.printStackTrace();
        }
    }

    try {

        BufferedReader buffer = new BufferedReader(new InputStreamReader(
                content));
        String s = "";
        while ((s = buffer.readLine()) != null) {
            response += s;
        }

    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    return response;

最后在片段的 onActivityCreated() 方法中创建和执行 asynctask 类对象:

CateoryListDataGenerator dataGenerator = new CateoryListDataGenerator();
dataGenerator.execute(new String[] { CATEGORY_ALL_FETCHING_URL });     

我在这里做错了吗?我也包含了 INTERNET 权限。目前,我已经更改了线程策略以在 android 3.0 或更高版本上运行此应用程序,但这不是解决方案。

这是 logcat 消息:

05-24 17:11:36.025: E/AndroidRuntime(708): FATAL EXCEPTION: main
05-24 17:11:36.025: E/AndroidRuntime(708): android.os.NetworkOnMainThreadException
05-24 17:11:36.025: E/AndroidRuntime(708):  at     android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
05-24 17:11:36.025: E/AndroidRuntime(708):  at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
05-24 17:11:36.025: E/AndroidRuntime(708):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
05-24 17:11:36.025: E/AndroidRuntime(708):  at java.net.InetAddress.getAllByName(InetAddress.java:214)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:341)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpEngine.connect(HttpEngine.java:310)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
05-24 17:11:36.025: E/AndroidRuntime(708):  at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
05-24 17:11:36.025: E/AndroidRuntime(708):  at com.example.couponapp.adapters.CustomCategoryAdapter.getScaledBitmapFromFile(CustomCategoryAdapter.java:83)
05-24 17:11:36.025: E/AndroidRuntime(708):  at com.example.couponapp.adapters.CustomCategoryAdapter.getView(CustomCategoryAdapter.java:58)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.AbsListView.obtainView(AbsListView.java:2267)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.ListView.makeAndAddView(ListView.java:1769)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.ListView.fillDown(ListView.java:672)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.ListView.fillFromTop(ListView.java:733)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.ListView.layoutChildren(ListView.java:1608)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.AbsListView.onLayout(AbsListView.java:2102)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.View.layout(View.java:13754)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewGroup.layout(ViewGroup.java:4362)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.RelativeLayout.onLayout(RelativeLayout.java:948)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.View.layout(View.java:13754)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewGroup.layout(ViewGroup.java:4362)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.View.layout(View.java:13754)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewGroup.layout(ViewGroup.java:4362)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.View.layout(View.java:13754)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewGroup.layout(ViewGroup.java:4362)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.View.layout(View.java:13754)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewGroup.layout(ViewGroup.java:4362)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.View.layout(View.java:13754)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewGroup.layout(ViewGroup.java:4362)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1866)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1687)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.Choreographer.doCallbacks(Choreographer.java:555)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.Choreographer.doFrame(Choreographer.java:525)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.os.Handler.handleCallback(Handler.java:615)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.os.Handler.dispatchMessage(Handler.java:92)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.os.Looper.loop(Looper.java:137)
05-24 17:11:36.025: E/AndroidRuntime(708):  at android.app.ActivityThread.main(ActivityThread.java:4745)
05-24 17:11:36.025: E/AndroidRuntime(708):  at java.lang.reflect.Method.invokeNative(Native Method)
05-24 17:11:36.025: E/AndroidRuntime(708):  at java.lang.reflect.Method.invoke(Method.java:511)
05-24 17:11:36.025: E/AndroidRuntime(708):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
05-24 17:11:36.025: E/AndroidRuntime(708):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
05-24 17:11:36.025: E/AndroidRuntime(708):  at dalvik.system.NativeStart.main(Native Method)
4

3 回答 3

3

看起来问题不在这里。从日志中,从适配器内部,

05-24 17:11:36.025: E/AndroidRuntime(708): 在 libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
05-24 17:11:36.025: E/AndroidRuntime(708): 在 com.example.couponapp.adapters.CustomCategoryAdapter.getScaledBitmapFromFile(CustomCategoryAdapter.java:83)
05-24 17:11:36.025: E/AndroidRuntime(708): at com.example.couponapp.adapters.CustomCategoryAdapter.getView(CustomCategoryAdapter.java:58)
05-24 17:11:36.025: E/AndroidRuntime(708): 在 android.widget.AbsListView.obtainView(AbsListView.java:2267)

您可以看到 getView() 方法正在尝试加载图像,这反过来又发出网络请求以从某个地方获取图像。

检查你在这里做什么。

com.example.couponapp.adapters.CustomCategoryAdapter.getScaledBitmapFromFile(CustomCategoryAdapter.java:83)
05-24 17:11:36.025: E/AndroidRuntime(708): at com.example.couponapp.adapters.CustomCategoryAdapter.getView(CustomCategoryAdapter.java:58)

在 getScaledBitmapFromFile 方法中,我怀疑您正在进行网络调用,该调用位于 UIThread 上。

于 2013-05-24T11:24:39.627 回答
2

请将 onPostExecute 中的代码放回 doInBackground,并在 onPostExecute 中返回您想要放入适配器的结果。

您的问题必须是 JSONArray,请参阅文档...它不是线程安全的;)。

于 2013-05-24T11:25:06.713 回答
0

如果答案是 Luserdroid 不清楚,那么:你应该把你的处理代码放在里面doInBackground,我犯了一个错误,把处理代码放在里面onPostExecute,由主线程执行,因此我遇到了同样的问题。

于 2017-06-25T11:49:51.403 回答