主要应用场景:后台运行和跨进程访问。 Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可通过绑定到服务与之进行交互,甚至是执行进程间通信 (IPC)。例如,服务可在后台处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序进行交互。
要使用Service,必须要在 AndroidManifest.xml 文件中声明
<service android:name=".service.TestService"/> <service android:name=".service.BindService"/>您还可在 元素中加入其他属性,以定义一些特性,如启动服务及其运行时所在进程需要的权限。android:name 属性是唯一必需的属性,用于指定服务的类名。
参考官方文档:应用清单文件 -> service
<service android:description="string resource" android:directBootAware=["true" | "false"] android:enabled=["true" | "false"] android:exported=["true" | "false"] android:foregroundServiceType=["connectedDevice" | "dataSync" | "location" | "mediaPlayback" | "mediaProjection" | "phoneCall"] android:icon="drawable resource" android:isolatedProcess=["true" | "false"] android:label="string resource" android:name="string" android:permission="string" android:process="string" > . . . </service> 属性说明android:description向用户描述服务的字符串。您应将此标签设置为对字符串资源的引用,以便可以像对界面中的其他字符串那样对其进行本地化。android:directBootAware服务是否支持直接启动,即其是否可以在用户解锁设备之前运行,默认值为 “false”。android:enabled系统是否可实例化服务,默认值为“true”android:exported其他应用的组件是否能调用服务或与之交互,默认值为“true”。android:foregroundServiceType阐明服务是满足特定用例要求的前台服务。例如,“location” 类型的前台服务表示应用正在获取设备的当前位置,目的通常是继续用户发起的操作,且该操作与设备位置相关。android:icon表示服务的图标。必须将该属性设置为对包含图像定义的可绘制资源的引用。android:isolatedProcess如果设置为 true,则此服务将在与系统其余部分隔离的特殊进程下运行。此服务自身没有权限,只能通过 Service API 与其进行通信(绑定和启动)。android:label可向用户显示的服务名称。如果未设置该属性,则转而使用为应用整体设置的标签。android:name实现服务的 Service 子类的名称,没有默认值。必须指定该名称。android:permission实体启动服务或绑定到服务所必需的权限的名称。android:process将运行服务的进程的名称。组件可以使用自己的 process 属性替换默认值,让您可以将应用散布到多个进程中。启动完之后该service就在后台运行,其生命周期跟启动它的Context没有任何关系。也不能跟Context通讯。
启动
private void testStartService() { Intent intent = new Intent(this, TestService.class); intent.putExtra(TestConstant.KEY_TEST_DATA,"data transfer"); startService(intent); }结束
private void testStopService() { Intent intent = new Intent(this, TestService.class); stopService(intent); }启动之后生命周期跟启动它的Context有关,比如Activity、fragment、service等。在Context中解绑之后,如果改Service没有任何绑定后该Service也就结束。
被绑定的Service:BindService
package com.example.testapp.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class BindService extends Service { private static final String TAG = "BindService"; public BindService() { super(); Log.d(TAG, "BindService: "); } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind: "); return new LocalBinder(); } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnbind: "); return super.onUnbind(intent); } public String getTestString () { return "binder successful"; } public class LocalBinder extends Binder { public BindService getBindSer() { return BindService.this; } } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: "); } }调用方式:先创建ServiceConnection
mSerConn = new ServiceConnection() { /* 与Service交互的接口方法 获取绑定Service传递过来的IBinder对象 通过这个IBinder对象,与Service进行交互 */ @Override public void onServiceConnected(ComponentName name, IBinder service) { mBindService = ((BindService.LocalBinder)service).getBindSer(); String testString = mBindService.getTestString(); Log.d(TAG, "onServiceConnected: " + "testString = " + testString); } /* 异常情况下取消绑定时回调(绑定失败) */ @Override public void onServiceDisconnected(ComponentName name) { Log.d(TAG, "onServiceDisconnected:"); } };绑定Service
Intent intent = new Intent(this,BindService.class); bindService(intent,mSerConn,Service.BIND_AUTO_CREATE);解绑Service 如果Activity绑定Service,要在 onDestroy() 时解绑Service
if(mBindService != null) { mBindService = null; unbindService(mSerConn); }onCreate() -> onStartCommand() -> onDestroy()
onCreate -> onBind() -> onUnbind() -> onDestroy()
如果服务已经开启,不会重复的执行onCreate(), 而是会调用onStart()和onStartCommand()。
一旦服务开启跟调用者(开启者)就没有任何关系了。开启者退出了,开启者挂了,服务还在后台长期的运行。开启者不能调用服务里面的方法。
绑定服务不会调用onstart()或者onstartcommand()方法
bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。 绑定者可以调用服务里面的方法。
可以看做是Service和HandlerThread的结合体,在完成了使命之后会自动停止,适合需要在工作线程处理UI无关任务的场景。
IntentService 是继承自 Service 并处理异步请求的一个类,在 IntentService 内有一个工作线程来处理耗时操作。当任务执行完后,IntentService 会自动停止,不需要我们去手动结束。如果启动 IntentService 多次,那么每一个耗时操作会以工作队列的方式在 IntentService 的 onHandleIntent 回调方法中执行,依次去执行,使用串行的方式,执行完自动结束。