您的位置:首页 > 移动开发 > Android开发

android简单的AIDL使用示例

2016-05-11 14:32 561 查看

android简单的AIDL使用示例

示例实现概述:

服务端:创建的时候起一个线程,每隔一秒中计数自增1,通过aidl有两个接口供远程调用;

客户端:进入客户端程序即bind服务,此时服务即运行起来;一个按钮获取服务中的计数值;退出客户端解除服务绑定(因为这个服务只有我们目前一个客户端绑定,所以服务端服务也会退出,并且线程应该终止)。

PS:《android框架》中在第10章Java服务框架章节中的示例是在工程源码中注册使用,其中包含服务的注册、检索和使用等;而下面的示例只是在应用app之间使用服务,并没有包含服务的注册、检索,以及包装服务的manager。—后面有空再写两个如书中所述在工程源码中添加Java服务的示例和第8章中用C/C++所写的本地服务示例。

也可以参考一篇比较好的博客:C++层Service的创建与使用

以下示例的代码都传到我的github上欢迎查看:
https://github.com/lb405828825/LearnSmapleCode.git
环境:

Ubuntu12.04

android-studio2.0

androidSDK=23

1.服务端Service

(1)IDE中建立服务端android工程,然后编写aidl远程接口文件;此时并没有AIDL的java文件产生,需android-studio编译生成的。

ISimpleAidlInterface.aidl

目录结构和代码如下图所示:



注意:需要确认aidl的packagename和AndroidManifest中的包名包一致。

自动生成的接口文件目录和结构如下图:



可以自行分析一下接口文件中的各个部分含义,其中每段代码都很有意思



可参考《android框架》中第10章Java服务部分,其中从Java服务框架进行了仔细分析,从Java到C++Binder如何关联起来的都有讲解。

这里只说明一下,抽象类stub是需要我们在接下来的服务中进行继承并具体实现其中的接口,与一般的接口有点不一样,它是服务代理通过Binder通信远程调用到我们的服务。

(2)编写服务,实现远程接口。

服务功能:服务端用线程来每秒增加1的计数,表示服务存在;服务终止的时候,线程也退出;

代码如下:

package com.hqbd2.learnsimpleaidl;

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

import com.hqbd2.learnsimpleaidl.ISimpleAidlInterface;

public class SimpleAidlService extends Service {

private final static String TAG = "hqbd2";
private boolean mFlag = false;
private static int mCount = 0;

public SimpleAidlService() {

}

@Override
public void onDestroy() {
super.onDestroy();
mFlag = false;
System.out.println("------SimpleAidlService, onDestroy()------");
}

@Override
public void onCreate() {
super.onCreate();

System.out.println("------SimpleAidlService, onCreate()------");
mFlag = true;
//服务端使用线程,mCount向客户端展示服务在运行中;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("SimpleAidlService, Thread is running");
while (mFlag){
mCount++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("SimpleAidlService, Thread's loop over");
}
}).start();
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mSimpleStub;
}

//服务stub具体实现aidl中的接口,mSimpleStub通过Binder返回给Proxy代理端使用的;
ISimpleAidlInterface.Stub mSimpleStub = new ISimpleAidlInterface.Stub() {
@Override
public void printHelloAidl() throws RemoteException {
Log.d(TAG, "Hello, this is SimpleAidlService, you use Aidl invoke");
System.out.println("Hello, this is SimpleAidlService, you use Aidl invoke");
}

@Override
public int getCount() throws RemoteException {
//            System.out.println("Hello, this is SimpleAidlService, getCount():mCount = " + mCount);
return mCount;
}
};
}


注意:

(1)即使服务实现文件和aidl在一个包中,也需要import进去。

import com.hqbd2.learnsimpleaidl.ISimpleAidlInterface;

(2)AndroidManifest文件中:

android:exported="true"

2.客户端Client

编写客户端android工程,需要将前面服务端中编写的aidl文件拷贝一份到客户端中。

注意:客户端和服务端的aidl接口文件是一致的,在应用编译之后,会自动生成一样的接口.java文件,如下图所示:



代码如下:

package com.hqbd2.simpleaidleclient;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.hqbd2.learnsimpleaidl.ISimpleAidlInterface;

public class MainActivity extends AppCompatActivity {

private static final String TAG = "hqbd2";
private static final String AIDL_SERVICE_ACTION = "android.intent.action.SimpleAidlService";

private Button mBtn;
private TextView mCountTv;

private ISimpleAidlInterface mSimpleAidlService;
private ServiceConnection mSc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//通过Binder获取服务代理,操作服务代理就像在同一进程中使用服务一样的。
mSimpleAidlService = ISimpleAidlInterface.Stub.asInterface(iBinder);
}

@Override
public void onServiceDisconnected(ComponentName componentName) {

}
};

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

//bind service
//        Intent i = new Intent(AIDL
4000
_SERVICE_ACTION);
Intent i = new Intent();
i.setClassName("com.hqbd2.learnsimpleaidl", "com.hqbd2.learnsimpleaidl.SimpleAidlService");
bindService(i, mSc, BIND_AUTO_CREATE);

mBtn = (Button) findViewById(R.id.button);
mCountTv = (TextView) findViewById(R.id.textView2);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
mSimpleAidlService.printHelloAidl();
} catch (RemoteException e) {
e.printStackTrace();
}

try {
int count = mSimpleAidlService.getCount();
mCountTv.setText("Aidl-count: " + count);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}


3.编译运行

服务端和客户端各自编译成apk安装到手机中。只需要运行客户端的apk即可。

运行结果:

05-11 12:42:42.790 12848-12848/com.hqbd2.learnsimpleaidl I/System.out: ------SimpleAidlService, onCreate()------

05-11 12:42:42.790 12848-15279/com.hqbd2.learnsimpleaidl I/System.out: SimpleAidlService, Thread is running

05-11 12:42:49.220 12848-12865/com.hqbd2.learnsimpleaidl I/System.out: Hello, this is SimpleAidlService, you use Aidl invoke

05-11 12:42:57.700 12848-12866/com.hqbd2.learnsimpleaidl I/System.out: Hello, this is SimpleAidlService, you use Aidl invoke

05-11 12:43:00.490 12848-12848/com.hqbd2.learnsimpleaidl I/System.out: ------SimpleAidlService, onDestroy()------

05-11 12:43:00.800 12848-15279/com.hqbd2.learnsimpleaidl I/System.out: SimpleAidlService, Thread's loop over

手机端图片:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: