• Android 远程Service


    远程Service

    在清单文件中给Service添加属性process 为:remote

    <service  
            android:name="com.example.servicetest.MyService"  
            android:process=":remote" >  
        </service>  

    使用远程Service,MyService将在另一个进程中运行,只会阻塞所在进程中的主线程,不会当前应用程序。

    远程Service会在应用包名加上:remote;

    远程Service的弊端:

    开启多进程时 Application会运行两次 (初始化数据时不妥当 : 需要判断进程名与当前应用的的进程名)

    使用bind方式与Activity建立连接时 程序会崩溃。

    因为Service与Activity 运行在两个不同的进程中 ,不能使用传统的建立连接方式,需要引入AIDL;

    Activity与远程Service 建立关联, 使用AIDL 进行跨进程通信(IPC)

    AIDL(Android Interface Definition Languge) android接口定义语言 

    AIDL的作用: 用于Service与多个应用程序组件之间进行跨进程通信 ,实现多个应用程序共享一个Service的功能

    使用跨进程通信的步骤

    1. 首先新建一个AIDL文件  进行文件MyAIDLService.aidl文件

    package com.example.service.remote;
    
    interface MyAIDLService
    {
        int plus(int a, int b);  
        String toUpperCase(String str);  
    
    }

    //保存后,gen目录下会生产一个对应的java文件 ;

      //编写Aidl文件时,需要注意下面几点:

    
    

      1.接口名和aidl文件名相同。

    
    

      2.接口和方法前不用加访问权限修饰符public,private,protected等,也不能用final,static。

    
    

      3.Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、 CharSequence),使用这些类型时不需要import声明。对于List和Map中的元素类型必须是Aidl支持的类型。如果使用自定义类型作 为参数或返回值,自定义类型必须实现Parcelable接口。

    
    

      4.自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。

    
    

      5.在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数。

    
    

      6.Java原始类型默认的标记为in,不能为其它标记。

     

    2、然后修改MyService中的代码   实现刚定义好的MyAIDLService接口  并且在onBInd中返回对象

       @Override  
        public IBinder onBind(Intent intent) {  
            return mBinder;  
        }  
      
        MyAIDLService.Stub mBinder = new Stub() {  
      
            @Override  
            public String toUpperCase(String str) throws RemoteException {  
                if (str != null) {  
                    return str.toUpperCase();  
                }  
                return null;  
            }  
      
            @Override  
            public int plus(int a, int b) throws RemoteException {  
                return a + b;  
            }  
        };  

    // Stub是Binderd的子类

    3、在MainActivity中写实现代码

      private MyAIDLService myAIDLService;  
      
          //创建 ServiceConnection对象 并实现MyAIDLeService中的方法
    private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) {
            // 获取MyAIDLService对象 myAIDLService
    = MyAIDLService.Stub.asInterface(service); try { int result = myAIDLService.plus(3, 5); String upperStr = myAIDLService.toUpperCase("hello world"); Log.d("TAG", "result is " + result); Log.d("TAG", "upperStr is " + upperStr); } catch (RemoteException e) { e.printStackTrace(); } } };

    4.在其他应用程序中调用MyService的方法  

    4.1、在清单文件中给MyService 添加隐式Intent; 用于其他应用程序调用

    <service android:name="com.example.service.remote.MyService"
                     android:process=":remote"
                >
                <intent-filter>
                    <action android:name="com.example.service.remote.MyService.MyAIDLService"></action>
                </intent-filter>
                
            </service>
    //MyService可以响应这个action的Intent

    4.2.然后在一个新的项目中,把MyAIDLService.aidl文件拷贝过来(要将原有的包路径一起拷贝过来)

    4.3 然后在MainActivity中  加入MyService建立关联的代码

      private MyAIDLService myAIDLService;  
      
          //创建 ServiceConnection对象    并实现MyAIDLeService中的方法
        private ServiceConnection connection = new ServiceConnection() {  
      
            @Override  
            public void onServiceDisconnected(ComponentName name) {  
            }  
      
            @Override  
            public void onServiceConnected(ComponentName name, IBinder service) {  
            // 获取MyAIDLService对象
                myAIDLService = MyAIDLService.Stub.asInterface(service);  
                try {  
                    int result = myAIDLService.plus(3, 5);  
                    String upperStr = myAIDLService.toUpperCase("hello world");  
                    Log.d("TAG", "result is " + result);  
                    Log.d("TAG", "upperStr is " + upperStr);  
                } catch (RemoteException e) {  
                    e.printStackTrace();  
                }  
            }  
        };  

    4.4 bindService  通过隐式意图

    case R.id.btn_bind:
                Intent intent1 = new Intent("com.example.service.remote.MyService.MyAIDLService");
                bindService(intent1, conn , BIND_AUTO_CREATE);
                break;

    实现不同应用程序跨进程通信功能。

  • 相关阅读:
    bjdctf_2020_router
    Windows下Apache配置https
    Linux定时备份数据库并删除N天以前的数据
    MySQL出现Waiting for table metadata lock的原因以及解决方法
    MySQL操作(五)查询实例
    Windows常用命令
    PHPSTORM常用快捷键
    MySQL操作(四)索引及优化
    MySQL操作(三)数据表
    MySQL操作(二)数据库
  • 原文地址:https://www.cnblogs.com/pbq-dream/p/5394287.html
Copyright © 2020-2023  润新知