zoukankan      html  css  js  c++  java
  • android中的AIDL进程间通信

    关于IPC应该不用多介绍了,Android系统中的进程之间不能共享内存,那么如果两个不同的应用程序之间需要通讯怎么办呢?比如公司的一个项目要更新,产品的需求是依附于当前项目开发一个插件,但是呢这个插件功能以及界面比较复杂,不能和当前项目在一个进程中,同时呢,还要用到当前项目中已经写好了的一些东西,那么因为新开发的依附于当前项目的插件和当前项目不是一个进程,因此不能共享内存,就出现了问题,于是,需要提供一些机制在不同进程之间进行数据通信,这个机制就是AIDL了。

    一、一个android中AIDL的简单例子

      假如是这样,现在有一个项目中提供了比较成熟的计算的方法,而现在我想开发一款软件其中一个模块想用到一个计算类,而我又不想重新写了,那么就可以通过AIDL实现啦。假设,已经开发完成的那个已经提供了比较成熟的计算类的程序叫AIDLCalculateDemoServer(相当于服务器),而我要写的程序叫AIDLCalculateDemoClient(相当于客户端),类似与客户端服务器模式。首先至关的看下工程结构图:

                                   

                 图1-1 服务器                   图1-2 客户端 

      现在假设自己写的程序要调用服务端的运算界面,输入num1和num2,进行远程运算,调用服务端的接口,服务端运算好之后,返回结果给客户端,效果图如下:

              

      然后来看看实现,首先需要定义AIDL接口,客户端和服务器端都要定义,并且要在同一包中,也就是图1-1和图1-2 com.example.aidl.calculate中的CalculateInterface,其中的代码如下:

    1 package com.example.aidl.calculate;
    2 
    3 interface CalculateInterface {
    4     double doCalculate(double a, double b);
    5 }

      编译发现,目录结构如图1-1和图1-2中gen/com.example.aidl.calculate中多了CalculateInterface.java文件,内容如下:

    1 package com.example.aidl.calculate;
    2 
    3 interface CalculateInterface {
    4     double doCalculate(double a, double b);
    5 }

      定义好接口就是要看服务端和客户端的代码啦,其中服务端主要看CalculateService代码,这个一个继承Service的类,在其中对AIDL中的接口进行赋予实际意义,如下:

    复制代码
     1 package com.example.calculate;
     2 
     3 import com.example.aidl.calculate.CalculateInterface;
     4 import com.example.aidl.calculate.CalculateInterface.Stub;
     5 
     6 import android.app.Service;
     7 import android.content.Intent;
     8 import android.os.IBinder;
     9 import android.os.RemoteException;
    10 import android.util.Log;
    11 
    12 public class CalculateService extends Service {
    13     
    14     private static final String                            TAG                        =    "CalculateService";
    15     
    16     @Override
    17     public IBinder onBind(Intent arg0) {
    18         // TODO Auto-generated method stub
    19         logE("onBind()");
    20         return mBinder;
    21     }
    22     
    23     @Override
    24     public void onCreate() {
    25         // TODO Auto-generated method stub
    26         logE("onCreate()");
    27         super.onCreate();
    28     }
    29     
    30     @Override
    31     public void onStart(Intent intent, int startId) {
    32         // TODO Auto-generated method stub
    33         logE("onStart()");
    34         super.onStart(intent, startId);
    35     }
    36     
    37     @Override
    38     public boolean onUnbind(Intent intent) {
    39         // TODO Auto-generated method stub
    40         logE("onUnbind()");
    41         return super.onUnbind(intent);
    42     }
    43     
    44     @Override
    45     public void onDestroy() {
    46         // TODO Auto-generated method stub
    47         logE("onDestroy()");
    48         super.onDestroy();
    49     }
    50     
    51     private static void logE(String str) {
    52         Log.e(TAG, "--------" + str + "--------");
    53     }
    54     
    55     private final CalculateInterface.Stub mBinder = new CalculateInterface.Stub() {
    56         
    57         @Override
    58         public double doCalculate(double a, double b) throws RemoteException {
    59             // TODO Auto-generated method stub
    60             Log.e("Calculate", "远程计算中");
    61             Calculate calculate = new Calculate();
    62             double answer = calculate.calculateSum(a, b);
    63             return answer;
    64         }
    65     };
    66 }
    复制代码

      然后可以看看,关键的服务都提供完毕,那么在客户端是怎么访问的呢,要进行绑定服务和一个ServiceConnection类完成,如下:

    复制代码
     1 package com.example.calculate;
     2 
     3 import android.app.Activity;
     4 import android.content.ComponentName;
     5 import android.content.Context;
     6 import android.content.Intent;
     7 import android.content.ServiceConnection;
     8 import android.graphics.Color;
     9 import android.os.Bundle;
    10 import android.os.IBinder;
    11 import android.os.RemoteException;
    12 import android.util.Log;
    13 import android.view.View;
    14 import android.widget.Button;
    15 import android.widget.EditText;
    16 import android.widget.TextView;
    17 
    18 import com.example.aidl.calculate.CalculateInterface;
    19 import com.example.aidlcalculatedemoclient.R;
    20 
    21 public class CalculateClient extends Activity {
    22     private static final String                 TAG                        =            "CalculateClient";
    23     
    24     private              Button                 btnCalculate;
    25     
    26     private              EditText                etNum1;
    27     
    28     private                 EditText                etNum2;
    29     
    30     private              TextView                tvResult;
    31     
    32     private               CalculateInterface      mService;
    33     
    34     private              ServiceConnection        mServiceConnection = new ServiceConnection() {
    35         
    36         @Override
    37         public void onServiceDisconnected(ComponentName name) {
    38             // TODO Auto-generated method stub
    39             logE("disconnect service");
    40             mService = null;
    41         }
    42         
    43         @Override
    44         public void onServiceConnected(ComponentName name, IBinder service) {
    45             // TODO Auto-generated method stub
    46             logE("connect service");
    47             mService = CalculateInterface.Stub.asInterface(service);
    48         }
    49     };
    50     
    51     @Override
    52     protected void onCreate(Bundle savedInstanceState) {
    53         // TODO Auto-generated method stub
    54         super.onCreate(savedInstanceState);
    55         setContentView(R.layout.main);
    56         
    57         Bundle args = new Bundle();
    58         Intent intent = new Intent("com.example.calculate.CalculateService");
    59         intent.putExtras(args);
    60         bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    61         
    62         etNum1 = (EditText) findViewById(R.id.et_num_one);
    63         etNum2 = (EditText) findViewById(R.id.et_num_two);
    64         
    65         tvResult = (TextView) findViewById(R.id.tv_result);
    66         
    67         btnCalculate = (Button) findViewById(R.id.btn_cal);
    68         
    69         btnCalculate.setOnClickListener(new View.OnClickListener() {
    70             
    71             @Override
    72             public void onClick(View v) {
    73                 // TODO Auto-generated method stub
    74                 
    75                 logE("开始远程运算");
    76                 try {
    77                     double num1 = Double.parseDouble(etNum1.getText().toString());
    78                     double num2 = Double.parseDouble(etNum2.getText().toString());
    79                     String answer = "计算结果:" + mService.doCalculate(num1, num2);
    80                     tvResult.setTextColor(Color.BLUE);
    81                     tvResult.setText(answer);
    82                             
    83                 } catch (RemoteException e) {
    84                 }
    85             }
    86         });
    87     }
    88     
    89     private void logE(String str) {
    90         Log.e(TAG, "--------" + str + "--------");
    91     }
    92 }
    复制代码

      如此一来,大功已经基本告成,最后,我们在来看看服务端的配置文件吧:

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.aidlcaculatedemoserver"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.aidlcaculatedemoserver.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <service android:name="com.example.calculate.CalculateService">
                <intent-filter>
                    <action android:name="com.example.calculate.CalculateService" />
                </intent-filter>
            </service>
        </application>
    
    </manifest>
    复制代码

    二、写AIDL注意事项

    1. 客户端和服务端的AIDL接口文件所在的包必须相同

    2. 需要一个Service类的配合

    http://www.cnblogs.com/BeyondAnyTime/p/3204119.html

  • 相关阅读:
    windows使用pipenv创建虚拟环境报错UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 4: in...
    mysql监控工具sqlprofiler,类似sqlserver的profiler工具安装(一)
    [转]linux awk命令详解
    navicat for mysql 如何设置字段唯一
    linux硬链接与软链接
    linux后台运行和关闭、查看后台任务
    测试覆盖率的基本策略
    【Unity Shader】二、顶点函数(vertex)和片元函数(fragment)传递数据,及各阶段可使用的语义(semantic)
    【Unity Shader】一、顶点函数(vertex)和片元函数(fragment)
    Unity Shader学习资料
  • 原文地址:https://www.cnblogs.com/cmblogs/p/4962552.html
Copyright © 2011-2022 走看看