Android后台服务控制UI活动

时间:2014-10-20 12:43:18

标签: android qt android-activity android-service

我是Android应用程序开发的新手,因此在让我的应用程序成功运行方面遇到了严重的麻烦。我想我的大多数问题都可以归结为由于缺乏android平台概念和Android上的PC编程概念的使用! ;)

我打算做的是开发基于UI的Android应用程序,但我强烈要求应用程序应该像守护进程一样! 当我说守护进程;当应用程序启动时,UI不应该是可见的!基于某些唤醒事件,应用程序显示被唤醒,以便UI对用户可见。同样,基于某些睡眠事件,应隐藏应用程序UI。类似于android上的警报应用程序。

UI部分对我来说非常容易,因为我使用了Qt端口用于android,应用程序就像魅力一样。但这与任何正常的应用程序一样,并不包括我上面提到的要求。我试过看Qt文档并没有规定实现这一点,在一些论坛中,他们建议使用android SDK方法来实现这一点。

由于我不是Java专家,我阅读了很多关于android开发的内容,并设法创建了一个应用程序,它有点“满足上述要求但我没有问题,我想知道我是否遵循了正确的方法。总结一下我在下面做的事情。

  1. 我将android.app.Service子类化,并在我的重写onStartCommand中,我创建了一个检查唤醒和睡眠事件的工作线程。为了便于讨论,我们假设唤醒事件就像每60分钟一样,睡眠事件就像唤醒后的5分钟一样。
  2. 在onStartCommand方法中,我正在广播一个Intent,期望创建我的服务的活动接收它(下面的步骤6解释了为什么我这样做)
  3. 满足唤醒条件的工作线程,按如下方式启动我的UI活动:

    Intent activityIntent = new Intent(getBaseContext(), MyUIActivity.class); activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getApplication().startActivity(activityIntent);

  4. 满足睡眠条件的工作线程通过广播期望UI活动接收它的Intent来请求我的UI活动完成。

  5. onStartCommand最终返回START_NOT_STICKY。
  6. 我有一个主要活动,它将一个BroadcastReceiver实例注册到一个IntentFilter,以便在从上面的步骤2开始服务后接收Intent。收到Intent后,我调用finish()来关闭UI来守护我的服务!
  7. 上面的设置工作正常,我可以看到服务在后台播放正确的Toast消息,当满足唤醒条件并且Qt小部件完美地显示在屏幕上时,UI也会显示。 但是,我在以安全的方式使用此设置时遇到的问题很少。以下是问题(不确定它们是否是真正的问题):

    有时当我启动应用程序时,我看不到从onStartCommand方法启动服务的toast消息,但logcat显示以下消息:

    W/ActivityManager( 628): Scheduling restart of crashed service org.example.myapp/.MyService in 1000ms I/ActivityManager( 628): START u0 {flg=0x10000000 cmp=org.example.myapp/.MyApplicationActivity (has extras)} from pid 21764 W/ActivityManager( 628): Permission Denial: starting Intent { flg=0x10000000 cmp=org.example.myapp/.MyApplicationActivity (has extras) } from null (pid=21764, uid=2000) not exported from uid 10129

    当我尝试手动启动应用程序时,它运行正常!

    当我尝试通过调用finish()来隐藏UI活动时;我想这是在我看到以下消息的时候:

    I/WindowState( 628): WIN DEATH: Window{428ef138 u0 org.example.myapp/org.example.myapp.MyApplicationActivity} W/ActivityManager( 628): Scheduling restart of crashed service org.example.myapp/.MyService in 1000ms W/WindowManager( 628): Force-removing child win Window{41962f40 u0 SurfaceView} from container Window{428ef138 u0 org.example.myapp/org.example.myapp.MyApplicationActivity}

    此后,该服务不再有效!

    从根本上说,我的问题是:这是正确的做法吗?

1 个答案:

答案 0 :(得分:0)

请确认何时发生睡眠事件您的设备处于睡眠模式,即屏幕关闭或开启?

如果它已经睡觉,那么你的接收器将无法接收意图,因为它已经在睡觉。您必须在活动中设置nay标志,您可以在活动恢复时检查并执行相应的操作并完成活动实例。

您没有看到您的Toast消息,因为服务的生命周期与Activity的生命周期无关。服务保持在后台运行,直到您明确停止或系统终止它们为止。