Service组件
- Android的进程
- service的启动与停止
- service生命周期
- Android的服务的调用
- IntentService
- 服务与线程
- 其他
01-Android的进程
- Foreground Process
- 拥有一个处于Resumed状态的Activity的进程
- Visisable Process
- 拥有一个处于Paused状态的Activity的进程.
- Service Process
- 拥有一个通过startService方法启动起来的进程.
- Background Process
- 拥有一个通过startService方法启动起来的进程.
- Empty Progcess
- 不拥有任何正在运行的四大组件.当系统需要内存就杀死了,目的是为了缓存,下次启动就很快.牺牲空间换时间.
02. service的启动与停止
//Service的启动
Intent service = new Intent();
//也分为显示和隐式意图启动
service.setClass(this, MyService.class);
startService(service);
//Service的停止
//Service的停止,需要通过调用stopService方法停止.或者在设置中手动的停止
Intent service = new Intent();
service.setClass(this, MyService.class);
stopService(service);
03. service生命周期
- startService方式
- onCreate()
- 第一次启动的时候,启动后就不会在调用
- onStartCommand()
- 每次startService的时候就会被调用一次
- onDestroy()
- 调用stopService()的时候调用一次
- onCreate()
- bindService方式
- onCreate()
- onBind()
- 当此时Activity绑定Service后,Activity销毁了,Service也会调用以下的方法,并抛出异常
- onUnbind()
- onDestory()
- 特点:
- 目的就是调用服务中方法
- 第一次调用bindService时,会执行onCreate和onbind方法,第二执行时,服务没有响应
- 服务不能够多次解绑,多次解绑回报异常
- 当onBind方法返回null 时,onServiceconnected()方法是不执行的
- bind方式的服务….调用者与service之间的关系,当调用者消亡时,service也必须消亡
- 通过bind方式开启的额服务在设置中不能找到,相当于开启一个隐形的服务
混用方式:服务既可以在后台中运行,也可以调用服务中方法
1.startService+bindService+unBindService+stopService- onCreate - onStartCommand - onBind - onUnbind - 此时当调用stopService的时候才会onDestroy.
04. Android的服务的调用
实现: 获得IBinder代理对象,作为与服务通信之间的桥梁
- 继承Binder类
在本应用内使用并且不需要实现跨进程工作
- 普通方式实现
- 在服务内部定义一个方法,让Activity(调用者)去调用的方法
- 定义一个代理对象继承Binder类
- 把定义的代理对象在onBind()方法中返回
- 在Activity的onCreate()方法中调用bindService()的目的是获得代理对象
- 在实现ServiceConnection接口的类中的重写方法中获取代理对象
- 用代理对象调用服务里的方法
- 当Activity销毁的时候,解绑服务
- 已接口的方式去实现
- 定义一个接口,把要服务中需要暴露的方法定义在借口里面
- 让代理对象实现定义的借口
- 在调用者中获取该代理对象
- 普通方式实现
- 代码实现
//Service端
public class DemoService extends Service {
//把我定义的中间人对象返回
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
//办证的方法
public void banZheng(int money){
if (money>1000) {
Toast.makeText(getApplicationContext(), "我是领导 把证给你办了", 1).show();
}else {
Toast.makeText(getApplicationContext(), "这点钱 还想办事....", 1).show();
}
}
//打麻将的方法
public void playMaJiang(){
System.out.println("陪领导打麻将");
}
//洗桑拿的方法
public void 洗桑拿(){
System.out.println("陪领导洗桑拿");
}
//[1]定义中间人对象(IBinder)
private class MyBinder extends Binder implements Iservice{
public void callBanZheng(int money){
//调用办证的方法
banZheng(money);
}
public void callPlayMaJiang(){
//调用playMaJiang 的方法
playMaJiang();
}
}
}
//调用者
public class MainActivity extends Activity {
private MyConn conn;
private Iservice myBinder;//我定义的中间人对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this,DemoService.class);
//连接服务
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
//点击按钮调用服务里面办证的方法
public void click(View v) {
myBinder.callBanZheng(10000000);
// myBinder.callPlayMaJiang();
// myBinder.callXiSangNa();
}
//监视服务的状态
private class MyConn implements ServiceConnection{
//当服务连接成功调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取中间人对象,此时已经提升为接口类型,而不是代理人类型
myBinder = (Iservice) service;
}
//失去连接
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onDestroy() {
//当activity 销毁的时候 解绑服务
unbindService(conn);
super.onDestroy();
}
}
//暴露的接口interface
public interface Iservice {
//把想暴露的方法都定义在接口里
public void callBanZheng(int money);
//public void callPlayMaJiang();
}
- AIDL 专门用来解决Android 中实现进程间通信IPC的方式,该方式可以进行跨进程通信,比如挂断电话
- 本地服务:运行在自己应用中的服务
- 远程服务:运行在其他应用中的服务
- 实现进程间的通信(IPC)
- 使用步骤
- 把服务中要暴露的方法定义在接口中
- 把接口Iservice.java变成一个aidl文件,去掉权限修饰符public
- 系统自动生成一个Iservice.java,其中有一个Stub类
- 让代理对象直接继承该Stub 类
- 保证两个应用中的是同一个aidl文件,保证他们的包名相同
- 获取中间人的对象
- iservice = Stub.asInterface(service);
//aili文件
interface Iservice {
//把想暴露的方法定义在接口里面
void callMethodService();
}
//本地服务
public class MainActivity extends Activity {
private MyConn conn;
private Iservice iservice;//中间人对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]调用bindservcie 获取中间人对象
Intent intent = new Intent();
intent.setAction("com.itheima.remoteservice");
conn = new MyConn();
//[2]连接服务 目的为了获取我们定义的中间人对象
bindService(intent, conn, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
//点击按钮调用第九个应用 服务里面的方法
public void click(View v) {
try {
iservice.callMethodService();
} catch (RemoteException e) {
e.printStackTrace();
}
}
//监视服务的状态
private class MyConn implements ServiceConnection{
//连接成功
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取中间人对象 注意这里面在获取 中间人对象的方式变了 和之前不一样
iservice = Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
//远程服务
public class RemoteService extends Service {
//把我们定义的中间人对象返回
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
//定义一个方法
public void methodService(){
System.out.println("我是远程服务里面的方法");
}
//[1]定义一个中间人对象(IBinder)
private class MyBinder extends Stub{
@Override
public void callMethodService() {
//调用方法
methodService();
}
}
}
- Using Messenger,参见Android文件,可以用于Activity与Service之间相互发消息
05. IntentService
概念:里面有一个方法在线程中执行,因此可以进行耗时操作当子线程执行完后,该IntentService会自己结束
//该服务的启动
startService(new Intent(this, MyIntentService.class));
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start(View view){
startService(new Intent(this, MyIntentService.class));
}
}
//
public class MyIntentService extends IntentService {
//参数:子线程的名称
private MyIntentService(String name) {
super(name);
}
//必须声明一个空参的构造函数,否则系统无法创建这个对象
public MyIntentService(){
this("MySubThread");
}
//在子线程中执行的,因此可以阻塞.
//当这个方法执行完了,IntentService就会自杀
@Override
protected void onHandleIntent(Intent intent) {
Log.d("tag", "ThreadName="+Thread.currentThread().getName());
Log.d("tag", "开始执行任务");
SystemClock.sleep(10000);
Log.d("tag", "任务执行完了");
}
@Override
public void onCreate() {
super.onCreate();
Log.d("tag", "onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("tag", "onDestroy");
}
}
//服务的注册
<service android:name="com.example.intentservice.MyIntentService"/>
06. 服务与线程
参间Android文档
07. 其他
- Android中的四大组件都是运行在主线程中的,
- 服务是在后台运行,没有界面的Activity
- 当服务启动后,即使杀死进程,服务也不会死亡,还会自动启动该进程 而广播接收者是,即使程序退出,只有接收到了广播,就会启动该程序
- 在其他组件中不能够直接调用服务里的方法
- 服务只能自己stop或者是在running中stop