正确处理Async-Task中的片段交互

时间:2014-10-25 00:41:25

标签: android android-fragments android-asynctask android-context

我正在尝试使用更安全的异步任务来重构我的片段密码,因为我注意到偶尔发生了一些崩溃。现在,经过一些搜索,我受过更好的教育,我发现我的主要问题是从异步任务本身访问活动或片段变量。

我将每个异步任务分成单个类,这些类实现了对调用它们的片段或活动的接口回调。例如:

public class LoginFragment extends Fragment implements RequestForgotPassword {

...
//On Forgot Password click
new AsyncForgotPassword(LoginFragment.this, mEmail).execute();
...

@Override
public void onForgotPasswordResult(Result result)
{
    if(isAdded())
    {
        if (result == Result.SUCCESS)
            Toast.makeText(getActivity(), "An email has been sent to your account to assist in recovering your password", Toast.LENGTH_LONG).show();
        else
            Toast.makeText(getActivity(), "We don't have any record of that registered email, sorry! Please try again", Toast.LENGTH_LONG).show();
    }
}

...

}

OnTaskCompleted.java

public interface OnTaskCompleted {
    enum Result{SUCCESS, FAILURE};
}

RequestForgotPassword.java

public interface RequestForgotPassword extends OnTaskCompleted {
    void onForgotPasswordResult(Result result);
}

AsyncForgotPassword.java

public class AsyncForgotPassword extends AsyncTask<Void, Void, JSONObject> {

    private RequestForgotPassword mRequest;
    private String mEmail;

    public AsyncForgotPassword(RequestForgotPassword request, String email)
    {
        mRequest = request;
        mEmail = email;
    }

    @Override
    protected JSONObject doInBackground(Void... params) {
        ServerFunctions serverFunctions = new ServerFunctions();
        return serverFunctions.forgotPassword(mEmail);
    }

    @Override
    protected void onPostExecute(JSONObject obj) {
        try {
            JSONObject json1 = obj.getJSONObject("response");
            if (json1.getString("success").matches("1")) {
                mRequest.onForgotPasswordResult(OnTaskCompleted.Result.SUCCESS);
            } else {
                mRequest.onForgotPasswordResult(OnTaskCompleted.Result.FAILURE);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

所以基本上我认为如果大多数异步任务都是这样编写的话会很好。许多将以进度对话为特色,可以长时间运行,或者与调用片段等进行有意义的交互。我发现了一些非常有趣的讨论herehereherehere让我接近这个设置。

我在第一个链接的答案(2010年的书面回答)中对Dianne的代码的理解是,它确保从异步任务访问时活动永远不会为空。我的应用程序只有几个活动和许多片段,所以我无法真正看到这种方法今天如何运作良好。我过去在使用异步任务等交换片段时遇到了问题,并希望确保我不会再遇到与上下文无关的问题。

因此,如果我在异步任务完成后检查片段中的isAdded(),那么getActivity()是否保证为非空?我应该每次调用executePendingTransactions()just beforehand来确定吗?这一切都有点过分吗?

感谢您的任何反馈!

1 个答案:

答案 0 :(得分:1)

来自doc:

public final boolean isAdded ()

Return true if the fragment is currently added to its activity.

所以活动不能为空。

编辑:

要实现长时间运行的任务,我建议您使用 IntentService (如果任务执行复杂的本地操作,否则AsyncTask就可以了),将数据保存在 DB 中(或者以其他形式,例如在SharedPreferences中,如果它是一小部分信息)并使用 LocalBroadcast 传播逻辑。您还可以管理对片段的 onCreate()回调的检查,这样如果在任务过期时它被分离,它可以检索持久化的数据并正确管理它们;之后,您可以刷新先前存储的数据。