开始
Service 用于在 Android 中执行一些后台任务,实现多任务或者进程间通信
Service 依赖于创建时所在的进程,当进程被杀死后,该进程的所有 Service 均失效
使用 Service 不会自动创建新的线程,若需要去实现一个耗时任务,创建新线程要注意避免 Service 运行在主线程引起的 ANR 问题(应用程序无响应)
创建 Service
创建 Service:继承 Service
类,重写方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class TestService extends Service { @Override public void onCreate() { super.onCreate(); }
@Override public void onDestroy() { super.onDestroy(); }
@Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); }
@Override public IBinder onBind(Intent arg0) { return null; } }
|
onCreate
:在 Service 被创建时调用,由系统调用
onDestroy
:在 Service 被销毁时调用,由系统调用
onStartCommand
:在 Service启动时调用,在该方法中定义任务
onBind
:返回 IBinder 对象,app 通过 IBinder 对象与 Service 通信
onStartCommand
方法的返回值决定了系统如何处理该 Service
START_STICKY
:若系统杀死 Service 后会重新创建,但不能接收 intent
START_NOT_STICKY
:系统杀死 Service 后不会重新创建
START_REDELIVER_INTENT
:系统杀死 Service 后会重新创建,能够接收 intent
注册 Service
在 AndroidManifest.xml
中注册
1 2 3 4 5 6
| <service android:name=".TestService" android:enabled="true"> <intent-filter> <action android:name="com.example.service.TEST_SERVICE"/> </intent-filter> </service>
|
启动和停止 Service
相关方法
startService
:启动一个 Service
bindService
:绑定一个 Service
stopService
:停止一个 Service
几种不同的启动方式,Service 内部方法的执行顺序不同
-
调用 startService()
启动
依次调用 onCreate()
、onStartCommand()
,若多次调用 startService()
,则复用创建的 Service 对象,重新调用 onStartCommand()
通过这种方式启动 Service,Service 的生命周期独立于 app,只能调用 stopService()
来停止
-
调用 bindService()
启动
依次调用 onCreate()
、onBind()
,若多次调用 bindService()
,则复用创建的 Service 对象,不会重新调用 onBind()
,直接将 IBinder 对象返回给调用端,用于与调用端通信
调用 unbindService()
解除绑定,会调用 Service 的 onUnbind()
,当不存在绑定时,调用 onDestroy()
通过这种方式启动 Service,Service 的生命周期与调用端绑定,当调用端销毁,Service 也停止
-
启动后绑定
先调用 startService()
启动服务,再调用 bindService()
绑定
Service 内部触发的方法依次是 onCreate()
,onStartCommand()
,onBind()
,onUnbind()
,onRebind()
通过这种方式启动 Service,Service 的生命周期独立,通过 onBind()
返回的 IBinder 与 app 通信,调用 onUnbind
时也不会停止,可以反复绑定
ServiceConnection 对象:bindService()
的参数,可用于监听 app 与 Service 的连接情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class MyServiceConnection extends ServiceConnection { @Override public void onServiceDisconnected(ComponentName name) { System.out.println("------Service DisConnected-------"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("------Service Connected-------"); binder = (MyBinder) service; } }
|
Activity 与 Service 通信
将 Activity 与 Service 进行绑定,使 Activity 可以调用 Service 中的方法
- 在
MyService
类中定义 MyBinder
类,继承 Binder
类,在该类中提供执行的方法
- 在
MyService
类中创建 MyBinder
类的实例,在 onBind()
中返回该对象
- 在
MainActivity
中创建 ServiceConnection
实现类对象,重写方法
- 通过 Intent 将 Activity 与 Service 绑定,调用
bindService()
,传入 intent 和 connection 对象和值 Service.BIND_AUTO_CREATE
,表示绑定后自动创建 Service,其中会执行 MyService 的 onCreate()
,不执行 onStartCommand()
MyService
实现 Service
类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| public class TestService extends Service { private final String TAG = "TestService"; private int count; private boolean quit; private MyBinder binder = new MyBinder(); public class MyBinder extends Binder { public int getCount() { return count; } } @Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind方法被调用!"); return binder; } @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate方法被调用!"); new Thread() { public void run() { while(!quit) { try { Thread.sleep(1000); } catch(InterruptedException e) { e.printStackTrace(); } count++; } }; }.start(); } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "onUnbind方法被调用!"); return true; } @Override public void onDestroy() { super.onDestroy(); this.quit = true; Log.i(TAG, "onDestroyed方法被调用!"); } @Override public void onRebind(Intent intent) { Log.i(TAG, "onRebind方法被调用!"); super.onRebind(intent); } }
|
在 Activity 中使用 Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class MainActivity extends Activity { MyBinder binder; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { System.out.println("------Service DisConnected-------"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("------Service Connected-------"); binder = (TestService2.MyBinder) service; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent intent = new Intent(); intent.setAction("com.example.service.TEST_SERVICE"); btnbind.setOnClickListener(v -> { bindService(intent, conn, Service.BIND_AUTO_CREATE); }); btncancel.setOnClickListener(v -> { unbindService(conn); }); btnstatus.setOnClickListener(v- > { int count = binder.getCount() }); } }
|
IntentService
使用 Service 进行耗时操作时,容易引发 ANR,这是由于 Service 不会创建线程,它与 app 处于同一个进程中
使用 IntentService 可以解决该问题,IntentService 中存在一个任务队列,将请求的 Intent 放入队列中,在后台线程进行处理
继承 IntentService
类实现相应方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| public class TestService extends IntentService { private final String TAG = "hehe"; public TestService() { super("TestService"); } @Override protected void onHandleIntent(Intent intent) { String action = intent.getExtras().getString("param"); if(action.equals("s1")) { Log.i(TAG,"启动service1"); } else if (action.equals("s2")) { Log.i(TAG,"启动service2"); } else if (action.equals("s3")) { Log.i(TAG,"启动service3"); } try { Thread.sleep(2000); } catch(InterruptedException e) { e.printStackTrace(); } } @Override public IBinder onBind(Intent intent) { Log.i(TAG,"onBind"); return super.onBind(intent); } @Override public void onCreate() { Log.i(TAG,"onCreate"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG,"onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void setIntentRedelivery(boolean enabled) { super.setIntentRedelivery(enabled); Log.i(TAG,"setIntentRedelivery"); } @Override public void onDestroy() { Log.i(TAG,"onDestroy"); super.onDestroy(); } }
|