美文网首页
Android笔记之Service

Android笔记之Service

作者: 卖梦想的男孩 | 来源:发表于2017-03-01 17:22 被阅读29次

    相对于应用的界面,Service则是一个看不见的后台。
    一个正常的Service需要满足:

    • 依附的上下文(必选)
      通常是继承自Service,开发者只关心自己需要实现的效果
    • 清单的声明(必选)
      需要在AndroidManifest.xml中告诉系统存在某个Service。
    • 细节的过滤(可选)
      可以设置IntentFilter来过滤哪些命令才是Service自己关心的。

    Service的正常使用

    启动Servie

    public ComponentName startService(Intent service)
    

    停止Service

    public boolean stopService(Intent name)
    //Service中可以调用stopSelf来停止
    

    生命周期
    onCreate
    onStartCommand //多次启动会回调这个方法
    onDestroy

    Service的绑定使用

    绑定Service

    public boolean bindService(Intent service, ServiceConnection conn,int flags) 
    

    BindServiceFlags:

    • BIND_AUTO_CREATE //只要绑定存在,系统就会自动启动相应的Service
    • BIND_DEBUG_UNBIND //调试时方便打印绑定的信息
    • BIND_NOT_FOREGROUND //不允许绑定到前台进程
    • BIND_ABOVE_CLIENT //如果app被杀,系统尽可能的保留绑定
    • BIND_ALLOW_OOM_MANAGEMENT//低内存下尽可能保留绑定
    • BIND_WAIVE_PRIORITY//使绑定像后台进程一样被管理
    • BIND_IMPORTANT//当客户端是前台进程时,提高其等到同前台进程
    • BIND_ADJUST_WITH_ACTIVITY//忽略其他标志,不管其绑定的Activity是否对用户可见,都相应的提高其权重。

    解绑Service

    public void unbindService(ServiceConnection conn)
    

    生命周期
    onCreate
    onBind
    onUnbind
    onDestroy

    public interface ServiceConnection {
        //当连接到Service时
        public void onServiceConnected(ComponentName name, IBinder service);
      //当连接的Service宿主出现崩溃或者被杀掉时
        public void onServiceDisconnected(ComponentName name);
    }
    

    注:

    • onCreate只有在Service不存在的时候才会调用
    • 如果是通过bindService启动的,调用unbindService会触发销毁,否则只会触发onUnbind,onDestroy则是谁启动的谁关闭,因为系统要确保这个服务最终已经无人使用了。
    • 绑定的上下文销毁时Service也会跟着销毁。

    IntentService

    IntentService本质上是对Service的扩展
    优势:

    • 为了异步消息处理
    • 处理消息后自动停止服务
    protected void onHandleIntent(final Intent intent)
    

    开发者只需要关心自己的异步实现就可以了。

    AIDL

    Android接口定义语言(Android Interface Definition Language)
    用来实现跨进程的通讯

    跨进程方式 对比
    BrodcastReceiver 实现简单但跨进程比较耗时
    Messenger 请求队列是同步进行的,无法并发执行
    AIDL 书写稍微麻烦,但是借助工具可以简化,相对Messenger更灵活

    如果是其他进程提供服务的Service,记得配置Manifest的时候导出

    android:process=""//指定进程
    android:exported="true"//向外暴露
    

    数据类型

    • 基本类型
    • Java中的八种基本数据类型,包括 byte,short,int,long,float,double,boolean,char。
    • String 类型。
    • CharSequence类型。
    • List/Map (元素是其他基本类型或parcelable)
    • Parcelable
      需要写一份对象的aidl,但是只是做声明即可
    package xxxPackage;
    parcelable xxxClass;
    

    有个bug,可能是不同版本的问题,我这个版本生成的类会调用readFromParcel,而Parcelable已经去掉了该方法,所以对象类中自己手动写了个。

    数据流向
    adil中非基本参数都需要指明数据流向,不管是 in , out , 还是 inout 。基本参数的定向tag默认是并且只能是 in

    • in 服务端只读该参数,不做修改
    • out 服务端只对该参数进行修改,不读取传进来的参数
    • inout 服务端先读取参数,再对其做修改
      可以查看生成的源码,当然其实这个也好理解,上面的基本类型是无法对其地址上的数据做修改的(类似深浅拷贝问题),一般情况下指定in/out即可,没必要做无谓的开销。

    总结:其实adil可以看做的bindService的强化版,只需要做以下几步。

    1. 需要用到自定义的实体,就申明一个实体的aidl,然后写好相应的实体。
    2. 定义adil接口的方法,如果引用到自定义的类型,就导入相应的类并指定数据流向。
    3. 在服务端书写Binder继承接口的Stub
    4. bindService后,在ServiceConnection中获取Binder的实例即可。

    相关文章

      网友评论

          本文标题:Android笔记之Service

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