我在线程返回后使用处理程序来更新我的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?
我不确定使用这个的细节所以有点犹豫 - 我可能会发布另一个问题,看看这是否有问题?
答案 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的方法的名称。