5

我有一个应用程序对 MySQL 数据库进行了多次调用;它在AsyncTask. 下面是一个可能看起来像的示例。

我的主要问题是这个;有时,主机(Godaddy,呃)决定停止连接和我的progressDialog加载,加载,加载更多,直到强制关闭并且应用程序崩溃。特别是如果用户试图打断它(但是我已经设置为不可取消)。

有没有比我下面更好的方法来处理这个问题?我在try/中这样做catch,但不知道如何利用它来发挥我的优势。

class Task extends AsyncTask<String, String, Void> {
        private ProgressDialog progressDialog = new ProgressDialog(
                MasterCat.this);
        InputStream is = null;
        String result = "";

        protected void onPreExecute() {
            progressDialog.setMessage("Loading...");
            progressDialog.show();
            progressDialog.setCancelable(false);
        }

        @Override
        protected Void doInBackground(String... params) {
            String url_select = "http://www.---.com/---/master.php";

            HttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url_select);
            ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();

            try {
                httpPost.setEntity(new UrlEncodedFormEntity(param));
                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();

                // read content
                is = httpEntity.getContent();

            } catch (Exception e) {

                Log.e("log_tag", "Error in http connection " + e.toString());
            }
            try {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(is));
                StringBuilder sb = new StringBuilder();
                String line = "";
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();

            } catch (Exception e) {
                // TODO: handle exception
                Log.e("log_tag", "Error converting result " + e.toString());
            }

            return null;

        }

        protected void onPostExecute(Void v) {

            String cat;
            try {
                jArray = new JSONArray(result);
                JSONObject json_data = null;
                for (int i = 0; i < jArray.length(); i++) {
                    json_data = jArray.getJSONObject(i);
                    cat = json_data.getString("category");

                    cats.add(cat);

                }
            } catch (JSONException e1) {
                Toast.makeText(getBaseContext(), "No Categories Found",
                        Toast.LENGTH_LONG).show();
            } catch (ParseException e1) {
                e1.printStackTrace();
            }

            ListView listView = getListView();
            listView.setTextFilterEnabled(true);

            listView.setOnItemClickListener(new OnItemClickListener() {

                public void onItemClick(AdapterView<?> arg0, View arg1,
                        int arg2, long id) {

                    Intent i = new Intent(getApplicationContext(), Items.class);
                    i.putExtra("category", cats.get(arg2));
                    startActivity(i);

                }
            });

            progressDialog.dismiss();

            MasterCatAdapter adapter = new MasterCatAdapter(MasterCat.this,
                    cats);
            setListAdapter(adapter);

        }
    }

编辑:现在我假设强制关闭是因为连接不良;但是当我可以重新创建它时,我会尝试启动它。

Edit2:这里是 LogCat:

