0

我已经制作了一个 android 应用程序,因为数据来自服务器,所以这是一个耗时的过程,所以我创建了一个进度对话框..

下面是我的代码

  @Override
protected void onResume() {
    super.onResume();
    if (placesListItems != null)
        placesListItems.clear();
    new LoadPlaces().execute();
}

@Override
public void onPause() {
    super.onPause();
    if (pDialog != null)
        pDialog.dismiss();
}


  class LoadPlaces extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading Places..."));
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }



  protected String doInBackground(String... args) {

        GooglePlaces googlePlaces = new GooglePlaces();

        try {
            double radius = 1000; // 10000 meters

            // get nearest places
            if (query != null) {
                nearPlaces = googlePlaces.search(lat, lon, radius, query);
                if (nearPlaces != null) {

                    for (Place p : nearPlaces.results) {
                        reference = p.reference;
                        lat = p.geometry.location.lat;
                        lon = p.geometry.location.lng;
                        break;
                    }
                }
            }

            String types = "bar|restaurant|night_club|gym|health|food|shopping_mall|hospital";

            if (reference != null) {
                PlaceDetails placeDetails = googlePlaces.getPlaceDetails(reference);
                if (placeDetails != null) {
                    String status = placeDetails.status;

                    // check place deatils status
                    // Check for all possible status
                    if (status.equals("OK")) {
                        if (placeDetails.result != null) {
                            lat = placeDetails.result.geometry.location.lat;
                            lon = placeDetails.result.geometry.location.lng;
                            nearDeals = googlePlaces.search(lat, lon, radius, types);

在下面的代码中,如果我在从服务器获取数据期间按下主页按钮或屏幕消失(您可以说进度对话框正在运行),如果我回到我的应用程序,我得到一个错误 ARRAY INDEX OUT OF BOUND

                    // int total = ;
                            for (int i = nearDeals.results.size() - 1; i >= 0; i--) {
                                // Log.i("WHAT THE HELL",nearPlaces.results.get(i).name);
                                if (getResult(nearDeals.results.get(i).name, nearDeals.results.get(i).geometry.location.lat,
                                        nearDeals.results.get(i).geometry.location.lng) == 0) {
                                    // nearDeals.results.add(nearPlaces.results.get(i));
                                    nearDeals.results.remove(i);

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

下面是logcat

  09-25 18:23:13.429: W/System.err(4375): java.lang.IndexOutOfBoundsException: Invalid index 15, size is 15
  09-25 18:23:13.429: W/System.err(4375):   at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
  09-25 18:23:13.429: W/System.err(4375):   at java.util.ArrayList.get(ArrayList.java:311)
  09-25 18:23:13.429: W/System.err(4375):   at com.eheuristics.android.diegodeals.googleplacesandmaps.MainActivity$LoadPlaces.doInBackground(MainActivity.java:204)
  09-25 18:23:13.429: W/System.err(4375):   at com.eheuristics.android.diegodeals.googleplacesandmaps.MainActivity$LoadPlaces.doInBackground(MainActivity.java:1)
  09-25 18:23:13.429: W/System.err(4375):   at android.os.AsyncTask$2.call(AsyncTask.java:185)
  09-25 18:23:13.439: W/System.err(4375):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
  09-25 18:23:13.439: W/System.err(4375):   at java.util.concurrent.FutureTask.run(FutureTask.java:138)
  09-25 18:23:13.439: W/System.err(4375):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
  09-25 18:23:13.439: W/System.err(4375):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
  09-25 18:23:13.439: W/System.err(4375):   at java.lang.Thread.run(Thread.java:1019)

如果我不按主页键,或者在进度对话框运行期间屏幕不熄灭,那么一切正常

//从你们所有人那里得到解决方案后,我已经按照所有人的建议进行了打击,但我遇到了另一个错误,比如打击

    LoadPlaces ob;


    protected void onResume() {
    super.onResume();
    if (placesListItems != null)
        placesListItems.clear();
    ob.execute();
}

@Override
public void onPause() {
    super.onPause();
    if(ob!=null)
    if(ob.getStatus() == AsyncTask.Status.RUNNING){
       ob.cancel(true);
    }

    if (pDialog != null)
        pDialog.dismiss();
}

然后我得到如下错误

   09-25 18:53:30.609: E/AndroidRuntime(4674): java.lang.RuntimeException: Unable to resume activity {com.eheuristics.android.diegodeals/com.eheuristics.android.diegodeals.googleplacesandmaps.MainActivity}: java.lang.IllegalStateException: Cannot execute task: the task is already running.
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2241)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2256)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:965)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.os.Handler.dispatchMessage(Handler.java:99)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.os.Looper.loop(Looper.java:130)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.app.ActivityThread.main(ActivityThread.java:3835)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at java.lang.reflect.Method.invokeNative(Native Method)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at java.lang.reflect.Method.invoke(Method.java:507)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at dalvik.system.NativeStart.main(Native Method)
  09-25 18:53:30.609: E/AndroidRuntime(4674): Caused by: java.lang.IllegalStateException: Cannot execute task: the task is already running.
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.os.AsyncTask.execute(AsyncTask.java:380)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at com.eheuristics.android.diegodeals.googleplacesandmaps.MainActivity.onResume(MainActivity.java:137)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)
  09-25  18:53:30.609: E/AndroidRuntime(4674):  at android.app.Activity.performResume(Activity.java:3832)
  09-25  18:53:30.609: E/AndroidRuntime(4674):  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2231)
  09-25 18:53:30.609: E/AndroidRuntime(4674):   ... 10 more
4

2 回答 2

1

每次显示活动时,您都在启动 asynctask。因此,您应该在退出时取消任务(AsyncTask.cancel(true)),或者在 onResume 方法中检查它是否仍在运行。

于 2012-09-25T13:08:38.780 回答
0

在您收到错误 onResume() 的情况下,将再次调用,启动一个新的 AsyncTask。现在您有多个 AsyncTask 同时访问和更改 nearDeals.results 的大小(您在其上调用 remove)。当一个 asyncTask 从列表中删除一个项目时,第二个 asyncTask 可能会遇到 ArrayIndexOutOfBounds,因为列表大小已更改。

编辑:这实际上不是删除项目,而是您在 googlePlaces.search 中设置了列表的新实例,并且该列表的大小可能与旧 asynctask 使用的大小不同。

解决方案:在 onPause 中(或在开始新任务之前在 onResume 中)对正在运行的异步任务调用取消

于 2012-09-25T13:19:54.273 回答