AIDL简单实例

本文介绍了如何通过Android Interface Definition Language (AIDL)实现在Android应用程序间的进程间通信(IPC)。文章详细解释了三个主要步骤:定义AIDL接口、实现远程服务的存根以及将远程服务提供给本地客户端。

 

每一个应用程序都有自己的进程,进程之间不能互相访问,这叫做应用程序沙漏(application sandboxing
为了能用使应用程序能互相访问,Android提供IPC(interprocess communication protocol
IPC protocol因为需要整理封装(marshaling/un marshaling数据)而变得复杂。
因此.Android提供 AIDL(Android Interface Definition Language),它对使用了类似于java的语法,对IPC轻量级实现,并有AIDL工具自动实现stub的创建
实现步骤:
1.定义 the AIDL interface
2.为remote service实现Stub
3.将remote service提供给本地 local client

第一步:定义 the AIDL interface

package com.marakana;// 定义接口
]AIDLinterface IAdditionService {    // 可传递标记in, out, or inout.     // Primitive 类型 (例如 int, boolean, etc.) 仅能而其默认是in.   
int add(in int value1, in int value2);}

 

第二步:为remote service实现Stub

/**
* 这个类实现了remote service 到 Local client 本地
*/
public class AdditionService extends Service {
  private static final String TAG = "AdditionService";
  
  @Override
  public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate()");
  }
  
  //返回remote 对象

  @Override
  public IBinder onBind(Intent intent) {

    return new IAdditionService.Stub() {
      /**
       * Implementation of the add() method
       */
      public int add(int value1, int value2) throws RemoteException {
        Log.d(TAG, String.format("AdditionService.add(%d, %d)",value1, value2));
        return value1 + value2;
      }

    };
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy()");
  }
}

 
第三步:将remote service提供给本地 local client
利用servcie实现onBind(),就可以连接到remote service

public class AIDLDemo extends Activity {
  private static final String TAG = "AIDLDemo";
  IAdditionService service;
  AdditionServiceConnection connection;

  /**
   * 这个类实现了真实的remote service的连接.它将IBinder类型的对象,也就是Stub的实现类
   * 转为 AIDL 接口.    asInterface方法是aild工具产生的比较重要的方法
   */
  class AdditionServiceConnection implements ServiceConnection {

    public void onServiceConnected(ComponentName name, IBinder boundService) {
       service = IAdditionService.Stub.asInterface((IBinder) boundService);
      Log.d(AIDLDemo.TAG, "onServiceConnected() connected");
      Toast.makeText(AIDLDemo.this, "Service connected", Toast.LENGTH_LONG)
          .show();
    }

    public void onServiceDisconnected(ComponentName name) {
      service = null;
      Log.d(AIDLDemo.TAG, "onServiceDisconnected() disconnected");
      Toast.makeText(AIDLDemo.this, "Service connected", Toast.LENGTH_LONG)
          .show();
    }
  }

  /** 将Activity绑定到Service. */
  private void initService() {
    connection = new AdditionServiceConnection();
    Intent i = new Intent();
    i.setClassName("com.marakana", com.marakana.AdditionService.class.getName());
    boolean ret = bindService(i, connection, Context.BIND_AUTO_CREATE);
    Log.d(TAG, "initService() bound with " + ret);
  }

  /** 解除绑定. */
  private void releaseService() {
    unbindService(connection);
    connection = null;
    Log.d(TAG, "releaseService() unbound.");
  }

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    initService();

    // Setup the UI
    Button buttonCalc = (Button) findViewById(R.id.buttonCalc);

    buttonCalc.setOnClickListener(new OnClickListener() {
      TextView result = (TextView) findViewById(R.id.result);
      EditText value1 = (EditText) findViewById(R.id.value1);
      EditText value2 = (EditText) findViewById(R.id.value2);

      public void onClick(View v) {
        int v1, v2, res = -1;
        v1 = Integer.parseInt(value1.getText().toString());
        v2 = Integer.parseInt(value2.getText().toString());

        try {
          res = service.add(v1, v2);
        } catch (RemoteException e) {
          Log.d(AIDLDemo.TAG, "onClick failed with: " + e);
          e.printStackTrace();
        }
        result.setText(new Integer(res).toString());
      }
    });
  }

  /** Called when the activity is about to be destroyed. */
  @Override
  protected void onDestroy() {
    releaseService();
  }

}

   
资源来源:http://marakana.com/forums/android/examples/48.html

