处理程序返回没有活动?

时间:2015-07-08 20:03:31

标签: java android

我在线程返回后使用处理程序来更新我的UI - 以下是从线程(在片段中)运行的方法

public void signedIn(final boolean success, final String error) {
    Handler mainHandler = new Handler(getActivity().getMainLooper());
    mainHandler.post(new Runnable() {

        @Override
        public void run() {
            if(success) {
                Toast.makeText(getActivity(), "Signed In!",
                        Toast.LENGTH_SHORT).show();
            } else if (!success) {
                Toast.makeText(getActivity(), "Failed!" + error,
                        Toast.LENGTH_SHORT).show();
            }
        }
    });


}

这很好用,但是如果我在正确的时间旋转手机,则在创建活动之前调用处理程序,因此getActivity()返回null并且应用程序崩溃。我不能将方法包装在if(getActivity()!= null)中,否则它根本不会更新UI。

解决此问题的最佳方法是什么? Android有什么我可以用来解决这个问题吗?

谢谢,

凯文。

修改

所以我已经实现了以下其中一个似乎有用的响应。在应用程序类中使用静态上下文引用:Static way to get 'Context' on Android?

我不确定使用这个的细节所以有点犹豫 - 我可能会发布另一个问题,看看这是否有问题?

3 个答案:

答案 0 :(得分:1)

this回答中,您可以了解处理与轮换相关的应用程序配置更改的最佳做法。处理此问题的最佳方法是使用setRetainInstance(true)创建一个片段,以保留对正在进行的任务的引用。

这是必需的,因为当您旋转屏幕时,Android会破坏您当前的活动(甚至调用onDestroy方法)并使用新配置创建一个新活动。这样,您就可以知道任务何时完成,并对尚未创建的活动运行UI操作。

修改

如果上下文为null,片段任务不应该推送结果,只需存储它。重新加载活动时,将调用其onCreate。由于您使用了任务片段,因此您将能够检索片段实例并知道此任务是否已完成。活动应该做的唯一事情就是根据已完成的片段任务恢复其新状态。

答案 1 :(得分:0)

使用它来获取looper:

Looper mainLooper = Looper.getMainLooper();

它对我有用。

编辑: Looper.getMainLooper()返回UI线程的looper(主线程)。

EDIT2: 您可以在View上使用getContext()来获取上下文。

答案 2 :(得分:0)

您可以使用getApplicationContext()为Toast获取合适的上下文。但是,您可以访问的方法受此代码执行位置的限制。

编辑:

我在这里努力理解你的方法。你为什么拒绝这样做:

public void signedIn(boolean success, String error) {
    if(success){
        Toast.makeText(getActivity(), "Signed In!",
            Toast.LENGTH_SHORT).show();
    } 
    else{
        Toast.makeText(getActivity(), "Failed!" + error,
            Toast.LENGTH_SHORT).show();
    }
}

使其与runnable异步创建了一个潜在的竞争条件来访问活动的实例。对于显示祝酒的简单任务来说,这似乎是完全不必要的复杂性。

此外,由于布尔值只能处于两种状态之一,因此您不需要else if子句。

还要更改此方法的名称以更好地与Java命名约定保持一致。 “signedIn”应该是返回用户是否为signedIn的方法的名称。