08-13 14:57:00.580: E/WindowManager(2262): Activity com.---.---.MyFragmentActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@42b02cd0 that was originally added here
08-13 14:57:00.580: E/WindowManager(2262): android.view.WindowLeaked: Activity com.---.---.MyFragmentActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@42b02cd0 that was originally added here
08-13 14:57:00.580: E/WindowManager(2262):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:374)
08-13 14:57:00.580: E/WindowManager(2262):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292)
08-13 14:57:00.580: E/WindowManager(2262):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
08-13 14:57:00.580: E/WindowManager(2262):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
08-13 14:57:00.580: E/WindowManager(2262):  at android.view.Window$LocalWindowManager.addView(Window.java:547)
08-13 14:57:00.580: E/WindowManager(2262):  at android.app.Dialog.show(Dialog.java:277)
08-13 14:57:00.580: E/WindowManager(2262):  at com.---.---.MyFragmentActivity$RateFragment$RatingTask.onPreExecute(MyFragmentActivity.java:374)
08-13 14:57:00.580: E/WindowManager(2262):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
08-13 14:57:00.580: E/WindowManager(2262):  at android.os.AsyncTask.execute(AsyncTask.java:534)
08-13 14:57:00.580: E/WindowManager(2262):  at com.---.---.MyFragmentActivity$RateFragment$insertTask.onPostExecute(MyFragmentActivity.java:520)
08-13 14:57:00.580: E/WindowManager(2262):  at com.---.---.MyFragmentActivity$RateFragment$insertTask.onPostExecute(MyFragmentActivity.java:1)
08-13 14:57:00.580: E/WindowManager(2262):  at android.os.AsyncTask.finish(AsyncTask.java:631)
08-13 14:57:00.580: E/WindowManager(2262):  at android.os.AsyncTask.access$600(AsyncTask.java:177)
08-13 14:57:00.580: E/WindowManager(2262):  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
08-13 14:57:00.580: E/WindowManager(2262):  at android.os.Handler.dispatchMessage(Handler.java:99)
08-13 14:57:00.580: E/WindowManager(2262):  at android.os.Looper.loop(Looper.java:137)
08-13 14:57:00.580: E/WindowManager(2262):  at android.app.ActivityThread.main(ActivityThread.java:4745)
08-13 14:57:00.580: E/WindowManager(2262):  at java.lang.reflect.Method.invokeNative(Native Method)
08-13 14:57:00.580: E/WindowManager(2262):  at java.lang.reflect.Method.invoke(Method.java:511)
08-13 14:57:00.580: E/WindowManager(2262):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-13 14:57:00.580: E/WindowManager(2262):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-13 14:57:00.580: E/WindowManager(2262):  at dalvik.system.NativeStart.main(Native Method)
08-13 14:57:00.588: D/AndroidRuntime(2262): Shutting down VM
08-13 14:57:00.588: W/dalvikvm(2262): threadid=1: thread exiting with uncaught exception (group=0x4200b300)
08-13 14:57:00.596: E/AndroidRuntime(2262): FATAL EXCEPTION: main
08-13 14:57:00.596: E/AndroidRuntime(2262): java.lang.NullPointerException
08-13 14:57:00.596: E/AndroidRuntime(2262):     at com.---.---.MyFragmentActivity$RateFragment$RatingTask.onPostExecute(MyFragmentActivity.java:461)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at com.---.---.MyFragmentActivity$RateFragment$RatingTask.onPostExecute(MyFragmentActivity.java:1)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at android.os.AsyncTask.finish(AsyncTask.java:631)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at android.os.Looper.loop(Looper.java:137)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at android.app.ActivityThread.main(ActivityThread.java:4745)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at java.lang.reflect.Method.invokeNative(Native Method)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at java.lang.reflect.Method.invoke(Method.java:511)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-13 14:57:00.596: E/AndroidRuntime(2262):     at dalvik.system.NativeStart.main(Native Method)

编辑:这是在不同活动中但在 LogCat 中引用的任务:

class RatingTask extends AsyncTask<String, String, Void> {

            private ProgressDialog progressDialog = new ProgressDialog(
                    getActivity());

            InputStream is = null;
            String result = "";

            protected void onPreExecute() {
                progressDialog.setMessage("Loading...");
                progressDialog.show();
                progressDialog.setOnCancelListener(new OnCancelListener() {

                    public void onCancel(DialogInterface dialog) {
                        RatingTask.this.cancel(true);
                    }
                });
            }

            @Override
            protected Void doInBackground(String... params) {
                String url_select = "http://www.---.com/---/get_ratings.php";

                ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
                param.add(new BasicNameValuePair("item", Item));
                param.add(new BasicNameValuePair("category", Category));

                HttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url_select);

