你怎么能处理一个的AsyncTask完成后撤销该DialogFragment(兼容LIB)你怎么、完成后、LIB、AsyncTask

2023-09-05 09:06:10 作者:邮寄情书

有关于如何处理过程中的AsyncTask配置改变无数的帖子,但没有我发现提供关于那些在后台应用程序明确的解决方案(的onPause())时的AsyncTask结束,并试图解雇DialogFragment(兼容图书馆)。

There are numerous posts about how to handle a configuration change during an AsyncTask, but none I have found give a clear solution regarding apps that are in background (onPause()) when an AsyncTask finishes and tries to dismiss a DialogFragment (compatibility library).

下面的问题,如果我有一个AsyncTask的运行,应该驳回onPostExecute()一DialogFragment,我得到一个IllegalStateException如果应用程序是当它试图驳回DialogFragment背景。

Here is the problem, if I have an AsyncTask running that should dismiss a DialogFragment in onPostExecute(), I get an IllegalStateException if the app is in the background when it tries to dismiss the DialogFragment.

private static class SomeTask extends AsyncTask<Void, Void, Boolean> {

    public SomeTask(SomeActivity tActivity)
    {
        mActivity = tActivity;
    }

    private SomeActivity mActivity;

    /** Set the view during/after config change */
    public void setView(Activity tActivity) {
        mActivity tActivity;
    }

    @Override
    protected Boolean doInBackground(Void... tParams) {
        try {
          //simulate some time consuming process
          TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException ignore) {}
        return true;
    }

    @Override
    protected void onPostExecute(Boolean tRouteFound) {
        mActivity.dismissSomeDialog();  
    }

}

该活动是这样的:

The Activity looks like this:

import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

public class SomeActivity extends FragmentActivity {

    public void someMethod() {
        ...
        displaySomeDialog();
        new SomeTask(this).execute();
        ...
    }

    public void displaySomeDialog() {
        DialogFragment someDialog = new SomeDialogFragment();
        someDialog.show(getFragmentManager(), "dialog");
    }

    public void dismissSomeDialog() {
        SomeDialogFragment someDialog = (SomeDialogFragment) getFragmentManager().findFragmentByTag("dialog");
        someDialog.dismiss();
    }

    ....

}

做工精细,除非应用程序切换到后台,而SomeTask仍在运行。在这种情况下,当SomeTask尝试dismissSomeDialog(),我得到一个IllegalStateException。

Works fine UNLESS the app switches to background while SomeTask is still running. In that case, when SomeTask tries to dismissSomeDialog(), I get an IllegalStateException.

05-25 16:36:02.237: E/AndroidRuntime(965): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

所有我见过的职位似乎指向一些缺憾方向精心设计的解决方法。是不是有处理这方面的一些Android的方式吗?如果它是一个对话框,而不是DialogFragment,那么活动的dismissDialog()将正确地处理它。如果它是一个真正的DialogFragment,而不是一个来自ACP,然后dismissAllowingStateLoss()将处理它。是不是有这样的事情对于ACP版本DialogFragment的?

All of the posts I've seen seem to point in some kludgy direction with elaborate workarounds. Isn't there some android way of handling this? If it were a Dialog instead of a DialogFragment, then the Activity's dismissDialog() would handle it correctly. If it were a real DialogFragment instead of one from the ACP, then dismissAllowingStateLoss() would handle it. Isn't there something like this for the ACP version of DialogFragment?

推荐答案

要解决的非法状态异常的问题,基本上实现dismissAllowingStateLoss()可以使用应做到以下几点。

To get around the illegal state exception issue and essentially implement a dismissAllowingStateLoss() can be done using the following.

getFragmentManager().beginTransaction().remove(someDialog).commitAllowingStateLoss();

这应该可以解决这个问题,而不哈克code。同样也可用于显示应用,如果你有线程使用dialog.show()通过与UI线程处理程序进行通信;这可能会导致非法状态异常以及

This should solve the issue without the hacky code. The same can also be applied for show if you have threads communicating through a handler with the UI thread using dialog.show(); Which can cause an illegal state exception as well

getFragmentManager().beginTransaction().add(someDialog).commitAllowingStateLoss();

@joneswah是正确的,因为海报问题。 如果您使用的是支持库,取代

@joneswah is correct, given the posters question. If you are using the support library, replace

getFragmentManager()

getSupportFragmentManager()

对于未来的谷歌: @Alex洛克伍德提出这个解决方案很好的,有效的关注。该解决方案确实解决了错误,将在大多数情况下,但暗示有与原来的问题的办法,从UX透视问题。

For future Googlers: @Alex Lockwood raises good and valid concerns with this solution. The solution does solve the error and will work in most cases, but hints that there are issues with the approach in the original question, from a UX perspective.

该活动应该假定异步任务可能无法完成,而且将不执行onPostExecute()。无论UI动作(如微调,最好不要一个对话框)开始通知异步操作的用户,应该有规定自动停止无论是在超时或跟踪状态,并检查OnRestore中/ onResume类型的生命周期事件,确保了UI是正确更新。服务可能还值得探讨。

The Activity should assume that the async task may not complete and that it will not perform onPostExecute(). Whatever UI action (ie, spinner, ideally not a dialog) is started to notify the user of the async operation, should have provisions to stop automatically either on a timeout or by tracking state and checking in onRestore/onResume type lifecycle events to ensure the UI is updated properly. Services may also be worth investigating.