应用程序崩溃,因为它可能在其主线程上做了太多工作

The application crashes because it may be doing too much work on its main Thread

也许之前有人回答过这个问题,但除了提案之外我找不到任何相同的解决方案。我正在构建一个应用程序,其中我通过 JSON 从 Mysql 数据库填充 4 ListViews。这项工作正在 4 个片段中完成。问题是,当我从数据库填充 2 个列表,另外 2 个仅使用一些字符串数组数据时,一切正常,但是当我尝试同时填充所有 4 个列表时,它会崩溃。

错误:

01-04 11:27:25.405    3002-3017/com.order.app.order W/EGL_genymotion﹕ eglSurfaceAttrib not implemented
01-04 11:27:25.405    3002-3017/com.order.app.order W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa31ff7a0, error=EGL_SUCCESS
01-04 11:27:30.619    3002-3002/com.order.app.order I/Choreographer﹕ Skipped 307 frames!  The application may be doing too much work on its main thread.

我的片段:

private View rootView;
    private ListView lv;
    private ArrayAdapter<ProductList> adapter;
    private String jsonResult;
    private String url = "http://reservations.cretantaxiservices.gr/files/getkafedes.php";
    ProgressDialog pDialog;
    List<ProductList> customList;
    private TextView tv1, tv2;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.activity_coffees_fragment, container, false);
        lv = (ListView)rootView.findViewById(R.id.coffeesListView);
        final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.activity_main_swipe_refresh_layout);
        ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(getActivity().getApplicationContext().CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean network_connected = activeNetwork != null && activeNetwork.isAvailable() && activeNetwork.isConnectedOrConnecting();

        if (!network_connected) {
            onDetectNetworkState().show();
        } else {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                accessWebService();
                registerCallClickBack();
                mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                    @Override
                    public void onRefresh() {
                        accessWebService();
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                });
            }
        }
        return rootView;
    }

    private AlertDialog onDetectNetworkState() {
        AlertDialog.Builder builder1 = new AlertDialog.Builder(getActivity().getApplicationContext());
        builder1.setMessage(R.string.wifi_off_message)
                .setTitle(R.string.wifi_off_title)
                .setNegativeButton(R.string.cancel,
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                getActivity().finish();
                            }
                        })
                .setPositiveButton(R.string.action_settings,
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                startActivityForResult((new Intent(
                                        Settings.ACTION_WIFI_SETTINGS)), 1);
                                getActivity().finish();
                            }
                        });
        return builder1.create();
    }



    private void registerCallClickBack() {
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getActivity().getApplicationContext(), "You have chosen " + customList.get(position).getName(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            if (pDialog.isShowing()) {
                pDialog.show();
            } else {
                pDialog.dismiss();
            }
            if (onDetectNetworkState().isShowing()
                    && onDetectNetworkState() != null) {
                onDetectNetworkState().show();
            } else {
                onDetectNetworkState().dismiss();
            }
        }
        if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {

            if (pDialog.isShowing()) {
                pDialog.show();
            } else {
                pDialog.dismiss();
            }
            if (onDetectNetworkState().isShowing()) {
                onDetectNetworkState().show();
            } else {
                onDetectNetworkState().dismiss();
            }
        }
    }
    public class JsonReadTask extends AsyncTask<String, Void, String> {
        public JsonReadTask() {
            super();
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(getActivity());
            pDialog.setTitle(R.string.waiting);
            pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            pDialog.setMessage(getString(R.string.get_stocks));
            pDialog.setIndeterminate(true);
            pDialog.setCancelable(false);
            pDialog.setInverseBackgroundForced(true);
            pDialog.show();
        }

        @Override
        protected String doInBackground(String... params) {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(params[0]);
            try {
                HttpResponse response = httpclient.execute(httppost);
                jsonResult = inputStreamToString(
                        response.getEntity().getContent()).toString();
            } catch (Exception e) {
                getActivity().finish();
            }
            return null;
        }

        private StringBuilder inputStreamToString(InputStream is) {
            String rLine = "";
            StringBuilder answer = new StringBuilder();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            try {
                while ((rLine = rd.readLine()) != null) {
                    answer.append(rLine);
                }
            } catch (Exception e) {
                getActivity().finish();
            }
            return answer;
        }

        @Override
        protected void onPostExecute(String result) {
            ListDrawer();
            pDialog.dismiss();
        }
    }// end async task

    public void accessWebService() {
        JsonReadTask task = new JsonReadTask();
        task.execute(new String[]{url});
    }

    public void ListDrawer() {
        customList = new ArrayList<ProductList>();
        try {
            JSONObject jsonResponse = new JSONObject(jsonResult);
            JSONArray jsonMainNode = jsonResponse.optJSONArray("kafedes");
            for (int i = 0; i < jsonMainNode.length(); i++) {
                JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
                String name = jsonChildNode.optString("name");
                String price = jsonChildNode.optString("price");
                String image = jsonChildNode.optString("image");
                customList.add(new ProductList(image, name, price));

            }
        } catch (Exception e) {
            getActivity().finish();
        }

        adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
        adapter.notifyDataSetChanged();
        lv.setAdapter(adapter);
    }

