彻底明白Android中AIDL及其使用

1、为什么要有AIDL?

无论学什么东西,最先得弄明白为什么要有这个东西,不要说存在即是合理,存在肯定合理,但是你还是没有明白。对于AIDL有一些人的浅显概念就是,AIDL可以跨进程访问其他应用程序,和其他应用程序通讯,那我告诉你,很多技术都可以访问,如广播(应用A在AndroidManifest.xml中注册指定Action的广播)应用B发送指定Action的广播,A就能收到信息,这样也能看成不同应用之间完成了通讯(但是这种通讯是单向的);还如ContentProvider,通过URI接口暴露数据给其他应用访问;但是这种都算不上是应用之间的通讯。可能最让人迷惑的是Android推出来了Messager,它就是完成应用之间的通讯的。那么为什么还要有AIDL呢,官方文档介绍AIDL中有这么一句话:

Note: Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL.

第一句最重要,“只有当你允许来自不同的客户端访问你的服务并且需要处理多线程问题时你才必须使用AIDL”,其他情况下你都可以选择其他方法,如使用Messager,也能跨进程通讯。可见AIDL是处理多线程、多客户端并发访问的。而Messager是单线程处理。还是官方文档说的明白,一句话就可以理解为什么要有AIDL。那么是不是这样的写个AIDL试试。

2、AIDL使用

第一、定义AIDL文件

// IRemoteService.aidl
package com.example.android;

// Declare any non-default types here with import statements

/** Example service interface */
interface IRemoteService {
    /** Request the process ID of this service, to do evil things with it. */
    int getPid();

    /** Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

这段代码也是官方文档的。命名为IRemoteService.aidl,放在com.example.android包下(这个可以随意),保存后Android编译器会在gen目录下自动生成IRemoteService.java文件

第二、定义我们的服务,DDService.java,并且需要在AndroidManifest.xml中注册,并添加“duanqing.test.aidl” 的ACTION

package com.example.service;

import com.example.android.IRemoteService;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Process;

public class DDService extends Service {
	@Override
	public void onCreate() {
		super.onCreate();
		System.out.println("DDService onCreate........" + "Thread: " + Thread.currentThread().getName());
	}
	@Override
	public IBinder onBind(Intent arg0) {
		System.out.println("DDService onBind");
		return mBinder;
	}

	private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
	    public int getPid(){
	    	System.out.println("Thread: " + Thread.currentThread().getName());
	    	System.out.println("DDService getPid ");
	        return Process.myPid();
	    }
	    public void basicTypes(int anInt, long aLong, boolean aBoolean,
	        float aFloat, double aDouble, String aString) {
	    	System.out.println("Thread: " + Thread.currentThread().getName());
	    	System.out.println("basicTypes aDouble: " + aDouble +" anInt: " + anInt+" aBoolean " + aBoolean+" aString " + aString);
	    }
	};

}

这样我们的服务端就完成了,把服务端运行到模拟器(或者手机上),等一会可以看一下打印信息,重点看“线程名”

第三、实现客户端测试代码

新建另一个工程,同样需要添加AIDL协议文件(这是一个标准的协议文件,定义对外服务),这里我列出来我的测试代码:

package com.example.aidlclient;

import android.app.Activity;
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.Process;
import android.os.RemoteException;
import android.view.View;

import com.example.android.IRemoteService;

public class MainActivity extends Activity {
	private IRemoteService remoteService;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			remoteService =	IRemoteService.Stub.asInterface(service);
			try {
				int pid = remoteService.getPid();
				int currentPid = Process.myPid();
				System.out.println("currentPID: " + currentPid +"  remotePID: " + pid);
				remoteService.basicTypes(12, 1223, true, 12.2f, 12.3, "我们的爱,我明白");
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			System.out.println("bind success! " + remoteService.toString());
		}
	};

    /**
     * 监听按钮点击
     * @param view
     */
    public void buttonClick(View view) {
    	System.out.println("begin bindService");
    	Intent intent = new Intent("duanqing.test.aidl");
    	bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	unbindService(conn);
    }
}

4、执行

点击客户端按钮,执行,看打印信息:

