Services
Service是一个应用程序组件,它能够在后台执行一些耗时较长的操作,并且不提供用户界面。服务能被其它应用程序的组件启动,即使用户切换到另外的应用时还能保持后台运行。此外,应用程序组件还能与服务绑定,并与服务进行交互,甚至能进行进程间通信(IPC)。 比如,服务可以处理网络传输、音乐播放、执行文件I/O、或者与content provider进行交互,所有这些都是后台进行的。
需要继承Services父类或者继承Services的子类
两种基本类型:
Started:没有和其他组件绑定,启动之后就一直在后台运行。此方法需要实现onStartCommand()方法。此方法在调用玩startservice()方法之后调用。之后就一直在后台运行,可以使用stopself()或stopservice()方法来终止服务。
Bound:与组件绑定(可与多个组件绑定),生命周期也与绑定的组件有关。需要实现onBind()方法。
以上两种方式启动完service之后会调用oncreate方式启动服务(如果服务已经运行,则不会调用oncreate方法)
扩展IntentService类
IntentService
这是Service类的子类,它使用了工作(worker)线程来处理所有的启动请求,每次请求都会启动一个线程。 如果服务不需要同时处理多个请求的话,这是最佳的选择。 所有你要做的工作就是实现onHandleIntent()即可,它会接收每个启动请求的intent,然后就可在后台完成工作。
扩展Service类
相比较上一种方式,这种方式要复杂很多。但是这样也有好处,能够让service多线程运行。public class Service extends android.app.Service { Looper looper; serviceHandle serviceHandle; @Override public int onStartCommand(Intent intent, int flags, int startId) { Message msg = serviceHandle.obtainMessage(); msg.arg1 = startId; serviceHandle.sendMessage(msg); return START_STICKY; } @Nullable @Override public IBinder onBind(Intent intent) { return null; } public class serviceHandle extends Handler { public serviceHandle(Looper looper) { super(looper); } public void handlemessage(Message msg) { } } @Override public void onCreate() { super.onCreate(); HandlerThread handlerThread = new HandlerThread("serviceHandle"); handlerThread.start(); looper = handlerThread.getLooper(); serviceHandle = new serviceHandle(looper); }
}
onStartCommand()方法必须返回一个整数。
-
START_NOT_STICKY
如果系统在onStartCommand()返回后杀死了服务,则不会重建服务了,除非还存在未发送的intent。
当服务不再是必需的,并且应用程序能够简单地重启那些未完成的工作时,这是避免服务运行的最安全的选项。
-
START_STICKY
如果系统在onStartCommand()返回后杀死了服务,则将重建服务并调用onStartCommand(),但不会再次送入上一个intent,
而是用null intent来调用onStartCommand() 。除非还有启动服务的intent未发送完,那么这些剩下的intent会继续发送。 这适
用于媒体播放器(或类似服务),它们不执行命令,但需要一直运行并随时待命。
-
START_REDELIVER_INTENT
如果系统在onStartCommand()返回后杀死了服务,则将重建服务并用上一个已送过的intent调用onStartCommand()。
任何未发送完的intent也都会依次送入。这适用于那些需要立即恢复工作的活跃服务,比如下载文件
服务向用户发送通知,一种是toast通知,一种是状态栏通知(点击可执行action)。
在前台运行服务
例如,网易云音乐
要把你的服务请求为前台运行,可以调用startForeground()方法。此方法有两个参数:唯一标识通知的整数值、状态栏通知Notification对象。例如:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION, notification);
要从前台移除服务,请调用stopForeground()方法,这个方法接受个布尔参数,表示是否同时移除状态栏通知。此方法不会终止服务。不过,如果服务在前台运行时被你终止了,那么通知也会同时被移除。
1.创建服务之后在服务中添加一个Binder,用于返回给客户端来访问他内部。
2.在服务中创建一个messager,传入一个handle作为参数,这样客户端就能通过这个messager来send 消息给服务的handle来进行处理