Android AIDL -通过一个比较完整的Demo快速运用

android AIDL使用demo Android 接口定义语言 (AIDL) 类似于其他 IDL:它允许您定义客户端和服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口 阅读详情

前端时间项目运用到AIDL,关于AIDL客户端以及AIDL服务端网络上没有一个比较完备的Demo.

而参考Demo无疑是一个比较快速的学习方法.因此,我写了一个Demo.

供大家参考,也非常欢迎大家对其中写的不好的地方进行指正.

 

好了,首先简述下基本功能:

在AIDL 客户端三个EditText中输入三个值,点击提交按钮,将这三个值传入到AIDL服务端进行处理.

服务端处理后会执行客户端的回调函数:在AIDL客户端界面进行刷新,并显示一个toast.

 

接下来看看代码结构:

 

需要注意的是,两个工程中com.harlan.demo.aidl包内部的文件必须保持一致.

 

(1)HarlanInfo.java:这是包中唯一的一个java文件,是一个数据结构,该类实现了Parcelable接口

package com.harlan.demo.aidl;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * 
 * <一句话功能简述>
 * Parcelable是Android特有的功能,效率比实现Serializable接口高
 * 
 * @author  Administrator
 * @version  [版本号, 2012-12-10]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class HarlanInfo implements Parcelable
{
    private String name;
    
    private int age;
    
    private String place;

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public String getPlace()
    {
        return place;
    }

    public void setPlace(String place)
    {
        this.place = place;
    }
    
    /**
     * <默认构造函数>
     */
    public HarlanInfo()
    {
        
    }
    
    /**
     * <默认构造函数>
     */
    public HarlanInfo(Parcel in)
    {
        //注意顺序
         name = in.readString();
        age = in.readInt();
        place = in.readString();
    }
    
    /**
     * seems meaningless
     * return 0;
     */
    @Override
    public int describeContents()
    {
        return 0;
    }

    /**
     * 将对象序列化为一个Parcel对象
     *  可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,
     *  再通过createFromParcel从流里读取对象
     *  注意:写的顺序和读的顺序必须一致。 
     */
    @Override
    public void writeToParcel(Parcel dest, int flags)
    {
        dest.writeString(name);
        dest.writeInt(age);
        dest.writeString(place);
    }
    
    /**
     * 实例化静态内部对象CREATOR实现接口Parcelable.Creator
     * public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写
     */
    public static final Parcelable.Creator<HarlanInfo> CREATOR = new Creator<HarlanInfo>(){

      //将Parcel对象反序列化为HarlanInfo   
        @Override
        public HarlanInfo createFromParcel(Parcel source)
        {
            HarlanInfo hlInfo = new HarlanInfo(source);
            return hlInfo;
        }

        @Override
        public HarlanInfo[] newArray(int size)
        {
            return new HarlanInfo[size];
        }
        
    };
    
}

 

(2)HarlanInfo.aidl :协同HarlanInfo.java文件"作战",缺一不可.

package com.harlan.demo.aidl;

parcelable HarlanInfo;

 

(3)ICallBack.aidl:
这是客户端回调方法的接口,在客户端实现其具体方法,在服务端调用执行.

package com.harlan.demo.aidl;
interface ICallBack{
	/**
	*callback of AIDLClient
	*handle by server
	**/
	void handleByServer(String param);
}

 

(4)ExecuteService.aidl:

这是从服务端获取数据方法的接口,在服务端实现其具体方法,在客户端调用执行.

参数info是由用户输入的数据构成的,同时传递的还要客户端回调方法的句柄,从而服务端可以调用客户端的回调方法.

该方法返回一个HarlanInfo的数据类型,客户端获得此数据,在界面上进行相应的显示.

package com.harlan.demo.aidl;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;
interface ExecuteServiceAIDL
{
	/**
	 *get info from server and 
	 *Transfer a callback methods handle;
	 *if occur error ,will be return null
	 *对于非基本数据类型和String和CharSequence类型,要加上方向指示
	 *包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。
     */
	HarlanInfo getServerHarlanInfo(in HarlanInfo info,ICallBack icallback);
}


好了,现在对com.harlan.demo.aidl包已经大致了解,build一下project,发现gen文件夹下面多出来一个包:


 包中文件可以随便看看,不看也没事.因为你只要在客户端服务端相应的位置实现对应的接口就可以了.

