赞
踩
在 Android——使用AIDL实现进程间通讯简单案例 中介绍了使用 AIDL 在进程间传递字符串,对于8种基本数据类型( byte、short、int、long、float、double、boolean、char )和 CharSequence(包含 String )、List、Map,用法同理。
需要注意:List 和 Map 中的所有元素必须是 AIDL 支持的类型,List 支持泛型,Map 不支持泛型。
本文将介绍使用 AIDL 实现自定义 User 对象间的传递,User 包含 name(String)和 age(int)2个属性。
本文全部代码见→使用AIDL实现进程间传递对象案例
注意事项:
(1)传输类定义
User.java
- package commu;
-
- import android.os.Parcel;
- import android.os.Parcelable;
-
- public class User implements Parcelable{
- private String name;
- private int age;
-
- public User(String name, int age) {
- this.name = name;
- this.age = age;
- }
-
- protected User(Parcel in) {
- name = in.readString();
- age = in.readInt();
- }
-
- public static final Creator<User> CREATOR = new Creator<User>() {
- @Override
- public User createFromParcel(Parcel in) {
- return new User(in);
- }
-
- @Override
- public User[] newArray(int size) {
- return new User[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeInt(age);
- }
-
- public String getName() {
- return name;
- }
-
- public int getAge() {
- return age;
- }
-
- @Override
- public String toString() {
- return "User{" + "name='" + name + '\'' + ", age=" + age + '}';
- }
- }
(2)传输类声明
User.aidl
- package commu;
-
- parcelable User;
注意: 声明 parcelable,不是 Parcelable
(3)通讯接口
MessageManager.aidl
- package commu;
-
- import commu.User;
-
- interface MessageManager {
- void sendMsg(in User user);
- User getMsg();
- }
(4)服务
MyService.java
- package com.zhyan8.aidl_s;
-
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- import commu.MessageManager;
- import commu.User;
-
- public class MyService extends Service {
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBind;
- }
-
- MessageManager.Stub mBind = new MessageManager.Stub() {
- @Override
- public void sendMsg(User user) throws RemoteException {
- Log.d("MyService", "客户端发来消息: " + user.toString());
- System.out.println(user.toString());
- }
-
- @Override
- public User getMsg() throws RemoteException {
- return new User("小红",23); //客户端待接收的消息
- }
- };
- }
(5)注册服务
在 AndroidManifest.xml 文件中 application 节点下注册 service,如下。
- <service
- android:name=".MyService"
- android:enabled="true"
- android:exported="true">
- <intent-filter>
- <action android:name="com.xxx.aidl"/>
- </intent-filter>
- </service>
(6)主Acitvity
MainActivity.java
- package com.zhyan8.aidl_s;
-
- import android.os.Bundle;
- import android.support.v7.app.AppCompatActivity;
-
- public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- }
(1)复制 User 类及 aidl 文件
将 aidl_S 中 java 和 aidl 目录下的 commu 包及其中的 aidl 文件(User.aidl、MessageManager.aidl) 和 User.java 文件复制到 aidl_C 中相应目录下,见第2节中项目结构图 。
(2)布局
activity_main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- android:orientation="vertical"
- tools:context="com.zhyan8.aidl_c.MainActivity">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="姓名:"
- android:textSize="30sp"/>
- <EditText
- android:id="@+id/et_name"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:textSize="30sp"
- android:background="#ffcc66"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="20dp">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="年龄:"
- android:textSize="30sp"/>
- <EditText
- android:id="@+id/et_age"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:textSize="30sp"
- android:inputType="number"
- android:background="#ffcc66"/>
- </LinearLayout>
-
- <Button
- android:id="@+id/btn_send"
- android:layout_width="match_parent"
- android:layout_height="80dp"
- android:text="发送"
- android:textSize="30sp"
- android:layout_marginTop="30dp"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="50dp">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="姓名:"
- android:textSize="30sp"/>
- <TextView
- android:id="@+id/tv_name"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:textSize="30sp"
- android:background="#ffcc66"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="20dp">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="年龄:"
- android:textSize="30sp"/>
- <TextView
- android:id="@+id/tv_age"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:textSize="30sp"
- android:background="#ffcc66"/>
- </LinearLayout>
-
- <Button
- android:id="@+id/btn_recv"
- android:layout_width="match_parent"
- android:layout_height="80dp"
- android:text="接收"
- android:textSize="30sp"
- android:layout_marginTop="30dp"/>
- </LinearLayout>
界面如下:
(3)主Activity
MainActivity.java
- package com.zhyan8.aidl_c;
-
- 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.RemoteException;
- import android.support.v7.app.AppCompatActivity;
- import android.view.View;
- import android.view.inputmethod.InputMethodManager;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
- import commu.MessageManager;
- import commu.User;
-
- public class MainActivity extends AppCompatActivity {
- private MessageManager mMessageManager;
- private EditText et_name;
- private EditText et_age;
- private Button btn_send;
- private TextView tv_name;
- private TextView tv_age;
- private Button btn_recv;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- init();
- }
-
- public void init() {
- et_name = (EditText) findViewById(R.id.et_name);
- et_age = (EditText) findViewById(R.id.et_age);
- btn_send = (Button) findViewById(R.id.btn_send);
- tv_name = (TextView) findViewById(R.id.tv_name);
- tv_age = (TextView) findViewById(R.id.tv_age);
- btn_recv = (Button) findViewById(R.id.btn_recv);
- btn_send.setOnClickListener(cl);
- btn_recv.setOnClickListener(cl);
- }
-
- View.OnClickListener cl = new View.OnClickListener(){
- @Override
- public void onClick(View v) {
- hideInputMethod(MainActivity.this, v); //关闭输入法
- if (v.getId()==R.id.btn_send) {
- try {
- String name_t = et_name.getText().toString();
- int age_t = Integer.parseInt(et_age.getText().toString());
- User user = new User(name_t, age_t);
- sendMsg(user);
- } catch (Exception e) {
- Toast.makeText(MainActivity.this, "请输入姓名和年龄", Toast.LENGTH_SHORT).show();
- }
- }else if(v.getId()==R.id.btn_recv) {
- User user = getMsg();
- tv_name.setText(user.getName());
- tv_age.setText("" + user.getAge());
- }
- }
- };
-
- private void sendMsg(User user){
- if (mMessageManager==null) {
- attemptToBindService();
- }
- try {
- mMessageManager.sendMsg(user);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- private User getMsg(){
- if (mMessageManager==null) {
- attemptToBindService();
- }
- try {
- User user = mMessageManager.getMsg();
- return user;
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- private void attemptToBindService() {
- Intent intent = new Intent();
- intent.setAction("com.xxx.aidl");
- intent.setPackage("com.zhyan8.aidl_s");
- bindService(intent, conn, Context.BIND_AUTO_CREATE);
- }
-
- ServiceConnection conn = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mMessageManager = MessageManager.Stub.asInterface(service);
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mMessageManager = null;
- }
- };
-
- private void hideInputMethod(Activity act, View v) { //关闭输入法
- InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(v.getWindowToken(),0);
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- if (mMessageManager==null) {
- attemptToBindService();
- }
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- if (mMessageManager!=null) {
- unbindService(conn);
- }
- }
- }
(1)发送消息
在2个 EditView 中分别输入::小明、20,点击【发送】按钮,在服务端可以收到发送的消息,如下。
(2)接收消息
点击【接收】按钮,客户端 aidl_C 界面可以看到服务端 aidl_S 传过来的 user 信息,如下。
以下是点击【Make Build】后自动生成的代码,路径为【aild_C\build\generated\source\aidl\debug\commu\ 】
MessageManager.java
- package commu;
-
- public interface MessageManager extends android.os.IInterface {
-
- public static class Default implements commu.MessageManager {
- @Override
- public void sendMsg(commu.User user) throws android.os.RemoteException {
- }
-
- @Override
- public commu.User getMsg() throws android.os.RemoteException {
- return null;
- }
-
- @Override
- public android.os.IBinder asBinder() {
- return null;
- }
- }
-
- public static abstract class Stub extends android.os.Binder implements commu.MessageManager {
- private static final java.lang.String DESCRIPTOR = "commu.MessageManager";
-
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
-
- public static commu.MessageManager asInterface(android.os.IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof commu.MessageManager))) {
- return ((commu.MessageManager) iin);
- }
- return new commu.MessageManager.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 {
- java.lang.String descriptor = DESCRIPTOR;
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(descriptor);
- return true;
- }
- case TRANSACTION_sendMsg: {
- data.enforceInterface(descriptor);
- commu.User _arg0;
- if ((0 != data.readInt())) {
- _arg0 = commu.User.CREATOR.createFromParcel(data);
- } else {
- _arg0 = null;
- }
- this.sendMsg(_arg0);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_getMsg: {
- data.enforceInterface(descriptor);
- commu.User _result = this.getMsg();
- reply.writeNoException();
- if ((_result != null)) {
- reply.writeInt(1);
- _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- } else {
- reply.writeInt(0);
- }
- return true;
- }
- default: {
- return super.onTransact(code, data, reply, flags);
- }
- }
- }
-
- private static class Proxy implements commu.MessageManager {
- 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 void sendMsg(commu.User user) throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- if ((user != null)) {
- _data.writeInt(1);
- user.writeToParcel(_data, 0);
- } else {
- _data.writeInt(0);
- }
- boolean _status = mRemote.transact(Stub.TRANSACTION_sendMsg, _data, _reply, 0);
- if (!_status && getDefaultImpl() != null) {
- getDefaultImpl().sendMsg(user);
- return;
- }
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public commu.User getMsg() throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- commu.User _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- boolean _status = mRemote.transact(Stub.TRANSACTION_getMsg, _data, _reply, 0);
- if (!_status && getDefaultImpl() != null) {
- return getDefaultImpl().getMsg();
- }
- _reply.readException();
- if ((0 != _reply.readInt())) {
- _result = commu.User.CREATOR.createFromParcel(_reply);
- } else {
- _result = null;
- }
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public static commu.MessageManager sDefaultImpl;
- }
-
- static final int TRANSACTION_sendMsg = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
- static final int TRANSACTION_getMsg = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
-
- public static boolean setDefaultImpl(commu.MessageManager impl) {
- if (Stub.Proxy.sDefaultImpl == null && impl != null) {
- Stub.Proxy.sDefaultImpl = impl;
- return true;
- }
- return false;
- }
-
- public static commu.MessageManager getDefaultImpl() {
- return Stub.Proxy.sDefaultImpl;
- }
- }
-
- public void sendMsg(commu.User user) throws android.os.RemoteException;
-
- public commu.User getMsg() throws android.os.RemoteException;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。