Android创建AIDL服务

Android系统的进程之间不能共享内存,所以需要提供一些机制在不同的进程之间进行数据的交互。接下来本文就简单地介绍如何使用AIDL进行Android程序之间的跨进程访问。

1、什么是AIDL

大多数情况下我们在程序中自己实现的Service只能供自己的程序调用,其他程序是不能使用的。为了使其他的程序可以访问本地程序提供的服务,Android系统采用了RPC的方式来实现。Android使用AIDL(Android Interface Definition Language)来定义并公开服务的接口。

2、如何创建AIDL

创建的过程很简单,其实就是定义一个aidl文件,然后实现该文件定义的接口,然后发布接口,将服务运行在手机上,手机上的其他程序就可以访问你创建的服务了。

3、具体AIDL服务的创建过程


新建一个TestAIDL工程,在src目录下创建一个名为ITestService.aidl的文件。如上图所示,在aidl文件中定义两个方法。

package com.example.testaidl;

interface ITestService{

    String getValue();
    int calculateAdd(int a, int b);

}
注意方法不能加修饰符(如public、private等)以及AIDL不支持的数据类型

如果aidl文件的输入正确,那么adt公交会在gen目录下生产ITestService.java,一般情况下我们不用管这个文件,也不需要维护它。

然后我们需要用一个Service来提供aidl的实例。

创建一个TestService类,继承Service。在TestService中定义一个内嵌类来继承ITestService.Stub,TestService类的代码如下:

package com.example.testaidl;

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

public class TestService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return new TestServiceImpl();
    }

    
    public class TestServiceImpl extends ITestService.Stub{
        @Override
        public String getValue() throws RemoteException {
            // TODO Auto-generated method stub
            return "This is a value from aidl";
        }

        @Override
        public int calculateAdd(int a, int b) throws RemoteException {
            // TODO Auto-generated method stub
            return a+b;
        }
        
    }
}
看到了,我们在aidl中定义的两个方法是在TestServiceImpl中实现的。另外onBind方法需要返回一个TestServiceImpl的实例对象,否则的话调用者无法获得服务对象。

最后要做的就是在manifest文件中声明TestService

<service android:name=".TestService">
            <intent-filter>
                <action android:name="com.example.testaidl.ITestService"/>
            </intent-filter>
        </service>
注意,action中的name “com.example.testaidl.ITestService”就是其他程序访问aidl服务时需要传的ID

之后把该工程run到你的手机上,这个服务就可以被其他的程序访问了。
4、调用程序的创建
为了查看我们的AIDL服务是否创建成功,我们可以写一个测试程序TestAIDLClient来验证一下


新建一个相同的包名com.example.testaidl,然后把ITestService.java直接拷贝过来。

然后在MainActivity中绑定并调用aidl服务中的方法

MainActivity的代码如下:

package com.example.testaidlclient;

import com.example.testaidl.ITestService;

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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener{
    
    private ITestService testService;
    private Button bindBtn;
    private Button invokeBtn;
    private TextView showText;
    
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
            
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            testService = ITestService.Stub.asInterface(service);
            invokeBtn.setEnabled(true);
            Toast.makeText(getApplicationContext(), "绑定成功", Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.main_activity);
        
        bindBtn = (Button) findViewById(R.id.bind_btn);
        invokeBtn = (Button)findViewById(R.id.invoke_btn);
        //初始化不能点击,绑定成功之后可以点击
        invokeBtn.setEnabled(false);
        showText = (TextView) findViewById(R.id.show_text);
        
        bindBtn.setOnClickListener(this);
        invokeBtn.setOnClickListener(this);
    }

    
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.bind_btn:
                bindService(new Intent("com.example.testaidl.ITestService"), serviceConnection, Context.BIND_AUTO_CREATE);
                break;
            case R.id.invoke_btn:
                try {
                    showText.setText(testService.getValue() + testService.calculateAdd(10, 20));
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;
        }
    }

    
    
}

首先点击绑定按钮进行绑定,系统通过serviceConnection的onServiceConnected方法获得aidl服务对象,然后通过对象调用aidl服务的具体方法。运行截图如下:

    

最后是两个工程的下载链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值