我已经制作了一个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
答案 0 :(得分:1)
每次展示活动时,您都会启动asynctask。因此,您应该在退出时取消该任务(AsyncTask.cancel(true)),或检查它是否仍在onResume方法中运行。
答案 1 :(得分:0)
在你得到错误onResume()的情况下再次调用,启动一个新的AsyncTask。现在你有多个AsyncTask同时访问和改变nearDeals.results的大小(你调用remove就可以了)。当一个asyncTask从列表中删除一个项目时,第二个asyncTask可能会运行到ArrayIndexOutOfBounds,因为列表大小已经改变。
编辑:实际上并不是删除项目,而是在googlePlaces.search中设置列表的新实例,此列表的大小可能与旧的asynctask使用的大小不同。
解决方案:在onPause上调用正在运行的异步任务取消(或在启动前调用onResume) 新任务)