先来看看服务端,因为服务端相对简单些,不需要界面什么的,只是一个Service.

上代码:

package com.harlan.demo.service;

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

import com.harlan.demo.aidl.ExecuteServiceAIDL;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;

public class AIDLService extends Service
{
    public static final String TAG = "AIDLService";
    
    private ICallBack mCallBack;
    
    /**
     * 绑定服务
     */
    @Override
    public IBinder onBind(Intent intent)
    {
        // TODO Auto-generated method stub
        return mBinder;
    }
    
    /**
     * 创建服务
     */
    @Override
    public void onCreate()
    {
        super.onCreate();
    }

    /**
     * 销毁服务
     */
    @Override
    public void onDestroy()
    {
        super.onDestroy();
    }

    /**
     * 启动服务
     */
    @Override
    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
    }

    /**
     * 解绑服务
     */
    @Override
    public boolean onUnbind(Intent intent)
    {
        mCallBack = null;
        return super.onUnbind(intent);
    }
    
    ExecuteServiceAIDL.Stub mBinder = new ExecuteServiceAIDL.Stub()
    {
       //这里实现了getServiceHarlanInfo接口
        @Override
        public HarlanInfo getServerHarlanInfo(HarlanInfo info, ICallBack icallback)
            throws RemoteException
        {
            Log.d(TAG,"getServerHarlanInfo");
            mCallBack = icallback;
            mCallBack.handleByServer("The msg is from server");
            HarlanInfo newInfo = new HarlanInfo();
            newInfo.setName(info.getName().toLowerCase());
            newInfo.setAge(info.getAge() + 10);
            newInfo.setPlace("Home");
            return newInfo;
        }
    };
    
}

一目了然,服务端主要的功能就是实现了aidl中的getServerHarlanInfo(HarlanInfo info, ICallBack icallback)接口.返回了一个mBinder供客户端调用.

写好了服务,还得在Manifest文件里面配置一下:

 <service 
            android:name=".AIDLService">
            <intent-filter>
                <action android:name="com.harlan.demo.aidl.service"/>
            </intent-filter>
</service>

 

服务端写好了,就来客户端的了.客户端主要是一个activity,界面相对简单,如图所示:

界面布局相对简单,就不贴代码了.

 

下面贴ClientActivity的代码:

package com.harlan.demo.activity;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.harlan.demo.aidl.ExecuteServiceAIDL;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;

public class ClientActivity extends Activity
{
    public static final String TAG = "ClientActivity";
    
    private static final String BIND_ACTION = "com.harlan.demo.aidl.service";
    
    private EditText mEditTextName;
    
    private EditText mEditTextAge;
    
    private EditText mEditTextPlace;
    
    private Button mButtonCommit;
    
