Android 操作系统之 Activity 与 Service

作者: 程序老秃子 | 来源:发表于2022-10-14 15:31 被阅读0次

    Activity 与 Service 是否处于同一进程?

    一般来说:同一个包内的 activity 和 service,如果 service 没有设定属性 android:process=":remote" 的话,service 会和 activity 跑在同一个进程中,由于一个进程只有一个 UI 线程,所以,service 和 acitivity 就是在同一个线程里面的

    android:process=":remote" 值得注意他的用法!!!如果Activity 想访问 service 中的对象或方法,service 设定属性 android:process=":remote",那么就是跨进程访问,跨进程访问容易出现意想不到的问题,还是慎重给 service 设定属性 android:process=":remote"

    Service 的两大功能是什么?怎样实现?

    Service 主要有两个作用:

    • 后台运行
    • 跨进程通讯
    情况1:

    当 Acitivity 和 Service 处于同一个 Application 和进程时,通过继承 Binder 类来实现

    步骤如下:

    • Service 和 Activity 的连接;可以用 ServiceConnection 来实现,需要实现一个新的 ServiceConnection,重写 onServiceConnected 和 onServiceDisconnected 方法
    • 执行绑定,调用bindService方法,传入一个选择了要绑定的 Service 的 Intent(显式或隐式)和一个你实现了的 ServiceConnection 实例
    • 一旦连接建立,你就能通 Service 的接口 onBind() 得到 serviceBinder 实例进而得到 Service 的实例引用
    • 一旦 Service 对象找到,就能得到它的公共方法和属性;但这种方式,一定要在同一个进程和同一个 Application 里
    情况2:

    跨进程通讯,使用 AIDL

    步骤如下:

    • 在 Eclipse 工程的 package 目录中;建立一个扩展名为 aidl 的文件;package 目录就是 Java 类所在的目录;该文件的语法类似于 Java 代码。aidl 文件中定义的是 AIDL 服务的接口;这个接口需要在调用 AIDL 服务的程序中访问
    • 如果 aidl 文件的内容是正确的,Eclipse 插件会自动生成一个Java接口文件(*.java)
    • 建立一个服务类(Service 的子类)
    • 实现由 aidl 文件生成的 Java 接口
    • 在 AndroidManifest.xml 文件中配置 AIDL 服务,尤其要注意的是,<action> 标签的 android:name 属性值就是客户端要引用该服务的 ID,也就是 Intent 类构造方法的参数值

    当 acitivity 和 service 处于同一个 application 和进程时,通过继承 binder 类来实现

    当一个 activity 绑定到一个 service 上时,它负责维护 service 实例的引用,允许你对正在运行的 service 进行一些方法调用;比如你后台有一个播放背景音乐的 service,这时就可以用这种方式来进行通信

    代码如下:

    • service 代码
    public class localservice extends service {
    
    private final ibinder binder = new localbinder();
    
    public class localbinder extends binder {
    
    localservice getservice() {
    
    return localservice.this;
    
    }
    
    } public ibinder onbind(intent intent) {
    
    return binder;
    
    }
    
    }
    
    • activity 代码
    public class bindingactivity extends activity {
    localservice localservice;
    
    private serviceconnection mconnection = new serviceconnection() {
    
    public void onserviceconnected(componentname classname,ibinder localbinder) { localservice = (localbinder) localbinder.getservice();
    
    }
    
    public void onservicedisconnected(componentname arg0) {
    
    localservice = null;
    
    }
    
    };
    
    protected void onstart() {
    
    super.onstart();
    
    intent intent = new intent(this, localservice.class);
    
    bindservice(intent, mconnection, context.bind_auto_create);
    
    }
    
    protected void onstop() {
    
    super.onstop();
    
    unbindservice(mconnection);
    
    }
    
    public void printrandomnumber{
    
    int num = localservice.getrandomnumber();
    
    system.out.println(num);
    
    }
    
    }
    

    代码解释:

    使用使用 context.bindservice() 启动 service 会经历:

    context.bindservice()->oncreate()->onbind()->service running
    
    onunbind() -> ondestroy() ->service stop
    

    该如何检验 activity 和 service 是否是在同一个进程中运行

    一般情况下,activity 和 service 在同一个包名内,并且没有设定属性 android:process=":remote",两者在同一个进程中

    因为一个进程只有一个 ui 线程,所以两者就在同一个线程里

    如果设置 android:process=":remote",就属于跨进程访问,就属于不同的进程了

    验证方法:

    在 activiyt 和 service 的 oncreate 中打印进程的信息

    如:

    log.i("tag",thread.curentthread().getid());
    

    尾述

    有需要文中完整代码的小伙伴:可以点击此处获取底层源码 现在点击还可 免费获取一份 Android 高级开发系统化学习笔记

    感谢阅读,希望这篇文章能够帮助到大家,觉得内容不错的话,可以点赞分享一下;谢谢大家的支持!

    相关文章

      网友评论

        本文标题:Android 操作系统之 Activity 与 Service

        本文链接:https://www.haomeiwen.com/subject/nahczrtx.html