UI线程处理程序在第一个Activity onCreate()之前没有收到消息

时间:2014-09-02 19:22:40

标签: android android-handler

我在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,管理者无论如何都无法显示任何内容。但我只是对这个原因感到好奇。

1 个答案:

答案 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);

但所有这一切都是因为我喜欢在框架规则和内置功能中进行游戏,因为它们比重新发明轮子更容易使用。