在Android系统中实现AIDL 自定义对象传递

  今天要在《在Android系统中实现AIDL接口回调》这篇文章的基础上实现AIDL自定义对象的传递功能。还是上一篇说到的三个项目:

├── SimpleJar
├── SimpleJarClient
└── SimpleJarService

一、在SimpleJar项目中添加aidl中要传递的对象StudentInfo.aidl跟StudentInfo.java,具体如下:

 ├── Android.mk
└── src
    └── com
        └── china
            └── jar
                ├── IVoiceCallBackInterface.aidl
                ├── IVoiceClientInterface.aidl
                ├── StudentInfo.aidl
                ├── StudentInfo.java
                ├── VoiceChangedListener.java
                └── VoiceManager.java
StudentInfo.aidl跟StudentInfo.java的代码实现如下:

package com.china.jar;
parcelable StudentInfo;
package com.china.jar;

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

public class StudentInfo implements Parcelable{
	String name;
	int age;
	
	protected StudentInfo(Parcel in){
		name = in.readString();
		age = in.readInt();
	}
	
	public StudentInfo(String name, int age) {
		this.name = name;
		this.age = age;
	}
	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;
	}
	@Override
	public int describeContents() {
		return 0;
	}
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeString(name);
		dest.writeInt(age);
	}
	
	public static final Creator<StudentInfo> CREATOR = new Creator<StudentInfo>() {

		@Override
		public StudentInfo createFromParcel(Parcel in) {
			return new StudentInfo(in);
		}

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

 由于是跨进程之间的通信,所以传递对象需要序列化,让StudentInfo实现Parcelable。这样就可以在IVoiceClientInterface.aidl中使用StudentInfo对象进行数据传递了,如下:

package com.china.jar;
import com.china.jar.IVoiceCallBackInterface;
import com.china.jar.StudentInfo;
interface IVoiceClientInterface{
	void face();
	
	void registerCallBack(IVoiceCallBackInterface callback);
	
	void unRegisterCallBack(IVoiceCallBackInterface callback);
	
	void registerUser(in StudentInfo studentInfo);
}

二、在SimpleJarService项目的SimpleService.java类中实现 registerUser(in StudentInfo studentInfo)方法,具体实现如下:

├── AndroidManifest.xml
├── Android.mk
├── libs
│  ├── android-support-v4.jar
│  ├── fw.jar
│  └── simple.jar
├── res
│  ├── drawable-hdpi
│  │  └── ic_launcher.png
│  ├── drawable-ldpi
│  ├── drawable-mdpi
│  │  └── ic_launcher.png
│  ├── drawable-xhdpi
│  │  └── ic_launcher.png
│  ├── layout
│  ├── values
│  │  ├── strings.xml
│  │  └── styles.xml
│  ├── values-v11
│  │  └── styles.xml
│  └── values-v14
│      └── styles.xml
└── src
    └── com
        └── china
            └── service
                ├── BootReceiverBroadcast.java
                ├── Logger.java
                ├── SimpleControl.java
                └── SimpleService.java
 

package com.china.service;

import com.china.jar.IVoiceCallBackInterface;
import com.china.jar.IVoiceClientInterface;
import com.china.jar.StudentInfo;
import com.china.jar.VoiceChangedListener;
import com.china.jar.VoiceManager;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;

public class SimpleService extends Service{
	private static VoiceClientInterfaceImpl mBinder;
	@Override
	public IBinder onBind(Intent intent) {
		Logger.d();
		return mBinder;//跟客户端绑定
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Logger.d();
		if (null == mBinder){
			initService();
		}
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Logger.d();
		if (null == mBinder){
			initService();
		}
		return START_STICKY;
	}
	//实现AIDL的接口
	private class VoiceClientInterfaceImpl extends IVoiceClientInterface.Stub{
		protected RemoteCallbackList<IVoiceCallBackInterface> mRemoteCallbackList = 
				new RemoteCallbackList<IVoiceCallBackInterface>();
		private SimpleControl control;
		
		public VoiceClientInterfaceImpl(){
			control = new SimpleControl(voiceChangedListener);
		}
		
		@Override
		public void face() throws RemoteException {
			Logger.d("face----excute!");//客户端调用face方法时这里会执行,会打印face----excute!
		}
		
		//注册回调
		@Override
		public void registerCallBack(IVoiceCallBackInterface arg0)
				throws RemoteException {
			Logger.d();
			mRemoteCallbackList.register(arg0);
			
		}

		//注销回调
		@Override
		public void unRegisterCallBack(IVoiceCallBackInterface arg0)
				throws RemoteException {
			Logger.d();
			mRemoteCallbackList.unregister(arg0);
		}
		
		//调用回调方法
		private VoiceChangedListener voiceChangedListener = new VoiceChangedListener() {
		
			@Override
			public void openAppByVoice(String arg0) {
				Logger.d("arg0 = " + arg0);
				int len = mRemoteCallbackList.beginBroadcast();
				for (int i = 0; i <len; i++) {
					try {
						mRemoteCallbackList.getBroadcastItem(i).openAppByVoice(arg0);
					} catch (RemoteException e) {
						e.printStackTrace();
					}
				}
				mRemoteCallbackList.finishBroadcast();
			}
		};

		@Override
		public void registerUser(StudentInfo studentInfo) throws RemoteException {
			Logger.d("name = " + studentInfo.getName() + " ,age = " + studentInfo.getAge());
			
		}
	}
	//初始化服务,主要是向系统注册服务
	private void initService(){
		Logger.d();
		if (null == mBinder){
			synchronized (SimpleService.class) {
				if (null == mBinder){
					try {
						mBinder = new VoiceClientInterfaceImpl();
						ServiceManager.addService(VoiceManager.NAME, mBinder);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
}

 registerUser(in StudentInfo studentInfo)方法体中实现非常简单,就是打印学生姓名跟年龄。

三、在SimpleJarClient项目中调用registerUser(in StudentInfo studentInfo)方法,进行自定义对象的数据传递,如下:

 ├── AndroidManifest.xml
├── Android.mk
├── libs
│  └── simple.jar
├── res
│  ├── drawable-hdpi
│  │  └── ic_launcher.png
│  ├── drawable-ldpi
│  ├── drawable-mdpi
│  │  └── ic_launcher.png
│  ├── drawable-xhdpi
│  │  └── ic_launcher.png
│  ├── drawable-xxhdpi
│  │  └── ic_launcher.png
│  ├── layout
│  │  ├── activity_main.xml
│  │  ├── activity_tss.xml
│  │  ├── test.xml
│  │  ├── usb.xml
│  │  └── version.xml
│  ├── menu
│  ├── values
│  │  ├── dimens.xml
│  │  └── strings.xml
│  ├── values-v11
│  ├── values-v14
│  └── values-w820dp
│      └── dimens.xml
└── src
    └── com
        └── example
            └── helloworld
                ├── TestVoice.java
                ├── UsbTest.java
                └── util
                    ├── Logger.java
                    └── USBUtil.java
 

package com.example.helloworld;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.china.jar.StudentInfo;
import com.china.jar.VoiceChangedListener;
import com.china.jar.VoiceManager;
import com.example.helloworld.util.Logger;


public class TestVoice extends Activity{
	VoiceManager voiceManager;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.version);
		voiceManager = VoiceManager.getInstance();
		if (voiceManager != null){
			voiceManager.addVoiceChangedListener(new VoiceChangedListener() {//客户端的监听及实现
				
				@Override
				public void openAppByVoice(String arg0) {
					Logger.d("packageName = " + arg0);
				}
			});
		}
		
		voiceManager.registerUser(new StudentInfo("赵敏", 18));//aidl中客户端传递自定义对象StudentInfo到服务端
	}
	
	public void startVoice(View view){
		Logger.d();
		Intent intent = new Intent();
		intent.setClass(TestVoice.this, UsbTest.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(intent);
    }
    
    public void stopVoice(View view){
    	Logger.d();
    	VoiceManager.getInstance().face();
    }
    
    public void finishVoice(View view){
    	Logger.d();
    	finish();
    }
}

四、运行结果如下:

 

代码参考路径:https://github.com/gunder1129/android-tool/tree/master/AIDLdemo

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值