android AIDL的使用

在Android中,一个进程通常无法访问另一个进程的内存。为了进程间的通信,进程需要将其对象分解成可供操作系统理解的语言,将其编组为可更操作的对象,编写执行该编组操作的代码较为繁琐,因此Android会使用AIDL为我们处理此问题。

白话

让某个Service与多个应用程序组件之间进行跨进程通信,从而实现多个应用程序共享同一个Service的功能

使用场景

AIDL:只有需要不同应用的客户端通过IPC方式访问服务,并且希望服务中进行多线程操作的
Binder:单应用多进程开发IPC,服务中进行多线程
Messenger:跨应用多进程IPC,不需要多线程

根据不同业务需求来使用相应的IPC方式。

如何使用

写两个应用 MsApplication 、MyApplacation。MsApplication 中启动这个将作为共享的服务 ,在MyApplacation中通过AIDL获得service中的内容

首先创建AIDL文件 文件位置存放
位置
它的内容是这样的 划红线的部分是我自己添加的方法;basicTypes方法可以删掉。
aidl

MsApplication中MainActivity.java

public class MainActivity extends AppCompatActivity {

    private ServiceConnection service = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            aidlInterface = IMyAidlInterface.Stub.asInterface(service);
            try {
                String string = aidlInterface.getString();
                Log.e("", string);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            aidlInterface = null;
        }
    };
    private IMyAidlInterface aidlInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.b).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MainService.class);
                bindService(intent, service, BIND_AUTO_CREATE);
            }
        });
    }
}

MainService.java

public class MainService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("///", "创建");
    }

    @Override
    public IBinder onBind(Intent intent) {

        return new Mybind();
    }


    public synchronized ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
        return null;
    }

    class Mybind extends IMyAidlInterface.Stub {

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public String getString() throws RemoteException {
            String string = "我是从服务起返回的";
            return string;
        }
    }
}

清单文件

<service android:name=".MainService">
            <intent-filter>
                <action android:name="com.example.msapplication.MainService" />
            </intent-filter>
        </service>

在这个Service中我们创建了内部类继承我们的AIDL文件IMyAidlInterface,需要.Stub。重写了两个方法,我们可以再getString中搞我们想要做的事情。这时是可以启动应用程序并且开启这个服务的,也可以得到我们通过getString方法放回字符串的,但是并没有实现跨进程通信。在来写My Application。这个应用中我同样要定义AIDL文件,且要和服务端的AIDL文件一致,就是和MsApplication的AIDL文件一致。剩下的就只需要通过Intent绑定到My Application的服务了。

My Application中MainActivity.java

public class MainActivity extends AppCompatActivity {

    private IMyAidlInterface aidlInterface;

    private ServiceConnection service = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
        	//系统调用这个来传送在service的onBind()中返回的IBinder.
            aidlInterface = IMyAidlInterface.Stub.asInterface(service);
            try {
                String string = aidlInterface.getString();
                Log.e("", string);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        	//service的连接意外丢失时调用这个.比如当service崩溃了或被强杀了.当客户端解除绑定时,这个方法不会被调用.
            aidlInterface = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction("com.example.msapplication.MainService");
                intent.setPackage("com.example.msapplication");
                bindService(intent, service, BIND_AUTO_CREATE);
            }
        });
        findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    String string = aidlInterface.getString();
                    Log.d("///", string);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

结果验证:同时开启两个App 开启服务后 在另一个App中绑定服务,调用方法得到字符串
两个
ms
my

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android AIDLAndroid Interface Definition Language)是一种用于定义客户端和服务之间通信接口的语言。AIDL 是一个 Android 特有的 RPC(远程过程调用)机制。 下面是使用 AIDL 的基本步骤: 1. 定义 AIDL 接口 在服务端创建一个 AIDL 文件,定义服务的接口方法。例如,创建一个名为 IMyService.aidl 的文件,其中包含以下内容: ``` interface IMyService { void sayHello(); } ``` 2. 实现 AIDL 接口 在服务端实现 AIDL 接口,例如: ``` public class MyService extends Service { private final IMyService.Stub binder = new IMyService.Stub() { @Override public void sayHello() throws RemoteException { Log.i("MyService", "Hello World"); } }; @Nullable @Override public IBinder onBind(Intent intent) { return binder; } } ``` 3. 绑定服务 在客户端绑定服务,例如: ``` private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IMyService myService = IMyService.Stub.asInterface(service); try { myService.sayHello(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; private void bindService() { Intent intent = new Intent(this, MyService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE); } ``` 通过上述步骤,就可以实现客户端与服务端之间的通信。需要注意的是,AIDL 接口中定义的方法必须是可序列化的。如果方法参数或返回值类型不支持序列化,可以通过 Parcelable 接口实现序列化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值