0

私はデータがサーバーから来ているというアンドロイドアプリケーションを1つ作成したので、プロセスに時間がかかるので、進行状況ダイアログボックスを1つ作成しました..

以下は私のコードです

  @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.cancel(true))、onResumeメソッドでタスクがまだ実行されているかどうかを確認する必要があります。

于 2012-09-25T13:08:38.780 に答える
0

エラーが発生した場合は、onResume()が再度呼び出され、新しいAsyncTaskが開始されます。これで、nearDeals.resultsのサイズに同時にアクセスして変更する複数のAsyncTaskができました(removeを呼び出します)。1つのasyncTaskがリストからアイテムを削除すると、リストのサイズが変更されたため、2番目のasyncTaskがArrayIndexOutOfBoundsに遭遇する可能性があります。

編集:実際にはアイテムの削除ではありませんが、googlePlaces.searchでリストの新しいインスタンスを設定すると、このリストのサイズが古い非同期タスクで使用されていたものと異なる場合があります。

解決策:onPause(または新しいタスクを開始する前にonResume)で実行中の非同期タスクでcancelを呼び出します

于 2012-09-25T13:19:54.273 に答える