我正在接近Android服务,但我有很多疑问。这里有一些问题。 在开始之前,请注意我已阅读这些页面 Android Services (official) Bounded Services (official) 加上我语言中的内心课程理论。请耐心等待,我仍然有点困惑。
1)首先,服务区别于AsyncTask主要是因为如果应用程序暂停(即用户正在观看另一个应用程序),它也会继续运行;在这种情况下,AsyncTask会停止。可以,还是我错了? 2)服务在通过startService()启动它的活动的同一个线程中运行。 为了不影响Activity的性能,我必须为该服务创建一个单独的线程,例如实现Runnable接口。另一种方法是创建一个扩展IntentService的服务,它自动为服务提供一个新线程:在任何onHandleIntent()调用上创建一个新线程。
现在,让我们来看看我的具体问题。我需要创建一个将被许多活动使用的服务:他的任务是每隔60秒连接到服务器数据库并检查新闻。如果找到新闻,请通知新消息(如果我们在MainActivity上)或显示新新闻的标题(如果我们在新闻阅读器中)。我该怎么编码呢? 我做了一个MainActivity来实例化一个NewsService并立即调用startService()。另一方面,我有NewsService扩展IntentService,(当调用onHandleIntent时创建一个新线程?)并寻找新消息。使用IntentService是个坏主意吗?我意识到启动无限期调用startService()的服务会非常难看。 在这个练习的开始我认为它是一个很好的解决方案,因为它自动创建一个新的线程,并使Service实现简单。但现在我有些怀疑(我不知道是否有新闻!MainActivity如何知道它?以及如何获得标题)
这应该通过普通的扩展Thread类来完成,它在它的run()方法中创建一个无限的cicle,每隔60秒检查一次新闻,如果有新的,则读取标题来自远程DB和更新活动按钮/视图。然后,如果应用程序将被用户关闭,则服务也将关闭。 但问题是,如果我是这样的类,它的工作将在MainActivity暂停或停止时停止,而其他活动(在这种情况下为NewsReader)无法获得任何更新,因为新线程不是此刻获得新闻。所以我需要一个服务。
我希望它清楚。我该如何以正确的方式实施解决方案? 请突出显示我的文字中的所有错误,我真的需要学习:D
答案 0 :(得分:1)
你好像已经理解了一切。
关于您的具体问题,我建议如下:
使用AlarmManager
来安排您的服务。不要让Service
在没有的情况下运行。
使用Broadcast Intent
新消息。所有Activities
都必须有一个内部BroadcastReceiver
来监听服务的Broadcast
意图,并做出相应的反应。
答案 1 :(得分:0)
服务对于你想要的东西来说是一个很好的方法,它们非常适合做一些消耗很少资源的进程,例如在后台保留一个守护进程,它们也可以在没有活动的情况下显示通知,并且即使你退出活动也能继续运行
如果您需要在服务中执行更多繁重的操作,您仍然可以使用AsyncTask
,启动它,在另一个线程中执行操作并自动在主线程中接收结果。
如果您希望始终保持服务正常运行,可以在服务中使用START_STICKY
@Override
public int onStartCommand(final Intent intent, final int flags,
final int startId) {
// Ensure the service will restart if it dies
return START_STICKY;
}
您可以启动服务:
final Intent service = new Intent();
service.setComponent(new ComponentName(YourService.PACKAGE_NAME,
YourService.SERVICE_FULL_NAME));
// Start the service
context.startService(service);
答案 2 :(得分:0)
1)首先,服务区别于AsyncTask 主要是因为如果应用程序暂停,它也会继续运行(即 用户正在观看其他应用);在这种情况下,AsyncTask会停止。是 好吧还是我错了?
这不正确。 AsyncTask
是一种将后台处理卸载到单独线程的机制,并提供一种机制,用于通知用户该后台处理的进度,错误和完成情况。如果应用暂停,则AsyncTask
不会停止工作。它继续在后台执行处理。通常,AsyncTask
和启动它的Activity
之间存在紧密耦合。
另一方面,Service
(通常)与启动它的Activity
完全分离。 Service
有自己的生命周期,独立于应用程序中的其他活动。此外,服务没有UI,因此它们没有链接到应用程序的可视元素,并且它们没有为与进度,错误或完成相关的视觉反馈提供(直接)机制。这需要单独编程。
2)服务运行在同一个线程中 通过startService()启动它的活动。不影响 活动的表现,我必须为此创建一个单独的线程 服务,例如实现Runnable接口。另一个 方法是制作一个扩展IntentService的服务 自动为服务提供一个新线程:一个新线程 在任何onHandleIntent()调用上创建。
这也不正确。 Service
不能在任何特定线程上运行。 Service
(onCreate()
,onStartCommand()
等)的生命周期方法在主(UI)主题上运行,其可能相同或不同调用startService()
的线程。但是,Service
可以(并且通常会)启动其他后台线程,尽可能多地执行必要的工作。
IntentService
是一种特定类型的Service
,它管理一个或多个用于执行后台处理的工作线程。您向IntentService
发送“命令”,然后IntentService
将您的命令放入队列中。在某些时候(不同Android版本中的不同实现表现不同),您的“命令”将在后台线程中出列并处理。处理完所有“命令”后,IntentService
自行停止。由于IntentService
的行为方式,Service
通常不是IntentService
的最佳选择。
AlarmManager
绝对不是你想要的。你应该使用Service
并设置一个每分钟开始Service
的警报。当您的Activity
启动时,它应该创建一个后台线程来联系您的服务器并检查新闻。如果没有新闻它就可以消失。如果有新消息,则可以启动Intent
通知用户,也可以发送Activity
将看到的广播Notification
(如果正在运行),或者可以创建一个Service
,然后用户可以随时打开它。您需要弄清楚如何确定应用程序应何时停止检查服务器。也许用户应该告诉你他不再感兴趣,或者{{1}}可能会认识到该应用程序不再运行(或者已经超过X小时或者其他任何时候都没有看过)。有很多方法可以做到这一点,这取决于您的要求。