源代码:    http://marakana.com/static/tutorials/AIDLDemo.zip

 

 

 

 

基于51单片机,实现对直流电机的调速、测速以及正反转控制。项目包含完整的仿真文件、源程序、原理图和PCB设计文件,适合学习和实践51单片机在电机控制方面的应用。 功能特点 调速控制:通过按键调整PWM占空比,实现电机的速度调节。 测速功能:采用霍尔传感器非接触式测速,实时显示电机转速。 正反转控制:通过按键切换电机的正转和反转状态。 LCD显示:使用LCD1602液晶显示屏,显示当前的转速和PWM占空比。 硬件组成 主控制器:STC89C51/52单片机(与AT89S51/52、AT89C51/52通用)。 测速传感器:霍尔传感器,用于非接触式测速。 显示模块:LCD1602液晶显示屏,显示转速和占空比。 电机驱动:采用双H桥电路,控制电机的正反转和调速。 软件设计 编程语言:C语言。 开发环境:Keil uVision。 仿真工具:Proteus。 使用说明 液晶屏显示: 第一行显示电机转速(单位:转/分)。 第二行显示PWM占空比(0~100%)。 按键功能: 1键:加速键,短按占空比加1,长按连续加。 2键:减速键,短按占空比减1,长按连续减。 3键:反转切换键,按下后电机反转。 4键:正转切换键,按下后电机正转。 5键:开始暂停键,按一下开始,再按一下暂停。 注意事项 磁铁和霍尔元件的距离应保持在2mm左右,过近可能会在电机转动时碰到霍尔元件,过远则可能导致霍尔元件无法检测到磁铁。 资源文件 仿真文件:Proteus仿真文件,用于模拟电机控制系统的运行。 源程序:Keil uVision项目文件,包含完整的C语言源代码。 原理图:电路设计原理图,详细展示了各模块的连接方式。 PCB设计:PCB布局文件,可用于实际电路板的制作。
### AIDL 简单使用示例 AIDLAndroid Interface Definition Language)是一种用于定义远程过程调用接口的语言,主要用于实现跨进程通信(IPC)。以下是 AIDL 的一个简单使用示例: #### 1. 创建 AIDL 文件 首先,在 Android 项目中创建一个 `.aidl` 文件。例如,创建一个名为 `ICalculation.aidl` 的文件,定义一个简单的加法操作接口。 ```aidl // ICalculation.aidl package com.example.aidlsimpleexample; interface ICalculation { int add(int a, int b); } ``` #### 2. 实现 AIDL 接口 在服务端实现上述 AIDL 接口。需要继承 `ICalculation.Stub` 并重写其中的方法。 ```java // CalculationService.java package com.example.aidlsimpleexample; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class CalculationService extends Service { @Override public IBinder onBind(Intent intent) { return new ICalculation.Stub() { @Override public int add(int a, int b) throws RemoteException { return a + b; } }; } } ``` #### 3. 注册服务 在 `AndroidManifest.xml` 中注册该服务。 ```xml <service android:name=".CalculationService"> <intent-filter> <action android:name="com.example.aidlsimpleexample.CalculationService" /> </intent-filter> </service> ``` #### 4. 客户端绑定服务 客户端通过 `bindService` 方法绑定到服务端,并获取 `IBinder` 实例以调用远程方法。 ```java // MainActivity.java (客户端) package com.example.aidlsimpleexample; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private ICalculation iCalculation; private final ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iCalculation = ICalculation.Stub.asInterface(service); try { int result = iCalculation.add(5, 3); System.out.println("Result: " + result); // 输出结果 } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { iCalculation = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.aidlsimpleexample", "com.example.aidlsimpleexample.CalculationService")); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection); } } ``` 上述代码展示了如何通过 AIDL 实现简单的跨进程通信[^1]。服务端提供了一个 `add` 方法,客户端可以通过绑定服务调用该方法[^5]。 --- ### 注意事项 - 确保客户端和服务端的 AIDL 文件内容一致,否则可能导致序列化失败[^2]。 - 在 `AndroidManifest.xml` 中正确注册服务[^4]。 - 如果需要传递复杂对象(如自定义类),必须实现 `Parcelable` 接口[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值