【问题标题】:Correctly handling fragment interactions from an Async-Task正确处理来自异步任务的片段交互
【发布时间】:2014-10-25 00:41:24
【问题描述】:

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

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

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 的代码的理解是,它确保从异步任务访问时活动永远不会为空。我的应用程序只有几个活动和许多片段,所以我真的看不出这种方法在今天如何运作得那么好。过去我在用异步任务等交换片段时遇到过问题,我想确保我不会再遇到与 null Context 相关的问题。

所以如果我在异步任务完成后检查片段内的isAdded()getActivity() 是否保证为非空?我是否应该每次都调用 executePendingTransactions() just beforehand 来确保?这都是大材小用吗?

感谢您的任何反馈!

【问题讨论】:

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


    【解决方案1】:

    来自文档:

    public final boolean isAdded ()
    
    Return true if the fragment is currently added to its activity.
    

    所以活动不能为空。

    编辑:

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

    【讨论】:

    • 好的,这已经回答了我的问题了 :) 我将如何正确处理片段分离?我将更新问题的标题以反映这一点。
    猜你喜欢
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    相关资源
    最近更新 更多