    private ExecuteServiceAIDL executeService;
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);
        getView();
	//用户点击提交按钮,将数据传至服务端进行处理  
     	 mButtonCommit.setOnClickListener(new View.OnClickListener()
        {
            
            @Override
            public void onClick(View v)
            {
	    //绑定服务
                getServiceConnect();             
            }
        });
    }
        
    private void getView()
    {
        mEditTextName = (EditText)findViewById(R.id.editText_name);
        mEditTextAge = (EditText)findViewById(R.id.editText_age);
        mEditTextPlace = (EditText)findViewById(R.id.editText_place);
        mButtonCommit = (Button)findViewById(R.id.button_commit);
    }
    
    private void getServiceConnect()
    {
        Intent it = new Intent();
        it.setAction(BIND_ACTION);
        startService(it);
        bindService(it, mserviceConnection, BIND_AUTO_CREATE);
    }
    
    ServiceConnection mserviceConnection = new ServiceConnection()
    {
        
        @Override
        public void onServiceDisconnected(ComponentName name)
        {
            Log.d(TAG, "onServiceDisconnected");           
        }
        
        @Override
        public void onServiceConnected(ComponentName name, IBinder service)
        {
            Log.d(TAG, "onServiceConnected");
            //获取服务端传过来的IBinder对象,通过该对象调用服务端的方法
              executeService = ExecuteServiceAIDL.Stub.asInterface(service);
            if (executeService != null)
            {
                handlerInfo();
            }
        }
    };
    
    private void handlerInfo()
    {
        String mName;
        int mAge;
        String mPlace;
        if (mEditTextName.getText().toString().equals(""))
        {
            mEditTextName.setText("Harlan");
            mName = "Harlan";
        }
        else
        {
            mName = mEditTextName.getText().toString();
        }
        if (mEditTextAge.getText().toString().equals(""))
        {
            mAge = 22;
        }
        else
        {
            mAge = Integer.parseInt(mEditTextAge.getText().toString());
        }
        if (mEditTextPlace.getText().toString().equals(""))
        {
            mPlace = "Nanjing";
        }
        else
        {
            mPlace = mEditTextPlace.getText().toString();
        }
        HarlanInfo mInfo = new HarlanInfo();
        mInfo.setName(mName);
        mInfo.setAge(mAge);
        mInfo.setPlace(mPlace);
        try
        {
            HarlanInfo serverInfo = new HarlanInfo();
	   //调用服务端的方法
              serverInfo = executeService.getServerHarlanInfo(mInfo, mCallBack);
            //更新界面
              mEditTextName.setText(serverInfo.getName());
            mEditTextAge.setText(String.valueOf(serverInfo.getAge()));
            mEditTextPlace.setText(serverInfo.getPlace());
            unbindService(mserviceConnection);
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
    }
    ICallBack.Stub mCallBack = new ICallBack.Stub()
    {
       //客户端回调方法的具体实现
        @Override
        public void handleByServer(String param)
            throws RemoteException
        {
            Toast.makeText(getApplicationContext(), param, Toast.LENGTH_LONG).show();          
        }
    };
   
}

服务端调用客户端回调方法,在界面上显示一个toast.客户端根据服务端传回来的数据,刷新界面. 

最后运行结果如图所示:

 

 

具体的Demo已经上传至优快云,下载地址:http://download.youkuaiyun.com/detail/singleton1900/4928804

Android AIDL使用(双向callback,传递自定义类型) 一、服务端 结构如下 1.aidl文件如下 // AidlBean.aidl package com.example.aidlservice; // Declare any non-default types here with import statements parcelable AidlBean; // ICallback.aidl package com.example.aidlservice; import com.example.aidlservice.AidlBean; // D. 阅读详情

相关推荐

一个AIDL的安卓demo,建立一个服务端和一个客户端的通信

报告文档 --郭辉 任务描述 了解android service服务,使用AIDL进行交互; 写一个简单的类似于sayhello的demo,做一个客户端和一个服务器端,两个apk,建立起通信,搞清楚通信流程; 使用bundle作为数据传输,从activity传输信息到达service端; 使用markdown写报告文档,并画出时序图,为期两周。 关于android service 什么是se...

w724372012的博客 1863

Android aidl 正确使用 callback的方式

AIDL文件 1.callBack文件: interface ICleanDiskCallBack{ void onComplete(); } 设计的意思是,当一个进程完成清理后,回掉给另外一个进程,好让他做后面的事情。 2.服务aidl import com.xxx.ICleanDiskCallBack; interface IFridgeLauncher { void cleanDisk(ICleanDiskCallBack cb); } 该aidl为Server端实现,设

男儿不展风云志,空有天生八尺躯 4233

基于AIDL实现Binder通信 demo

A demo about Binder and AIDL

qq_59700927的博客 1511

Aidl CallBack