看服务端打印,DDService onCreate..........Thread: main,主线程,当客户端调用服务端getPid方法时,服务端是在Thread: Binder2中执行,当客户端调用服务端basicType方法时,服务端是在Thread:Binder1中执行

彻底明白Android中AIDL及其使用,布布扣,bubuko.com

时间: 2024-10-10 15:44:27

彻底明白Android中AIDL及其使用的相关文章

Android技术22:Android中AIDL

在Android中进程内部通过全局变量,文件,preference,数据库作为数据的载体实现数据共享和通信.然后在进程之间则需要借助Binder实现IPC调用.Android进程通信框架:服务端,客户端,Linux binder驱动.Binder驱动成为连接两端的桥梁.我们首先通过aidl语言实现一个简单的多进程通信.具体实现步骤如下: 1.定义aidl文件 IService.aidl,定义一个接口,test() ,不包含负责的类和数据. 1 package com.demo.ipc; 2 3

Android中AIDL实现进程通信(附源码下载)

AIDL概述 之前的博客<Android中通过Messenger与Service实现进程间双向通信>演示了如何通过Messenger实现与Service进行跨进程通信,即IPC.但用Messenger实现的IPC存在一点不足:Service内部维护着一个Messenger,Messenger内部又维护着一个Hanlder,当多个client向该Service发送Message时,这些Message需要依次进入Hanlder的消息队列中,Hanlder只能处理完一个Message之后,再从消息队

Android 中AIDL的使用与理解

AIDL的使用: 最常见的aidl的使用就是Service的跨进程通信了,那么我们就写一个Activity和Service的跨进程通信吧. 首先,我们就在AS里面新建一个aidl文件(ps:现在AS建aidl不要求和java包名相同了): package aidl; interface IMyInterface { String getInfor(String s); } 可以看到,在这里面我们就一个方法getInfor(String s),接受一个字符串参数,然后返回一个字符串,恩,相当的简单

Android中AIDL详解

欢迎转载,转载请注明出处http://blog.csdn.net/l664675249/article/details/50649676 介绍 Android Interface Definition Language (AIDL), Android接口定义语言.系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信Interprocess communication (IPC).AIDL就是解决这个问题的. 阅读本文需要了解Service的相关知识,关于Service的

Android 中 AIDL 的理解与使用

1.跨应用启动Service 设置启动Service的Intent serviceIntent = new Intent(); serviceIntent.setComponent(new ComponentName("com.example.startservicefromanotherapp", "com.example.startservicefromanotherapp.AppService")); com.example.startservicefroma

彻底明确Android中AIDL及其使用

1.为什么要有AIDL? 不管学什么东西,最先得弄明确为什么要有这个东西.不要说存在即是合理.存在肯定合理,可是你还是没有明确. 对于AIDL有一些人的浅显概念就是,AIDL能够跨进程訪问其它应用程序,和其它应用程序通讯,那我告诉你.非常多技术都能够訪问,如广播(应用A在AndroidManifest.xml中注冊指定Action的广播)应用B发送指定Action的广播,A就能收到信息,这样也能看成不同应用之间完毕了通讯(可是这样的通讯是单向的).还如ContentProvider,通过URI接

入门篇:10.Android中AIDL(安卓接口定义语言)跨应用操作Service

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

Android中AIDL通信机制分析

一.背景 ·1.AIDL出现的原因 在android系统中,每一个程序都是运行在自己的进程中,进程之间无法进行通讯,为了在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界.通过代码来实现这个数据传输过程是冗长乏味的,Android提供了AIDL工具来处理这项工作,实现IPC(进行间的通信)与J2e中的RMI类似. ·2.绑定service 我看了很多人都博客都没有说到这里,其实我个人感觉AIDL就是一个

Android中AIDL的使用

AIDL(Android接口定义语言)---------------------------------AIDL用于定义跨进程通信时需要使用到的接口,即当多个应用程序都需要使用到相关的接口时,应该使用AIDL来定义.[使用AIDL定义接口的步骤]1. 使用一般的创建interface的方式创建Java接口文件2. 将创建的interface的权限删掉,即例如public interface IMusicPlayer修改为interface IMusicPlayer3. 打开Windows的资源管