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

时间:2015-01-04 11:25:28

标签: android mysql json android-listview android-asynctask

也许之前已经回答过,但我找不到任何相同的解决方案,但建议。我正在构建一个应用程序,其中我通过JSON从ListViews数据库填充4 Mysql。这项工作正在以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();
        }
    }

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

2 个答案:

答案 0 :(得分:1)

在这个方法中,你是UI线程

中的实际操作
 @Override
    protected void onPostExecute(String result) {
        ListDrawer();
        pDialog.dismiss();
    }

您调用ListDrawer();方法,它将执行CPU密集型任务,解析JSON。 它在该方法中抛出异常并在catch块中调用此getActivity().finish();。这就是你回到以前的活动的原因。 尝试在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);
}

答案 1 :(得分:1)

您正在访问该字段:

private String jsonResult;

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

JSONObject jsonResponse = new JSONObject(jsonResult);

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

解决方案是在异步任务的 doInBackground()方法中执行响应解析并从中返回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> {
    ...
}