Android 使用AIDL跨进程通信(二)--传递自定义对象

使用AIDL传递自定义Bean结构,必须实现parcelable接口

Server中进行定义Bean结构


// Parcelable与Serializable序列化对比
// 1.在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
//
// 2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
//
// 3.Parcelable不能使用在要将数据存储在磁盘上的情况,
// 因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。
// 尽管Serializable效率低点,但此时还是建议使用Serializable 。
public class User implements Parcelable {

    private String userName;
    private String passwd;

    public User() {
    }

    public User(String userName, String passwd) {
        this.userName = userName;
        this.passwd = passwd;
    }

    protected User(Parcel in) {
        userName = in.readString();
        passwd = in.readString();
    }


    //为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例
    public static final Creator CREATOR = new Creator() {
        @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(userName);
        dest.writeString(passwd);
    }


    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", passwd='" + passwd + '\'' +
                '}';
    }
}

定义AIDL接口文件

// IGetUser.aidl
package cn.edu.hebust.aidldemo2;

// Declare any non-default types here with import statements
// 手动添加
import cn.edu.hebust.aidldemo2.User;

interface IGetUser {
    /**
     * 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);

    // 自定义的AIDL接口
    List getUserInfo(String name);
}

定义AIDLBean文件

这里必须定义AIDL Bean文件,不然会出现import error 的编译错误,将AIDL声明Bean结构即可

// IUser.aidl
package cn.edu.hebust.aidldemo2;

// Declare any non-default types here with import statements
import cn.edu.hebust.aidldemo2.User;
parcelable User;

Ctrl+B 编译这个项目

这时会生成相应的Java文件, 然后使用这个java文件进行通信
提供一个Service供通信


public class MyService extends Service {

    // 实际的通信对象
    private IBinder mStub = new IGetUser.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        // 与其他Client通信的接口
        @Override
        public List getUserInfo(String name) throws RemoteException {
            List list = new LinkedList<>();
            for (int i = 0; i < 10; i++) {
                list.add(new User(name + i, name + (i >> 2)));
            }
            return list;
        }
    };

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

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

client的配置

拷贝相同的aidl文件和bean文件
注意Bean文件的包名应该一样
Android 使用AIDL跨进程通信(二)--传递自定义对象_第1张图片

// 另一个进程中的通信代码,通过Service

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "LOGGER";

    private TextView mTvText;

    private ServiceConnection mConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IGetUser mStub = IGetUser.Stub.asInterface(service);
            try {
                List list = mStub.getUserInfo("terry");
                for (User aUser : list) {
                    mTvText.append(aUser.toString() + "\n");
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected: ");
            Toast.makeText(MainActivity.this, "onServiceDisconnected", Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvText = (TextView) findViewById(R.id.id_tv_text);
        Intent intent = new Intent();
        ComponentName componentName = new ComponentName("cn.edu.hebust.aidldemo2"
                , "cn.edu.hebust.aidldemo2.MyService");
        intent.setComponent(componentName);
        bindService(intent, mConn, BIND_AUTO_CREATE);
    }

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

Android 使用AIDL跨进程通信(二)--传递自定义对象_第2张图片

你可能感兴趣的:(android)