0

there is java class extends FragmentActivity, min-sdk is 10

i used ViewPager with FragmentManager to show images in viewpager indicator

some times it shows me error when i want to exit activity

private static ArrayList<PgItem> image_resource;
public static ArrayList<ProjectItem> items = new ArrayList<ProjectItem>();
private static ViewPager v_pager;
private static TitlePageIndicator pagerIndicator;
public static FragmentManager fgmanger;
public static void setSIAdapter(ArrayList<ProjectItem> inputArray , int ex){
    switch (ex){
        case 0:
            Log.i(App.logs.WEBSERVICE, "CertificateAsync >> inputArray.size : " + inputArray.size());
            if(!inputArray.isEmpty()) {
                items.clear();
                items.addAll(inputArray);
                image_resource = new ArrayList<PgItem>();
                image_resource.clear();

                for (int i = 0; i < inputArray.size(); i++) {
                    String image = ""+inputArray.get(i).getPrjImage();
                    if(image.trim().length() > 0 && image.replace(""+App.webServiceConfigs.ROOT , "").trim().length() > 0) {
                        String text = ""+inputArray.get(i).getPrjTitle();
                        String ext = image.substring(image.lastIndexOf(".") , image.length());
                        if(!image.toLowerCase().contains("_xl"+ext)){
                            image = image.replace(ext , "_XL"+ext);
                        }
                        PgItem item = new PgItem(image, text);
                        image_resource.add(item);
                        Log.i(App.logs.TEST, "image_resource.image_name # " + (image_resource.size()-1) + " : " + image_resource.get(image_resource.size()-1).getImage());
                    }
                }
                FragmentAdapter adapter = new FragmentAdapter(fgmanger , image_resource);
                if(v_pager != null){
                    v_pager.setAdapter(adapter); // Error Line
                    pagerIndicator.setViewPager(v_pager);
                    pagerIndicator.setTextSize(UIHelpers.textFont-2);
                    pagerIndicator.setSelectedBold(true);
                    pagerIndicator.setSelectedColor(Color.parseColor("#595458"));
                    pagerIndicator.setTextColor(Color.parseColor("#9E9E9E"));
                    pagerIndicator.setTypeface(Typeface.createFromAsset(App.configs.currentActivity.getAssets(), "yekan.ttf"));
                }
  //ImagePagerAdapterPg adapter = new ImagePagerAdapterPg(image_resource);
  //   v_pager.setAdapter(adapter);

            }
            break;
        case -1:
            Toast toastProtocol = Toast.makeText(App.configs.context , App.configs.context.getString(R.string.PROTOCOL_EXCEPTION) , Toast.LENGTH_LONG);
            toastProtocol.setGravity(Gravity.CENTER, 0, (int) (UIHelpers.width * 0.25));
            toastProtocol.show();
            if(App.webServiceConfigs.connectionTimeOut <= 18000) {
                App.webServiceConfigs.connectionTimeOut += 3000;
            }
            if(App.webServiceConfigs.socketTimeOut <= 18000) {
                App.webServiceConfigs.socketTimeOut += 3000;
            }
            callWebservice();
            break;
        case -2:
            Toast toastIO = Toast.makeText(App.configs.context , App.configs.context.getString(R.string.IO_EXCEPTION) , Toast.LENGTH_LONG);
            toastIO.setGravity(Gravity.CENTER, 0, (int) (UIHelpers.width * 0.25));
            toastIO.show();
            if(App.webServiceConfigs.connectionTimeOut <= 20000) {
                App.webServiceConfigs.connectionTimeOut += 3000;
            }
            if(App.webServiceConfigs.socketTimeOut <= 20000) {
                App.webServiceConfigs.socketTimeOut += 3000;
            }
            callWebservice();
            break;
        case -3:
            break;
        case -4:
            break;
    }
}

i load images from cache and show to user, then connect to server and update image adapter again.

it shows me error :

05-19 17:56:27.213    9768-9768/com.emaarIt.app.Bernoulli E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: Activity has been destroyed
        at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1358)
        at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
        at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)
        at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
        at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:415)
        at com.emaarIt.app.Bernoulli.activities.ProjectGalleryActivity.setSIAdapter(ProjectGalleryActivity.java:225)
        at com.emaarIt.app.Bernoulli.webservice.modules.ProjectGalleryAsync.onPostExecute(ProjectGalleryAsync.java:78)
        at com.emaarIt.app.Bernoulli.webservice.modules.ProjectGalleryAsync.onPostExecute(ProjectGalleryAsync.java:32)
        at android.os.AsyncTask.finish(AsyncTask.java:602)
        at android.os.AsyncTask.access$600(AsyncTask.java:156)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4441)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
        at dalvik.system.NativeStart.main(Native Method)

1 Answer 1

3

Cause:

The problem here is that after your activity got destroyed, the AsyncTask was still working and when it finishes it's work it will call AsyncTask's OnPostExecute() callback method and you are setting the adapter of the ViewPager which contacts the Activity to add the Fragments to the back stack and that can't happen because your activity got destroyed.


Proposed Solution:

You can hold a reference to your AsyncTask object and cancel it on the Activity's onDestroy() callback.

protected void onDestroy() {
    super.onDestroy();
    // cancel the task
    if(asyncTask != null && asyncTask.getStatus() != AsyncTask.Status.FINISHED) {
        asyncTask.cancel(true);
    }
}

What AsyncTask.cancel() do?

Calling this method will result in onCancelled(Object) being invoked on the UI thread after doInBackground(Object[]) returns. Calling this method guarantees that onPostExecute(Object) is never invoked.

Sign up to request clarification or add additional context in comments.

1 Comment

If you'll go this way, be sure not do touch any UI-related stuff in onCancelled method, otherwise you might end up with the same problem as originally.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.