这个月初开始入职实习了,经过这几天的熟悉,大概了解了将来负责的方向了,然后就是开始学习。主要学习Android的Framwork一层,为上层的UI写一些接口封装,涉及到Android不同的service之间的通信,以及上层Java和底下native(C/C++)之间通信,也就是JNI技术(Java Native Interface的缩写)。

    刚开始给了一份binder的简单程序理解理解,昨天看了一天,没有什么头绪,今天看了一位大神的文章才有了写思路,文章我转载了,链接为:http://blog.csdn.net/hjf161105/article/details/79482549 。接下来我将讲述一下我对这一份简单的binder程序的理解,首先看一下整个的项目结构,如下图所示:

    这个目录结构是我这个测试模块的结构,最终还是需要放到Android源码结构中去编译的。这个目录中包含四个文件夹,分别是client、service、include和TestService。这里需要说明下TestService目录,其余三个目录都是一眼就是明白的,client是客户端程序,service是服务器程序,include是本项目中使用到的头文件,TestService目录其实是client和service之间通信binder处理的目录。

    我们先看下这两个头文件以及他们相对应的cpp文件:

TestService.h文件

#ifndef _TEST_SERVICE_#define _TEST_SERVICE_#include #include #include #include #include "ITestService.h"namespace android {//具体的服务操作类,继承于BnTestService,由BnTestService代理,//可由客户端的代理BpTestService调用class TestService:public BnTestService {public:virtual voidprint(String8 str);//虚函数,实现BnTestService的接口};}#endif

ITestService.h

#ifndef _ITEST_SERVICE_#define _ITEST_SERVICE_#include   // for status_t#include #include #include #include #include namespace android {//一个抽象类,是接口,可以被客户端的代理和服务器的代理实现class ITestService:public IInterface {public://这个宏里面定义了asInterface(),在ITestService.cpp中的//IMPLEMENT_META_INTERFACE具体实现这个asInterface()DECLARE_META_INTERFACE( TestService );//纯虚函数,被不同的代理继承后实现不同的功能virtual voidprint(String8 str) = 0;};//服务器的代理类,继承于BnInterface接口和ITestService接口,//此类还会调用其派生类的此基类ITestService中的print方法class BnTestService: public BnInterface{public://接收到客户端BpTestService的通信请求,根据code命令来决定操作virtual status_t    onTransact( uint32_t code,//操作的code命令const Parcel& data,//客户端请求发送的数据包Parcel* reply,//可能是用于返回的数据包uint32_t flags = 0 );//标志位};}#endif

TestService.cpp

#define LOG_TAG "TestService"#include #include "TestService.h"namespace android {//TestService中print方法的具体实现void TestService::print(String8 str){LOGI("TestService::print   %s...\n", str.string());}}

ITestService.cpp

#define LOG_TAG "TestService"#include #include #include #include #include  #include "ITestService.h"namespace android {//定义的操作命令enum {PRINT = IBinder::FIRST_CALL_TRANSACTION,};//客户端的代理类,用于响应客户端对ITestService的print方法的请求class BpTestService: public BpInterface{public://构造函数,首先在参数列表中将IBinder参数传递给BpInterfaceBpTestService( const sp& impl ): BpInterface( impl ) {}//实现了其基类ITestService的print方法,响应客户端的请求virtual voidprint(String8 str) {LOGD( "BpTestService print\n" );Parcel data, reply;//用于传递的数据data和返回的数据replydata.writeInterfaceToken( ITestService::getInterfaceDescriptor() );data.writeString8( str );remote()->transact( PRINT, data, &reply );//请求通信}};//在这个宏里面具体实现了asInterface()这个函数,在这个函数里面有一个new Bp##INTERFACE(obj)//相当于在这个函数中把TestService转化成了它的父类BpTestService并返回IMPLEMENT_META_INTERFACE( TestService, "test.service" );//响应客户端代理类的请求status_t BnTestService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags ){switch( code ) {case PRINT:{//得到的操作命令为定义的PRINT,做出相应判断CHECK_INTERFACE( ITestService, data, reply );LOGD( "BnTestService print\n" );print(data.readString8());//调用其子类TestService的print方法}break;default:{//code和定义的PRINT不匹配,交给BBinder处理return BBinder::onTransact( code, data, reply, flags );}break;}return NO_ERROR;}}

    以上这四个文件其实就是binder通信的主要实现,客户端和服务器其实只需要调用一下接口就可以实现通信了。这四个文件这涉及到了几个类,乍一看其实挺绕的,我才采用了UML图的方式梳理了一下这几个类的关系:

这几个类其实很多都是内部封装了,对于客户端程序来说,只需要了解ITestService和BpTestService类,对于服务器来说也是一样,只需了解ITestService和BnTestService类。我在上述的程序中做了比较详细的注释,可能会有一些地方还不了解而导致注释错误,还请多多包涵。下面把服务器程序和客户端程序也展示一下:

服务器main_TestService.cpp:

#define LOG_TAG "TestService"#include #include #include #include #include #include #include #include #include "ITestService.h"#include "TestService.h"using namespace android;int main(int argc, char** argv){    sp proc(ProcessState::self());        //获取servicemanager对象    sp sm = defaultServiceManager();        //向servicemanager添加service,TestService,取名为test.servicesm->addService(String16("test.service"), new TestService());    ProcessState::self()->startThreadPool();    IPCThreadState::self()->joinThreadPool();    return 0;}

客户端程序test_TestService.cpp:

#define LOG_TAG "TestService"#include #include #include #include #include #include #include #include #include #include #include #include "ITestService.h"using namespace android;class TestServiceDeath:public IBinder::DeathRecipient{public:virtual void binderDied(const wp& who){LOGD("TestService died notification");}};int main(int argc, char** argv){sp proc(ProcessState::self());ProcessState::self()->startThreadPool();sp binder = defaultServiceManager()->getService(String16("test.service"));sp dethNotify = new TestServiceDeath();binder->linkToDeath( dethNotify );if ( binder != NULL ) {//interface_cast(binder) 直接把IBinder类型对象binder转化成了ITestServicesp testServiceProxy = interface_cast( binder );testServiceProxy->print(String8("hello world"));}IPCThreadState::self()->joinThreadPool();return 0;}

更多相关文章

  1. Nginx系列教程(二)| 一文带你读懂Nginx的正向与反向代理
  2. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  3. Android(安卓)study(1)--Intent
  4. Android最佳实践之响应灵敏性(ANR)
  5. Android(安卓)HAL的作用及编程实例
  6. Android数据存储---数据备份(Data Backup)(二)
  7. 第四课:android数据相关---sharedPreferences
  8. android手把手教你开发launcher(五)——设置壁纸
  9. 为Android添加底层核心服务

随机推荐

  1. android移动支付——支付宝支付
  2. android:theme 与 setTheme()设置透明效
  3. android studio 串口通信JNI、NDK配置
  4. Android中使用addr2line来分析native信息
  5. Android应用程序窗口(Activity)实现框架简
  6. 屏幕适配那些事(02)Android逻辑像素刨根问
  7. Handler的使用方法――在子线程中更新界
  8. Android(安卓)混淆代码学习以及Android加
  9. Android应用启动过程浅析
  10. 盛大资深软件工程师谈Android开发经验