Android中的AIDL Android studio中建aidl

1.aidl: android interface definition language,是一种它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口
icp:interprocess communication :内部进程通信

2.既然aidl可以定义并实现进程通信,那么我们怎么使用它呢?文档/android-sdk/docs/guide/developing/tools/aidl.html中对步骤作了详细描述:

--1.Create your .aidl file - This file defines an interface (YourInterface.aidl) that defines the methods and fields available to a client. 
创建你的aidl文件,我在后面给出了一个例子,它的aidl文件定义如下:写法跟java代码类似,但是这里有一点值得注意的就是它可以引用其它aidl文件中定义的接口,但是不能够引用你的java类文件中定义的接口

[java] view plain copy

  1. package com.cao.android.demos.binder.aidl;
  2. import com.cao.android.demos.binder.aidl.AIDLActivity;
  3. interface AIDLService {
  4. void registerTestCall(AIDLActivity cb);
  5. void invokCallBack();
  6. }

Android studio中建aidl

先在main目录下新建一个文件夹,命名为aidl,再在该目录下新建一个包,包名跟AndroidManifest中的package同名,然后在该包下创建aidl文件,创建完之后在build/generated/source/aidl/debug下就可以见到自动生成的java文件

作者:卓学腾
链接:http://www.zhihu.com/question/21581761/answer/45895797
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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>

时间: 2024-10-06 01:30:20

Android中的AIDL Android studio中建aidl的相关文章

Android中的跨进程调用技术AIDL

什么是AIDL Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信. 为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现. 与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口. Android的四大组件中的三个(Activity.Broadcast

android: android 中的Matrix (android.graphics.Matrix) (转)

本篇博客主要讲解一下如何处理对一个Bitmap对象进行处理,包括:缩放.旋转.位移.倾斜等.在最后将以一个简单的Demo来演示图片特效的变换. 1. Matrix概述 对于一个图片变换的处理,需要Matrix类的支持,它位于"android.graphics.Matrix"包下,是Android提供的一个3*3 矩阵工具类: 它本身不能对图像或View进行变换,但它可与其他API结合来控制图形.View的变换,如Canvas.Matrix提供了一些方法来控制图片变换: setTrans

Android中开发工具Android Studio修改created用户(windows环境)

最近经常有朋友反馈说我的安卓项目中,在一些类中会出现Created by panchengjia on 2016/12/30的字样,是如何自动实现的(默认一般为Administrator),如下图: 实现上图这种效果,仅仅修改控制面板中的用户账户名是没有用的. 下面我简单介绍下windows环境下的实现方式: (1)进入本地组策略编辑器 可以通过快捷键windows键+R打开运行窗口或者直接点开始菜单选运行,输入gpedit.msc (2)修改管理员账户名 进入本地组策略编辑器后,后续操作如下图

Android的IPC机制(一)——AIDL的使用

综述 IPC(interprocess communication)是指进程间通信,也就是在两个进程间进行数据交互.不同的操作系统都有他们自己的一套IPC机制.例如在Linux操作系统中可以通过管道.信号量.消息队列.内存共享.套接字等进行进程间通信.那么在Android系统中我们可以通过Binder来进行进程间的通信.当然除了Binder我们还可以使用Socket来进行进程间的通信.  既然需要进程通信,那么就必须有多个进程.当然,在两个应用交互中必然出现多进程的情况.若是在一个应用中呢?我们

Android中的系统服务(代理模式)

一,系统启动 Android设备的开机流程总得来分可以分为三部分: 加载引导程序 引导程序bootloader是开机运行的第一个小程序,因此它是针对特定的主板与芯片的.bootloader有很多种,可以使用比较流行的如redboot.uboot.ARMBoot等,也可以开发自己的引导程序,它不是Android操作系统的一部分.引导程序也是OEM厂商或者运营商加锁和限制的地方. 引导程序初始化硬件设备.创建存储器空间的映射等软件运行时所需要的最小环境:加载Linux内核镜像文件(本文只针对Andr

Android中Handler引起的内存泄露

在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. 但是,其实上面的代码可能导致内存泄露,当你使用Android lint工具的话,会得到这样的警告 In Android, Handler classes should be static or leaks might occur, Messages enqueued on the application thread’s MessageQueue also retain their t

Android中使用Handler引发的内存泄露

转载请注明出处:http://blog.csdn.net/allen315410/article/details/43638373 本文翻译自:国外某位开发者的博客How to Leak a Context: Handlers & Inner Classes,英文可以的朋友可以直接点击原文查看. 在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. public class SampleActivity extends Activity

在android中读写文件

在android中读写文件 android中只有一个盘,正斜杠/代表根目录. 我们常见的SDK的位置为:/mnt/sdcard 两种最常见的数据存储方式: 一.内存 二.本地 1.手机内部存储 2.外部存储设备(SD卡) 在SD卡中读数据是不需要权限的,但是在SD卡中写数据是要权限的: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 读写文件的方式就是用的Java的文件

Android中的Audio播放:控制Audio输出通道切换

Audio 输出通道有很多,Speaker.headset.bluetooth A2DP等.通话或播放音乐等使用Audio输出过程中,可能发生Audio输出通道的切换.比如,插入有线耳机播放音乐时,声音是从耳机发出的:而此时拔出耳机,Audio输出通道会发生切换.如果音乐播放器不做处理,Audio输出是被切换到扬声器的,声音直接从Speaker发出.我们在编写程序时,要捕获并按照需求来处理这样的事,本文就是讲解如何处理的. Android中可以通过android.media.AudioManag