                try {
                    httpPost.setEntity(new UrlEncodedFormEntity(param));
                    HttpResponse httpResponse = httpClient.execute(httpPost);
                    HttpEntity httpEntity = httpResponse.getEntity();

                    // read content
                    is = httpEntity.getContent();

                } catch (Exception e) {

                    Log.e("log_tag", "Error in http connection " + e.toString());
                }
                try {
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(is));
                    StringBuilder sb = new StringBuilder();
                    String line = "";
                    while ((line = br.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                    is.close();
                    result = sb.toString();

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

                return null;

            }

            protected void onPostExecute(Void v) {

                String starTotal = null, starAvg = null;
                try {
                    JSONArray jArray = new JSONArray(result);
                    JSONObject json_data = null;
                    for (int i = 0; i < jArray.length(); i++) {
                        json_data = jArray.getJSONObject(i);

                        starTotal = json_data.getString("TotalRating");
                        starAvg = json_data.getString("AverageRating");

                    }
                } catch (JSONException e1) {
                    Log.e("log_tag",
                            "Error in http connection " + e1.toString());
                    Toast.makeText(getActivity(), "JSONexception",
                            Toast.LENGTH_LONG).show();
                } catch (ParseException e1) {
                    e1.printStackTrace();
                }

                int total = 0;

                if (starTotal != null) {
                    total = Integer.parseInt(starTotal);
                } else {
                    starTotal = "0";
                }

                if (total > 0) {
                    total = Integer.parseInt(starTotal);
                } else {
                    total = 0;
                }

                StarTotal = (TextView) getActivity().findViewById(
                        R.id.tvStarTotal);
                StarTotal.setText("(" + String.valueOf(total) + (")"));

                float avg = 0.f;
                try {
                    avg = Float.parseFloat(starAvg);
                } catch (NumberFormatException e) {
                    avg = 0;
                }

                DecimalFormat myFormat = new DecimalFormat("0.00");
                StarNumbers = (TextView) getActivity().findViewById(
                        R.id.tvStarNumber);
                StarNumbers.setText(myFormat.format(avg));

                ratingsBarTwo.setRating(Float.valueOf(avg));
                progressDialog.dismiss();
            }
        }
4

3 回答 3

5

首先检查是否有可用的连接,如果没有则通知用户。

特别是如果用户试图打断它(但是我已经设置为不可取消)。

我会重新考虑这个决定。就个人而言,我不喜欢不可中断的进程。我的建议是,您可以按照@CommonsWare 在此处评论中的建议继续。很快,有一个布尔变量来检查数据是否无效,或者您自己检查您的数据是否为空。如果是,请不要执行基于此数据的任何命令,您将不会有任何与此相关的强制关闭。

有没有比我下面更好的方法来处理这个问题?

除了上述内容之外,我建议向您的 http 客户端添加一些 HTTP 参数。例如:

final int CONN_WAIT_TIME = 3000;
final int CONN_DATA_WAIT_TIME = 2000;

HttpParams httpParams = new BasicHttpParams();      
HttpConnectionParams.setConnectionTimeout(httpParams, CONN_WAIT_TIME);
HttpConnectionParams.setSoTimeout(httpParams, CONN_DATA_WAIT_TIME);

DefaultHttpClient postClient = new DefaultHttpClient(httpParams);

// Go on...

如果您的 http 客户端超过了您在各自字段中输入的时间,它只会给您一个ConnectTimeoutException. 现在您已经足够了解数据是否有效onPostExecute()以及您是否应该继续使用它。

于 2012-08-13T22:00:22.080 回答
2

您的异常是因为您在输入不同的活动时仍然显示对话框。在你说之前

Intent i = new Intent(getApplicationContext(), Items.class);
i.putExtra("category", cats.get(arg2));
startActivity(i);

调用这个:

progressDialog.dismiss()

而且您的活动将不再泄漏。

于 2012-08-13T22:07:13.200 回答
1
  1. 您的 doInBackground 返回 NULL。 return null;你通常会return result; 在那里

  2. 你的 onPostExecute(这里有 NuLL) :)) 结果。在这里onPostExecute(String result)并以这种方式处理它。检查再次发布的示例。

  3. 您必须处理这些空值(and也许在 中关闭此进度对话框
    onPostExecute()

8-13 14:57:00.596: E/AndroidRuntime(2262):     at com.---.--  -.MyFragmentActivity$RateFragment$RatingTask.onPostExecute(MyFragmentActivity.java:461)
   08-13 14:57:00.596: E/AndroidRuntime(2262):     at com.---.---.MyFragmentActivity$RateFragment$RatingTask.onPostExecute(MyFragmentActivity.java:1)
于 2012-08-13T22:05:04.160 回答