服务,线程和流程

时间:2016-09-24 05:09:06

标签: android multithreading android-activity process android-service

recent answer中,我读了

  

服务不在自己的线程上运行,它在UI线程上运行

我在许多其他与服务相关的问题中都读过类似的陈述。

如果我从startService()致电ActivityService会在Activity的用户界面Thread上运行,还是会产生一个新进程它是自己的用户界面Thread

如果它在Activity的用户界面Thread上运行,那么Activity没有响应会不会有风险?

5 个答案:

答案 0 :(得分:3)

是服务确实在主线程上运行,关于ANR(应用程序没有响应)问题,如果您的服务使用CPU进行长时间处理工作,ANR的可能性会更高,因此官方文档也建议使用Worker Threads为了效率。 docs

您必须阅读文档中的警告段落以确认

如果您的任务是一次性拍摄,那么使用IntentService隐式使用线程机制进行处理,但IntentService会在任务完成后自动销毁,因此您必须再次启动它时间等等。

android:process :使用它来启动另一个进程中的服务将导致使用更多内存。这将导致您的应用程序在单独的堆内存空间中创建两个进程,这也需要其他维护。所以这很少使用,我不建议将其用于常规服务任务。

答案 1 :(得分:2)

  

如果我从startService()致电ActivityService会继续运行   Activity的用户界面Thread或者它是否会产生一个新的进程' s   自己的用户界面Thread

如果它是Service(不是IntentService),它将在您应用程序进程的主Thread上运行,只要您不这样做明确地将它定义为一个单独的进程(通过在Manifest中添加android:process标记)。

  

如果它在Activity的用户界面Thread上运行,则不会产生风险   Activity没有反应?

是的,如果你执行CPU密集型/阻塞操作。

为防止这种情况发生,您可以从Thread开始新的Service,或使用IntentService,这会自动产生新的工作人员Thread它的工作。

答案 2 :(得分:1)

Services Docs它清楚地解释了你的答案。

  

警告:服务在其托管进程的主线程中运行 -   service不会创建自己的线程,也不会单独运行   过程(除非您另行指定)。这意味着,如果你的   服务将进行任何CPU密集型工作或阻塞操作   (如MP3播放或网络),你应该创建一个新的线程   在服务范围内做这项工作。通过使用单独的线程,你   将降低应用程序无响应(ANR)错误的风险   应用程序的主线程可以保持专用于用户交互   与您的活动。

答案 3 :(得分:1)

  

在最近的回答中,我读了

Service

这是完全错误的。 Service是一个对象(类的实例)。它不在任何线程上运行,它根本不运行。它只是“是”。 Service的方法可以在任何线程上运行,具体取决于......

具体而言,直接从Android框架调用的onCreate()onStartCommand()startService()等)的生命周期方法在主(UI)线程上运行,或者可能不是调用Service的同一个线程。但是,Service可以(并且通常会)启动其他后台线程,尽可能多地执行必要的工作。

  

如果我从一个Activity调用startService(),那么服务是否会运行   Activity的UI Thread或它是否使用它自己的UI生成一个新进程   线程?

见上文。如果您希望android:process=":service"在单独的流程中运行,可以通过在清单中的<service>声明中指定Activity来执行此操作。默认情况下,服务在与应用程序的其他组件(BroadcastReceiverService等)相同的过程中运行。

  

如果它在Activity的UI线程上运行,那么冒这个风险的风险就不大了   活动没有反应?

这取决于你Service正在做什么!显然,如果您的Service在UI线程上进行了大量计算密集型处理,则会使您的应用无响应。如果您的Service在UI线程上进行I / O操作,Android通常会抛出异常(在更新版本的Android中)。这就是服务通常启动后台线程来完成工作的原因。但是,如果您的Service是轻量级的,那么您的{{ x.country + ":" + x.capital}} 的方法无法在UI线程上运行。正如我所说,这取决于......

答案 4 :(得分:0)

IntentService在后台线程上运行,因此,如果你想做一次性任务,那就使用它。