android开发中通过aidl实现远程方法调用

在安卓开发过程中我们可能见过这样的问题,就是在一个应用中调用另一个应用中的服务,并调用该服务中的方法。

我们可能对调用服务并不陌生,可是要执行服务中的方法,却不能直接调用。因为两个服务和调用它的程序属于两个应用,在不同的项目中,根本访问不到。安卓在设计的时候也帮我们想到了这个问题,并设计了aidl,下面我们来看一下到底是怎么使用的

  1. 创建服务,并配置意图过滤器,可以让其他程序通过隐式意图调用服务,在服务中编写需要被调用的方法
  2. 在android studio中可以直接创建一个aidl文件,在eclipse中需要手动创建文件,后缀名为.aidl,在里面定义一个接口,书写方法和在.java文件中写接口一样。写完之后开发工具会自动生成一个同名的java文件。该文件最好不要打开,因为不需要修改。
  3. 在服务中创建一个子类用来调用需要被远程调用的方法,该类继承上一步生成类的一个子类Stub ,并在服务的onBind方法中返回该类的对象。同时
  4. 将aidl文件复制到需要调用该服务的应用中,这里需要注意两个aidl文件所在的包名必须相同。
  5. 在需要调用的服务的activity中创建ServiceConnection对象,并实现其抽象方法。通过aidl名.Stub.asInterface(Ibinder对象);获取到在服务中创建的子类对象,就可以操作远程服务中的方法了。

下面我们来看个例子
服务端的服务配置如下

<service android:name="com.example.aidldy.myService">
    <intent-filter><action android:name="com.zl.aidl.service"/></intent-filter>
</service>

aidl文件

package com.example.aidldy;
interface aaa{
    //暴露出该方法用于调用服务中的a()方法
    void toA();
}

服务对应的文件

package com.example.aidldy;

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

public class myService extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        return new bb();
    }

    public void a(){
        Log.e("com.zl.aidl", "服务中方法被调用了");
    }

    //继承开发工具根据aidl文件生成的类
    class bb extends aaa.Stub{

        @Override
        public void toA() throws RemoteException {
            a();
        }

    }

}

接下来在另一个应用的activity中调用,activity同样需要有相同的aidl文件,activity如下

package com.example.aidldemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;

import com.example.aidldy.aaa;

public class MainActivity extends Activity {

    aaa aa;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ServiceConnection connection = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName arg0) {

            }

            @Override
            public void onServiceConnected(ComponentName arg0, IBinder arg1) {
                aa = aaa.Stub.asInterface(arg1);
            }
        };

        Intent intent = new Intent();
        intent.setAction("com.zl.aidl.service");
        startService(intent);
        bindService(intent, connection, 0);

    }

    public void click(View v){
        try {
            aa.toA();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}

上面的click()方法为页面上一个Button的回调方法,当Button被点击的时候该方法就会被调用然后执行服务中的方法在LogCat中打印日志。

一个小例子就完了,希望对阅读本文章的朋友有所帮助。

猜你喜欢

转载自blog.csdn.net/qq_28859405/article/details/52592807