一. Service:
Service主要有两个应用场景:后台运行和跨进程访问。
Service可以在后台执行长时间运行操作而不提供用户界面。
Service可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。
需要注意的是,Service是在主线程里执行操作的,可能会因为执行耗时操作而导致ANR。
如果要执行耗时操作,需要单独在Service中新开一个子线程,来执行耗时操作。
1.1 Service的创建:
右键-New-Service-Service(注意:不是IntentService)
image.png
通过这种方式创建之后,就会被自动注册到manifest.xml中。
image.png
如果想要手动建一个则需要建一个类,并集成Service即可。
image.png
1.2 Service的启动
startService() 启动服务
服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响。 已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。
Log.i(TAG, "点击进行startService服务通信");
Intent intent = new Intent(this, MyService.class);
Bundle bundle = new Bundle();
bundle.putSerializable(INTENT_KEY1,TIME_THRAED_1);
intent.putExtras(bundle);
startService(intent);
1.3 Service的绑定
bindService() 绑定到服务
服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。多个组件可以同时绑定服务,服务只会在组件与其绑定时运行,一旦该服务与所有组件之间的绑定全部取消,系统便会销毁它。
1.4 Service的绑定和启动
Service既可以是启动服务,也允许绑定。
此时需要同时实现以下回调方法:onStartCommand()和 onBind()。
系统不会在所有客户端都取消绑定时销毁服务。
为此,必须通过调用 stopSelf() 或 stopService() 显式停止服务
1. 5 启动/绑定之后的Service的生命周期测试:
public class MyService extends Service {
private int mStartMode; // 表示服务被 kill 之后的行为
private IBinder mBinder; // 表示绑定该服务的客户端
private boolean mAllowReind; // 表示是否允许重新绑定
@Override public void onCreate() {
// 服务被创建
super.onCreate();
}
@Nullable @Override public IBinder onBind(Intent intent) {
// 客户端通过 bindService() 方法绑定服务
return mBinder;
}
@Override public int onStartCommand(Intent intent, int flags, int startId) {
// 组件调用 startService() 方法启动服务
return mStartMode;
}
@Override public boolean onUnbind(Intent intent) {
// 所有绑定的客户端都已调用 unbindService() 方法解绑
return mAllowReind;
}
@Override public void onRebind(Intent intent) {
// 客户端在onUnbind() 方法回调之后,调用 bindService() 方法绑定服务
super.onRebind(intent);
}
@Override public void onDestroy() {
// 服务不再被使用并被销毁
super.onDestroy();
}
}
左边为StartService / 右边为BindService
二. IntentService:
Service存在的两个问题:
1.Service中的代码都是默认运行在主线程当中的,不会单独启动一条新线程,所以如果在服务中处理一些耗时任务,会产生ANR。
2.Service不会专门启动一个进程,而是与它所在的应用位于同一个进程
3.不能同时处理多个请求
对于第1点,我们可以使用多线程编程,在服务的onStartCommand方法或是BindService类的onCreate方法中中开启一个子线程去处理耗时任务,如果想要线程的任务执行完就停止服务,可以在run()的最后(任务处理完成后)调用stopSelf(),而IntentService就直接为我们创建了子线程执行耗时任务,处理异步请求的时候不需要自己去开启新的线程,可以减少写代码的工作量。
IntentService与Service不同在于:
1.IntentService创建默认的工作线程,用于在应用的主线程外执行传递给 onStartCommand() 的所有 Intent。
2.创建工作队列,用于将 Intent 逐一传递给 onHandleIntent() 实现,这样就不必担心多线程问题
3.在处理完所有启动请求后停止服务,因此不必自己调用 stopSelf()方法。
4.提供 onBind() 的默认实现(返回 null)
5.提供 onStartCommand() 的默认实现,可将 Intent 依次发送到工作队列和 onHandleIntent()
2.1 IntentService的创建:
与Service的创建同理
但请选择Service(IntentService)即可,会自动帮你继承IntentService。
image.png
通过这种方式创建之后,就会被自动注册到manifest.xml中。
image.png
如果想要手动建一个则需要建一个类,并集成IntentService即可。
image.png
IntentService的启动
Intent intent = new Intent(this, IntentService.class);
Bundle bundle = new Bundle();
bundle.putString("key", "当前值:" + i++);
intent.putExtras(bundle);
startService(intent);
具体的Demo:https://github.com/CodeLpea/PracticceOfAndorid.git
本文对应的代码在 Number1文件夹中。
Demo中有注释。
我有什么错误或者需要交流的地方,欢迎留言或者私信哈。
网友评论