Android AIDL简单实现(Android Studio环境)

简单实现 AIDL(进程间通信)

aidl应用场景,因为安卓不同的应用运行在不同的进程,不能共享内存。当一个项目实现某一部分功能时依赖于另一个项目时候我们就可以用aidl来实现。

下面实现一个模拟远程的登陆操作,登陆成功返回用户信息,登陆失败返回错误信息。

正确的用户名:user,密码:123456

实现方式:

先建立客户端或者服务端都可以,但是两个AIDL文件的包名等必须完全一致。

1、客户端:

建立.aidl文件,文件目录如下:


文件内容如下:

// ILoginInterface.aidl
package com.demo.jinjin.aidlclient;

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

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


    String login(String user,String pwd);

}
此时编译项目,即可在generated目录下生成相应的java文件,目录如下:


打开文件,可看到文件内容如下:

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: E:\\MyBase\\AIDLClient\\app\\src\\main\\aidl\\com\\demo\\jinjin\\aidlclient\\ILoginInterface.aidl
 */
package com.demo.jinjin.aidlclient;
// Declare any non-default types here with import statements

public interface ILoginInterface extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.demo.jinjin.aidlclient.ILoginInterface
{
private static final java.lang.String DESCRIPTOR = "com.demo.jinjin.aidlclient.ILoginInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.demo.jinjin.aidlclient.ILoginInterface interface,
 * generating a proxy if needed.
 */
public static com.demo.jinjin.aidlclient.ILoginInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.demo.jinjin.aidlclient.ILoginInterface))) {
return ((com.demo.jinjin.aidlclient.ILoginInterface)iin);
}
return new com.demo.jinjin.aidlclient.ILoginInterface.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
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_basicTypes:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
long _arg1;
_arg1 = data.readLong();
boolean _arg2;
_arg2 = (0!=data.readInt());
float _arg3;
_arg3 = data.readFloat();
double _arg4;
_arg4 = data.readDouble();
java.lang.String _arg5;
_arg5 = data.readString();
this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
reply.writeNoException();
return true;
}
case TRANSACTION_login:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _result = this.login(_arg0, _arg1);
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.demo.jinjin.aidlclient.ILoginInterface
{
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;
}
/**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
@Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(anInt);
_data.writeLong(aLong);
_data.writeInt(((aBoolean)?(1):(0)));
_data.writeFloat(aFloat);
_data.writeDouble(aDouble);
_data.writeString(aString);
mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public java.lang.String login(java.lang.String user, java.lang.String pwd) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(user);
_data.writeString(pwd);
mRemote.transact(Stub.TRANSACTION_login, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_login = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
/**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
public java.lang.String login(java.lang.String user, java.lang.String pwd) throws android.os.RemoteException;
}
这个文件内容我们不许要做过多的关注。

下面进行远程服务的绑定:

private ILoginInterface iLoginInterface;

private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        iLoginInterface = ILoginInterface.Stub.asInterface(service);
        LoginPresenter presenter = new LoginPresenter(MainActivity.this);
        presenter.login(iLoginInterface);
        unbindService(connection);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        connection = null;
    }
};
bindService( new Intent("com.demo.jinjin.aidlserver"),connection, Context.BIND_AUTO_CREATE);
绑定成功之后进行登陆操作,登陆操作完成之后记得解绑,注意此处的intent的action与服务端service注册的action要保持一致。

这块采用的是MVP的模式,所以登陆的具体方法在model中,通过presenter实现调度。

presenter如下:

public void login(ILoginInterface iLoginInterface){
    LoginModel loginModel = new LoginModel();
    try {
        loginModel.lolgin(iLoginView.getUser(), iLoginView.getPwd(),iLoginInterface, new OnLoginFinish() {
            @Override
            public void loginSuccess(User user) {
                iLoginView.showSnackBar(user.getUser());

            }

            @Override
            public void loginFailed(String error) {
                iLoginView.showSnackBar(error);
            }
        });
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }

}
model如下:

@Override
public void lolgin(String user, String pwd, ILoginInterface iLoginInterface, OnLoginFinish onLoginFinish) throws RemoteException, JSONException {
    String result =  iLoginInterface.login(user,pwd);
    Log.e("test","---------->" + result);
    JSONObject object = new JSONObject(result);
    if (100 ==object.getInt("result_code")){
        JSONObject object1 = object.getJSONObject("result_info");
        User user1 = new User();
        user1.setUser(object1.getString("user"));
        user1.setPwd(object1.getString("pwd"));
        onLoginFinish.loginSuccess(user1);
    }else {
        onLoginFinish.loginFailed("用户名,密码错误");
    }
}
即可实现远程的登陆操作。

2、服务端实现:

将客户端的aidl目录整体拷贝到服务端,如下:


之后对代码进行编译,生成相应的java目录:


下面进行远程service的定义,如下:

package com.demo.jinjin.aidlserver;

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

import com.demo.jinjin.aidlclient.ILoginInterface;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Created by linkmax on 2016/8/2.
 */
public class LoginService extends Service {


    private static final String TAG = "AIDLService";

    private void Log(String str){
        Log.e(TAG,"----------" + str + "----------");
    }

    public void onCreate(){
        Log.e(TAG,"service created");
    }

    public void onStart(Intent intent, int startId){
        Log.e(TAG,"service started id = " + startId);
    }


    @Nullable
    @Override
    public IBinder onBind(Intent t){
        Log.e(TAG,"service on bind");
        return mBinder;
    }

    public void onDestroy(){
        Log.e(TAG,"service on destroy");
        super.onDestroy();
    }

    public boolean onUnbind(Intent intent){
        Log.e(TAG,"service on unbind");
        return super.onUnbind(intent);
    }

    public void onRebind(Intent intent){
        Log.e(TAG,"service on rebind");
        super.onRebind(intent);
    }


    private final ILoginInterface.Stub mBinder = new ILoginInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public String login(String user, String pwd) throws RemoteException {
            if ("user".equals(user) && "123456".equals(pwd)){
                JSONObject object = new JSONObject();
                try {
                    JSONObject object1 = new JSONObject();
                    object1.put("user","server_user");
                    object1.put("pwd","server_123456");
                    object.put("result_code",100);
                    object.put("result_info",object1);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return object.toString();
            }else {
                JSONObject object = new JSONObject();
                try {
                    JSONObject object1 = new JSONObject();
                    object1.put("user","server_error");
                    object1.put("pwd","server_error");
                    object.put("result_code",200);
                    object.put("result_info",object1);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return object.toString();
            }
        }
    };


}
最后进行远程service的注册, 如下:

<service android:name=".LoginService">
    <intent-filter>
        <action android:name="com.demo.jinjin.aidlserver"/>
    </intent-filter>
</service>
注意,两边的action需要保持一致。

此时启动客户端与服务端即可实现远程的登陆操作。

源码下载:源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值