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
手机端图片:
相关文章推荐
- android的四种定位方式
- ANDROID内存优化(大汇总——全)
- 如何使用Android Studio把自己的Android library分享到jCenter和Maven Central
- ANDROID内存优化(大汇总——中)
- 在Android关机中插入脚本
- Only the original thread that created a view hierarchy can touch its views. 是怎么产生的
- Android优化
- ANDROID内存优化(大汇总——上)
- Android从菜鸟到笨鸟:ViewPager+Handler实现广告栏无限循环
- Android service进程保护
- Android辅助工具01
- 之前同时从git上拉下来的Android Studio代码无法运行
- Android 百度地图+Fragment冲突
- android常用动画
- Android APK反编译02
- android 全局异常捕获
- Android studio 如何修改工程的包名
- Android APK反编译01
- Android代码设置Shape,corners,Gradient
- 播放Android项目工程里的视频文件