1.aidl进程间通信传递java对象时,对象需要实现Parcelable接口 2.aidl 传递interface 实现callback。 aidl传递interface.java类时编译是会出错的。解决办法是通过aidl实现callback 首先创建aidl文件IService.aidl interface IService { void init(IDemoResul

yxdspirit的专栏 1367

Android中超简单AIDL使用Demo

最近在整理一些碎小的知识点,以前一提到AIDL整个人都不好了,因为不会,所以觉得非常高大上,正是所谓的不明觉厉,闲话少说,AIDL是Android中IPC的一种,本篇文章简单介绍使用AIDL来进行进程间的通信流程,分为客户端和服务端两个方面 1,服务端 服务端首先创建一个service监听客户端的连接请求,然后创建一个AIDL文件,在文件中声明暴露给客户端的接口,最后在service中实现AI...

lplj717的博客 679

Android IPC 之 AIDL 使用

总而言之,成功是留给准备好的人的。无论是参加什么面试,都要做好充足的准备,注意好面试的礼仪和穿着,向面试官表现出自己的热忱与真诚就好。即使最后没有过关,也要做好经验的总结,为下一次面试做好充足准备。这里我为大家准备了一些我在面试后整理的面试专题资料,除了面试题,还总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料分享给大家,希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

2401_84009215的博客 941

Android AIDL -通过一个比较完整的Demo快速运用

Android AIDL -通过一个比较完整的Demo快速运用 分类: Android基础 2012-12-26 10:21 1490人阅读 评论(0) 收藏 举报 aidlAIDLandroidAndroidANDROIDcallbackCallbackIPCipc 前端时间项目运用到AIDL,关于AIDL客户端以及AIDL服务端网络上没有一个比较完备的Demo.

u012547790的专栏 499

Android AIDL异步回调实现

AIDL异步回调实现权限验证定义AIDL服务端Service实现AIDL接口客户端实现AIDL回调接口客户端连接服务端客户端调用AIDL接口服务端回调客户端接口 权限验证 在服务端的AndroidMenifest中定义所需权限 <!-- 声明权限,一般来说,要声明权限的级别,否则在aidl调用时会出现一个bug:先安装client端,后安装service端会导致client端无法......

学无止境 5429

Android aidl 简单小demo学习过程记录(菜鸟详细版,快速上手aidl)

快速上手Android aidl

zhhxlj的博客 2350

Android AIDL全功能Demo:服务端与客户端实现

在Android开发中,AIDL(Android Interface Definition Language)是一种接口定义语言,用于在不同进程间通信(IPC)。通过定义AIDL接口,我们可以创建可以在客户端和服务端之间共享的方法,使得服务端可以向客户端提供特定的功能。接下来的章节将详细介绍AIDL接口的定义过程。AIDL接口定义语法类似于Java,但需要遵循一些特定的规则。AIDL文件的扩展名是.aidl,需要按照特定的语法规则编写。

weixin_31659095的博客 1400

Android项目之AidlDemo(简单aidl的例子)

Android项目之AidlDemo(简单的aidl的例子)。AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写。需要的小伙伴自请下载。

android aidl的使用及demo

demo下载地址 https://download.youkuaiyun.com/download/u010672559/10610856 ---------- 概述:AIDL即跨进程通信  1.在main下面新建aidl文件 // IMyAidlInterface.aidl package com.android.aidl; // Declare any non-default types her...

u010672559的博客 3235

超实用!用 Ollama + DeepSeek + Dify 搭建本地知识库,提升企业效率

本文介绍了如何使用 Ollama + DeepSeek + Dify 搭建本地知识库,帮助企业高效管理信息。通过简单配置,可实现智能问答、文档检索等功能,提升效率并保障数据安全。

Happiness is everywhere 4294

Android AIDL 创建的DEMO

Android 接口定义语言 (AIDL) 与您可能使用过的其他接口语言 (IDL) 类似。您可以利用它定义客户端与服务均认可的编程接口,以便二者使用进程间通信 (IPC) 进行相互通信。在 Android 中,一个进程通常无法访问另一个进程的内存。因此,为进行通信,进程需将其对象分解成可供操作系统理解的原语,并将其编组为可供您操作的对象。编写执行该编组操作的代码较为繁琐,因此 Android 会使用 AIDL 为您处理此问题。

小牧在一直在学习,在前进的道路上大家一起学习,进步。 2156

华为eNSP实战:手把手教你配置DHCP全局地址池(含AP固定IP分配)

本文通过华为eNSP模拟器,详细演示了如何配置DHCP全局地址池,为不同业务VLAN动态分配IP地址,并重点讲解了如何通过MAC地址绑定为接入点(AP)分配固定IP。文章涵盖了从拓扑设计、基础网络搭建到地址池精细配置、验证测试及常见故障排查的全流程,是网络工程师掌握企业级DHCP部署与AP管理的实用指南。

weixin_29235923的博客 598

手把手教你用Arduino和开源电路DIY一个手机连接的电化学传感器(附GitHub源码)

本文详细介绍了如何利用Arduino和开源电路DIY一个手机连接的电化学传感器,成本不到300元即可复现价值数千元的专业设备。从硬件选型、电路搭建到固件开发和手机应用实现,手把手教你完成整个项目,特别适合科研人员、环境监测爱好者和理工科学生。附GitHub源码,方便快速上手和扩展功能。

weixin_42561040的博客 336

Android生成Java AIDL

Android生成Java AIDL

薛文旺 2048

大模型推理中Prefill与Decode、KV Cache三者说明

Prefill 阶段对输入 Prompt 并行编码,一次性构建KV Cache,属于计算密集型任务。Decode 阶段逐 token 迭代生成,复用KV Cache避免重复计算,属于显存带宽密集型任务。KV Cache是自回归推理的核心基石,用显存换时间,实现两阶段衔接与高效生成。PD 分离通过任务解耦、异构硬件、异步调度、独立批处理,解决传统一体化推理的资源冲突与利用率低下问题,是当前云端大模型推理服务的主流工程优化方向。

a486259的博客 1485

Android:AIDL实战详解

这篇博文从实战出发,用一个尽可能精简的Demo,实现两个App(也是两个进程:服务端mainapp、客户端otherapp)通过AIDL的跨进程通信

肖云鹤的博客 1万+

手把手拆解:储能电站如何实现‘孤岛运行’与‘黑启动’?从SVPWM控制到无缝并网

本文深入解析储能电站的孤岛运行与黑启动技术,从SVPWM控制策略到电网重构实战。通过详细的三环控制架构和黑启动五阶段技术路线,展示储能电站在电网故障时如何快速切换为独立电压源并实现电网重建。文章还探讨了虚拟惯量补偿、多站协同控制等前沿技术,为电力系统应急恢复提供关键解决方案。

weixin_30509393的博客 304

hi3519dv500 os04a10输入调试

因该sensor接在soc端的iic6,在驱动中(Hi3519DV500_SDK_V2.0.1.1\smp\a55_linux\source\mpp\cbb\isp\user\sensor\hi3519dv500\omnivision_os04a10\os04a10_sensor_ctl.c)注意总线的选择。mem_process_isolation=1 改为 mem_process_isolation=0。2、OT_MIPI_SET_HS_MODE配置为LANE_DIVIDE_MODE_1。

linus 3165

【Android】AIDL之一个简单的demo

首先,使用 Android 的 AIDL(Android Interface Definition Language) 定义服务接口。文件:IAGM.aidl。

云边有间小卖铺 1334

matinal:SAP 采购中形成的差异

如果库存足够会影响到物料。

matinal 當冬夜漸暖 。公众号:matinal 820

开发AIDL Demo的完整流程(一)

由于本人没有任何安卓开发经验,所以很需要一步一步示范的教程。在ytb上找到了一个教程,基于此解决了Android11以后bindService无法绑定成功、不会回调onServiceConnected的问题,经测试可以在Android12 (Samsung G9910)上跑通 AIDL概述 AIDL是安卓为进程间通讯留下的接口,和其他RPC框架一样,AIDL也包括代理层,协议层和通讯层。代理层是安卓的跨进程通讯机制Binder,协议层是安卓接口定义语言AIDL,代理层除了AIDL自动生成的存根代码之外,.

huiyeruzhou的博客 4023

Unity零基础到入门 ☀️| 轻松学会 Unity界面布局和简单实例——入门级!(^_−)☆

入门级Unity知识,一起加油呀!

努力前行,总会成为自己心中的那道光 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android AIDL运用总结

AIDL是用于跨进程通信的描述语言,由于项目中需要将一个Android定位能力封装到小进程中,稍微研究了一下其实现,这里记录下来,留作后用。 首先,AIDL跨进程通信一般都是一方(进程A)去启动另一方(进程B)的服务(Service),然后由另一方(进程B)去实现一些启动方(进程A)需要的接口(Interface)并回调接口实现,从而使进程A持有一个代理,并以此代理来满足进程A的功能需求,这里面

u013478336的专栏 1470

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: Windows7 下载android源码
下一篇: Android 动态添加自定义式样的按钮
Harlan9001
博客等级 码龄14年 228粉丝 84原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值