• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android IPC 之 AIDL(一)

Android IPC 之 AIDL(一)

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了ipc和aidl,android aidl,android aidl详解,android studio aidl,android aidl实例等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android IPC 之 AIDL(一)


IPC是Inter-Process Communication的缩写,即跨进程通信。Android中跨进程通信有多种方式,如文件共享、使用ContentProvider、Broadcast、和Socket等。比较复杂的情况下,常用的两种方式为Messenger和AIDL,而Messenger的底层实现又是AIDL。

首先不看别的,先来看一下AIDL是如何使用的。

假设我们现在有一个两数相加的任务,客户端没办法完成(别问我它为什么完不成==,咱举栗子简单点哈~),需要将任务交给另一个进程中的服务端完成,再从服务端获取到该任务的结果。

我们首先如下图方式创建一个AIDL接口:

新建文件,选择AIDL

Android Studio会自动为它生成一个路径,如下图:

这里写图片描述

在该文件中声明一个接口以及一个我们想让服务端实现的接口方法。如下:

package com.vera.aidltest;

interface IMyAdd {
   int myAdd(int num_a,int num_b);
}

注意,并不是所有数据类型都能在AIDL文件中使用,AIDL文件只支持以下几种数据类型:

Java 中的基本数据类型 String 和CharSequence List 和 Map ,且List和Map 对象的元素必须是AIDL支持的数据类型 AIDL 自动生成的接口 ,需要导入(import,即使同处于一个包中) 实现android.os.Parcelable 接口的类的对象. 需要导入(import,即使同处于一个包中),且必须新建一个与其同名的AIDL文件,并在文件中声明该类为Parcelable

在接口定义好后,系统将为我们生成一个Java文件,AS下是在app\build\generated\source\aidl\debug目录下,生成的代码如下:

package com.vera.aidltest;
public interface IMyAdd extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.vera.aidltest.IMyAdd
{
private static final java.lang.String DESCRIPTOR = "com.vera.aidltest.IMyAdd";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.vera.aidltest.IMyAdd interface,
 * generating a proxy if needed.
 */
public static com.vera.aidltest.IMyAdd asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.vera.aidltest.IMyAdd))) {
return ((com.vera.aidltest.IMyAdd)iin);
}
return new com.vera.aidltest.IMyAdd.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_myAdd:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.myAdd(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.vera.aidltest.IMyAdd
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public int myAdd(int num_a, int num_b) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(num_a);
_data.writeInt(num_b);
mRemote.transact(Stub.TRANSACTION_myAdd, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_myAdd = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int myAdd(int num_a, int num_b) throws android.os.RemoteException;
}

代码很长很凌乱的样子……嗯,本节我们先不看它,只需要知道它是根据AIDL文件生成的一个接口IMyAdd,包含一个继承自Binder的静态内部抽象类Stub(咦,这么连起来说总有哪里怪怪的……),并且声明了myAdd()方法。为什么是抽象类呢,因为它实现了IMyAdd接口却并没有真正实现,那放到哪里实现呢?当然是我们的服务端咯。

接下来,我们可以就可以来写客户端和服务端的代码了,那么,我们这里的客户端和服务端指的是什么呢?就本例来说,它们分别是一个Activity和一个Service,这里我们将它们放在了同一个应用中,只不过通过某种方法使其运行在不同的进程。更多情况下它们并不运行在同一个应用中,这时候我们需要将整个aidl文件夹的内容复制一份,这是因为客户端和服务端的AIDL包结构需要保持一致,否则将会出现反序列化不成功的结果,那么跨进程通信将无法进行。

那么我们现在开始写服务端的代码,新建一个Service名为ServerService如下:

package com.vera.aidltest;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class ServerService extends Service {

   private Binder mBinder=new IMyAdd.Stub(){
       @Override
       public int myAdd(int num_a, int num_b) throws RemoteException {
           int result=num_a+num_b;
           Log.d("ServerService","the result of "+num_a+" and "+num_b+" is "+result);
           return result;
       }
   };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

ServerService很简单,它只是创建了一个Binder对象并在onBinder()方法中将其返回。该Binder对象就是我们实现了接口方法的Stub对象。好啦,现在我们可以在myAdd()方法中愉快地进行我们的操作啦。在这里我们只是得到num_a和num_b的和并将其打印,最后再返回结果。

另外,我们需要将该Service设置在一个独立的进程中,不然还怎么玩跨进程通信~
更改AndroidManifest.xml如下:


好了,服务端的创建已经完成啦,我们现在来看客户端。客户端要做些什么呢?,我们来看代码:

package com.vera.aidltest;

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 android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class ClientActivity extends AppCompatActivity {

    Button mButton;

    private ServiceConnection myConnection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            IMyAdd mMyAdd=IMyAdd.Stub.asInterface(iBinder);
            try {
                int result=mMyAdd.myAdd(1,2);
                Log.d("ClientActivity","get the result is "+result);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);
        mButton=(Button)findViewById(R.id.activity_client_mbutton);

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(ClientActivity.this,ServerService.class);
                bindService(intent,myConnection, Context.BIND_AUTO_CREATE);
            }
        });
    }
    @Override
    protected void onDes



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android IPC 之 AIDL(一)

相关文章

  • 2017-05-26Android使用静默安装时碰见的问题,android静默
  • 2017-05-26Linux主机网络流量监控ifstat
  • 2017-05-26从视频中每X秒创建一个缩略图
  • 2017-05-26Android常见问题及开发经验总结(三)
  • 2017-05-26安卓--selector简单使用,安卓--selector
  • 2017-05-228.3.1 三个绘图工具类详解
  • 2017-11-18android 自定义View圆圈箭头_
  • 2017-05-26android.view.InflateException: Binary XML file line #34: Error inflating class,
  • 2017-07-22Android深入四大组件(四)广播的注册、发送和接收过程
  • 2017-05-26android动画详解三 动画API概述

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 手机影音7--视频播放器的基本功能(4),7--基本功能
    • 解析View的getDrawingCache方法,getdrawingcache
    • Android,androidstudio
    • HandlerThread,handlerthread用法
    • 自定义的dialog中的EditText无法弹出输入法解决方案,dialogedittext
    • androidj基础:从网上下载图片,
    • ViewPager+GridView实现首页导航栏布局分页效果,viewpagergridview
    • 安卓四大组件之内容提供者,安卓四大提供者
    • android环境下的即时通讯,android即时通讯
    • android Unable toexecute dex: method ID not in [0, 0xffff]: 65536问题

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有