事实上,我正在使用 4 AsyncTasks 来完成这项工作。有什么想法吗???

编辑:

我更新了代码,因为我在网上找到了一些东西,但仍然是同样的错误

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if(customList == null){
            accessWebService();
        }else{
            ListDrawer();
        }
    }

任何帮助将不胜感激!!!

在此方法中,您实际上处于 UI 线程中

 @Override
    protected void onPostExecute(String result) {
        ListDrawer();
        pDialog.dismiss();
    }

并且您调用 ListDrawer(); 方法,它将执行 CPU 密集型任务,解析 JSON。 它在该方法中抛出异常并在 catch 块中调用此 getActivity().finish();。这就是为什么你回到以前的 activity。 尝试在 AsynckTask 中解析你的 JSON,它肯定能解决你的问题。

更新:

private View rootView;
private ListView lv;
private ArrayAdapter<ProductList> adapter;
private String jsonResult;
private String url = "http://reservations.cretantaxiservices.gr/files/getkafedes.php";
ProgressDialog pDialog;
List<ProductList> customList;
private TextView tv1, tv2;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.activity_coffees_fragment, container, false);
    lv = (ListView)rootView.findViewById(R.id.coffeesListView);
    final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.activity_main_swipe_refresh_layout);
    ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(getActivity().getApplicationContext().CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean network_connected = activeNetwork != null && activeNetwork.isAvailable() && activeNetwork.isConnectedOrConnecting();

    if (!network_connected) {
        onDetectNetworkState().show();
    } else {
        if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
            accessWebService();
            registerCallClickBack();
            mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    accessWebService();
                    mSwipeRefreshLayout.setRefreshing(false);
                }
            });
        }
    }
    return rootView;
}

private AlertDialog onDetectNetworkState() {
    AlertDialog.Builder builder1 = new AlertDialog.Builder(getActivity().getApplicationContext());
    builder1.setMessage(R.string.wifi_off_message)
            .setTitle(R.string.wifi_off_title)
            .setNegativeButton(R.string.cancel,
                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog,
                                            int which) {
                            getActivity().finish();
                        }
                    })
            .setPositiveButton(R.string.action_settings,
                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog,
                                            int which) {
                            startActivityForResult((new Intent(
                                    Settings.ACTION_WIFI_SETTINGS)), 1);
                            getActivity().finish();
                        }
                    });
    return builder1.create();
}



private void registerCallClickBack() {
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Toast.makeText(getActivity().getApplicationContext(), "You have chosen " + customList.get(position).getName(), Toast.LENGTH_SHORT).show();
        }
    });
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        if (pDialog.isShowing()) {
            pDialog.show();
        } else {
            pDialog.dismiss();
        }
        if (onDetectNetworkState().isShowing()
                && onDetectNetworkState() != null) {
            onDetectNetworkState().show();
        } else {
            onDetectNetworkState().dismiss();
        }
    }
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {

        if (pDialog.isShowing()) {
            pDialog.show();
        } else {
            pDialog.dismiss();
        }
        if (onDetectNetworkState().isShowing()) {
            onDetectNetworkState().show();
        } else {
            onDetectNetworkState().dismiss();
        }
    }
}
public class JsonReadTask extends AsyncTask<String , Void, List<ProductList>> {
    public JsonReadTask() {
        super();
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(getActivity());
        pDialog.setTitle(R.string.waiting);
        pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pDialog.setMessage(getString(R.string.get_stocks));
        pDialog.setIndeterminate(true);
        pDialog.setCancelable(false);
        pDialog.setInverseBackgroundForced(true);
        pDialog.show();
    }

