Service

Service组件

  1. Android的进程
  2. service的启动与停止
  3. service生命周期
  4. Android的服务的调用
  5. IntentService
  6. 服务与线程
  7. 其他
01-Android的进程
  1. Foreground Process
    • 拥有一个处于Resumed状态的Activity的进程
  2. Visisable Process
    • 拥有一个处于Paused状态的Activity的进程.
  3. Service Process
    • 拥有一个通过startService方法启动起来的进程.
  4. Background Process
    • 拥有一个通过startService方法启动起来的进程.
  5. 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生命周期

service_lifecycle

  1. startService方式
    1. onCreate()
      • 第一次启动的时候,启动后就不会在调用
    2. onStartCommand()
      • 每次startService的时候就会被调用一次
    3. onDestroy()
      • 调用stopService()的时候调用一次
  2. bindService方式
    1. onCreate()
    2. onBind()
      • 当此时Activity绑定Service后,Activity销毁了,Service也会调用以下的方法,并抛出异常
    3. onUnbind()
    4. onDestory()
    5. 特点:
      • 目的就是调用服务中方法
      • 第一次调用bindService时,会执行onCreate和onbind方法,第二执行时,服务没有响应
      • 服务不能够多次解绑,多次解绑回报异常
      • 当onBind方法返回null 时,onServiceconnected()方法是不执行的
      • bind方式的服务….调用者与service之间的关系,当调用者消亡时,service也必须消亡
      • 通过bind方式开启的额服务在设置中不能找到,相当于开启一个隐形的服务
  3. 混用方式:服务既可以在后台中运行,也可以调用服务中方法
    1.startService+bindService+unBindService+stopService

    - onCreate
    - onStartCommand
    - onBind
    - onUnbind
    - 此时当调用stopService的时候才会onDestroy.
    

    service_binding_tree_lifecycle

04. Android的服务的调用

实现: 获得IBinder代理对象,作为与服务通信之间的桥梁

  1. 继承Binder类
    在本应用内使用并且不需要实现跨进程工作
    1. 普通方式实现
      • 在服务内部定义一个方法,让Activity(调用者)去调用的方法
      • 定义一个代理对象继承Binder类
      • 把定义的代理对象在onBind()方法中返回
      • 在Activity的onCreate()方法中调用bindService()的目的是获得代理对象
      • 在实现ServiceConnection接口的类中的重写方法中获取代理对象
      • 用代理对象调用服务里的方法
      • 当Activity销毁的时候,解绑服务
    2. 已接口的方式去实现
      • 定义一个接口,把要服务中需要暴露的方法定义在借口里面
      • 让代理对象实现定义的借口
      • 在调用者中获取该代理对象

- 代码实现

//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();
}
  1. AIDL 专门用来解决Android 中实现进程间通信IPC的方式,该方式可以进行跨进程通信,比如挂断电话
    1. 本地服务:运行在自己应用中的服务
    2. 远程服务:运行在其他应用中的服务
    3. 实现进程间的通信(IPC)
    4. 使用步骤
      • 把服务中要暴露的方法定义在接口中
      • 把接口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();
    } 
  }
}
  1. 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. 其他
  1. Android中的四大组件都是运行在主线程中的,
  2. 服务是在后台运行,没有界面的Activity
  3. 当服务启动后,即使杀死进程,服务也不会死亡,还会自动启动该进程 而广播接收者是,即使程序退出,只有接收到了广播,就会启动该程序
  4. 在其他组件中不能够直接调用服务里的方法
  5. 服务只能自己stop或者是在running中stop
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值