我在UI线程上有一个Handler
(使用new Handler(Looper.getMainLooper())
创建),一旦应用程序启动就会发送一系列消息(特别是在Application类' {之后) {1}})。我注意到的是,onCreate
似乎在第一个Handler
的{{1}}周围才收到消息。在此之前,发送给它的消息似乎丢失了。
这是因为在第一个onCreate
可见之前,UI线程的Activity
还没有准备好执行消息吗?
补充资料
我只是在下面的评论中添加此信息 - 它不是特定问题的一部分。
此Looper
用作机制的一部分,允许各种长时间运行的任务使用我自己的Eclipse版本{Activity
使进度信息显示在当前Handler
上。 1}}。
当应用程序启动时,完成一项初始化工作。这项工作是一项长期运行的任务,涉及根据文件内容构建数据结构。在使用应用程序期间,这段初始化工作可能必须重复,具体取决于用户操作。
在这个应用程序中,我有自己的Activity
实现,这个想法基于Eclipse Platform API中的类。有了这个,应用程序中的各种长时间运行的任务,包括初始化工作,都可以从管理器类中获取IProgressMonitor
,并在其上调用进度更新方法(如IProgressMonitor
,{{1 }}, 等等)。如果显示任何IProgressMonitor
,则会导致可见的进度通知可见(使用Crouton库)。
IProgressMonitor背后的实际实现使用done()
将percentDone()
,Activity
等更新传输到UI线程。然后,经理类通过Handler
获取更新,并且会导致可见状态更新如果 done()
可见(并已向经理注册)。
让我了解上述问题的原因是,当应用程序启动并且首次启动初始化时,percentDone()
上的呼叫似乎无法通过UI-Thread Handler
直到第一个Activity
可见。从功能的角度来看,这并不重要,因为没有可见的IProgressManager
,管理者无论如何都无法显示任何内容。但我只是对这个原因感到好奇。
答案 0 :(得分:0)
消息不会丢失"正如你所说,它们是在晚些时候交付的。这是因为即使您拥有多个Handler
对象,消息所在的队列也只有一个Lopper
队列。当你的活动启动时,Android系统已经排队了它必须做的所有其他事情,以便向用户显示活动。
旁注:如果它没有用于任何与UI相关的东西,请不要将它放在UI线上!有道理吗?
某些选项可能会因他们正在做的事情而有所不同:
使用延迟初始化,意思是,只有在用户主动需要它们时才会初始化这些组件。
创建一个低优先级的HandlerThread
来执行那些与UI无关的操作。甚至可能会延迟它们几秒钟,以便在执行任何UI之前先构建整个UI。
根据您的额外信息进行修改:
我不建议您构建此方法所采用的方法,原因是:那不是Handlers的用途,Android框架有自己的长期运行任务实现以及如何进行通信返回当前有效的Activity
"这项工作是一项长期任务,并且#34;在Android中,长时间运行的任务,特别是与UI无关的任务,应该委托给Service
可能您应该查看自动拥有IntentService
HandlerThread
的{{1}}后台的长任务线程接收它们的顺序,并且当没有其他任何内容可以执行时自动销毁。
要获得有关正在服务上执行的任务的更新信息,请选择两种可能的方法。
1 - 更复杂,但更完整的方法,您bind
服务活动和直接调用方法,如setListener
。这涉及一些ServiceConnection回调,但也允许活动和服务之间的密切交互。
2 - 更简单的单向方法是对LocalBroadcastManager
进行调度更新并让活动听取它们,我将在下面向您展示一个快速示例:
服务代码,例如,在构建数据结构作业上发送进度更新
Intent i = new Intent(MY_APP_UPDATE);
i.putExtra("serviceType", BUILDING_DATA_STRUCTURE);
i.putExtra("updateType", ON_UPDATE);
i.putExtra("updateValue", progress_percent);
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
然后在你的活动中你创建一个BroadcastReceiver内部类和onResume / onPause你监听更新。
private BroadcastReceiver myReceiver = new BroadcastReceiver(){
@Override public void onReceive (Context context, Intent intent){
int serviceType = intent.getIntExtra("serviceType", 0);
int updateType = intent.getIntExtra("updateType", 0);
int updateValue = intent.getIntExtra("updateValue", 0);
// here you can properly handle the updates being sure that your activity isResumed
}
}
然后onResume / onPause注册/取消注册
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, new IntentFilter(MY_APP_UPDATE));
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
但所有这一切都是因为我喜欢在框架规则和内置功能中进行游戏,因为它们比重新发明轮子更容易使用。