    @Override
    protected List<ProductList> doInBackground(String... params) {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(params[0]);
        try {
            HttpResponse response = httpclient.execute(httppost);
            jsonResult = inputStreamToString(
                    response.getEntity().getContent()).toString();
            customList = new ArrayList<ProductList>();

            JSONObject jsonResponse = new JSONObject(jsonResult);
            JSONArray jsonMainNode = jsonResponse.optJSONArray("kafedes");
            for (int i = 0; i < jsonMainNode.length(); i++) {
                JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
                String name = jsonChildNode.optString("name");
                String price = jsonChildNode.optString("price");
                String image = jsonChildNode.optString("image");
                customList.add(new ProductList(image, name, price));

            }
            return customList;
        } catch (Exception e) {
            e.printStackTrace();
            getActivity().finish();
        }
        return null;
    }

    private StringBuilder inputStreamToString(InputStream is) {
        String rLine = "";
        StringBuilder answer = new StringBuilder();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        try {
            while ((rLine = rd.readLine()) != null) {
                answer.append(rLine);
            }
        } catch (Exception e) {
            getActivity().finish();
        }
        return answer;
    }

    @Override
    protected void onPostExecute(List<ProductList> customList) {
        if(customList == null){
            Log.d("ERORR", "No result to show.");
            return;
        }
        ListDrawer(customList);
        pDialog.dismiss();
    }
}// end async task

public void accessWebService() {
    JsonReadTask task = new JsonReadTask();
    task.execute(new String[]{url});
}

public void ListDrawer(List<ProductList> customList) {

    adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
    adapter.notifyDataSetChanged();
    lv.setAdapter(adapter);
}

您正在访问的字段:

private String jsonResult;

来自后台线程(在您的 AsyncTasks 的 doInBackground 方法中)和 ListDrawer() 方法中的 UI 线程在行中:

JSONObject jsonResponse = new JSONObject(jsonResult);

导致崩溃的最可能原因是 UI 线程没有看到 jsonResult 值已设置(因为该字段不是易变的)并且创建新的 JSONObject 会引发异常。

解决方案是在异步任务的 doInBackground() 方法中执行响应解析,并从中解析 return ArrayList(编辑:修复了编译错误)

@Override
protected ArrayList<ProductList> doInBackground(String... params) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(params[0]);
    try {
        HttpResponse response = httpclient.execute(httppost);

        String jsonResult = inputStreamToString(response.getEntity().getContent()).toString();

        ArrayList<ProductList> customList = new ArrayList<ProductList>();

        JSONObject jsonResponse = new JSONObject(jsonResult);
        JSONArray jsonMainNode = jsonResponse.optJSONArray("kafedes");
        for (int i = 0; i < jsonMainNode.length(); i++) {
            JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
            String name = jsonChildNode.optString("name");
            String price = jsonChildNode.optString("price");
            String image = jsonChildNode.optString("image");
            customList.add(new ProductList(image, name, price));
        }

        return customList;
    } catch (Exception e) {
        return null;
    }
}

onPostExecute()方法应该修改:

@Override
protected void onPostExecute(ArrayList<ProductList> result) {
    pDialog.dismiss();

    if(result == null) {
        getActivity().finish();
    } else {
        adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
        adapter.notifyDataSetChanged();
        lv.setAdapter(adapter);
    }
}

最后必须更改 AsyncTask 的签名:

public class JsonReadTask extends AsyncTask<ArrayList<ProductList>, Void, String> {
    ...
}