北大3G授课--JNI与Android下C和C++组件及IBinder等.ppt_第1页
北大3G授课--JNI与Android下C和C++组件及IBinder等.ppt_第2页
北大3G授课--JNI与Android下C和C++组件及IBinder等.ppt_第3页
北大3G授课--JNI与Android下C和C++组件及IBinder等.ppt_第4页
北大3G授课--JNI与Android下C和C++组件及IBinder等.ppt_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1,Android的C/C+组件与Java,JNI、Android与JNI、C/C+组件,王家林 Do one thing at a time,and do it well! Email: From:北京大学软件与微电子学院,2,Android的快速发展及原因,市场占有率: 2010年11月2日,Canalys研究公司周一发布报告说,第三季度,Google Android已经成为全球第二大智能手机软件平台。诺基亚的Symbian以37%的份额居第一,Android为17%,排名第二。一年时间大约上升了大约500%。 工作岗位需求量:据 oDesk 2010年11月初来自全球招聘市场的报告显示,

2、Android平台开发者的需求量从2009年10月到2010年10整整上升了710%。 最热门的应用:智能手机、平板电脑(tablet)、包含机顶盒(STB)在内的新兴产品领域。 原因:开放 、免费、完整的生态系统、OHA支持,3,Android中C/C+开发意义,Native C/C+支持独特的应用程序 软件、硬件结合,双方均可获得巨大利润 对手机生产商而言,Native C/C+与硬件基础结合,形成独特的竞争优势。,4,Android C/C+组件是同时具有标准化和可替换性的完美结构,标准化和可替换性是一个产业成熟和强大的标志。 Interface的重要性:不知(C/C+组建被替换)而能使

3、用。 JNI:Java程序和C/C+程序相互沟通,扮演接口的角色。 Plug and Play Easy to Change,5,JNI与Faade Pattern,Gramma等人在Design Pattern一书中写道: The common design goal is to minimize the communication and dependencies between subsystems. This can be an import consequence when the client and the subsystem are implemented independen

4、tly. One way to achieve the goal is to introduce a faade object that provides a single,simplified interface to the more general facilities of a subsystem. Design Pattern提到Faade Pattern的作用: 1,It shields clients from subsystem components, thereby reducing the number of objects that clients deal with a

5、nd making the subsystem easier to use. 2,It promotes weak compling between the subsystem and its clients.Often the components in a subsystem are strongly coupled.Weak coupling lets you vary the components of the system without affecting its clients.,6,Android中JNI与Faade Pattern完美组合,JNI提供Android中上层Jav

6、a代码和库中C/C+交互的接口,降低Android应用程序和C/C+组建之间的依赖性 Faade Pattern提供了组建的高度可替换性,PnP(Plug and Play)。“a Faade object that provides a single,simplified interface to”,7,Android中JNI与Faade Pattern完美组合示图,8,Android软件开发分工,架构:设计规范的接口,达到标准化和可替换性。发挥JNI作用。 C/C+组件开发:采用Linux平台(一般使用Ubuntu),需要ARM GNU/Linux交叉编译器,使用OOP的方式开发。 Jav

7、a应用程序的开发:发挥C/C+组件的功能,挖掘硬件的功能。,9,JNI开篇,Java是跨平台的语言,但是有些时候仍然需要调用本地代码,这些代码通常是由C/C+编写,也可以是其它被支持的语言。 Oracle公司提供的JNI是Java平台的一个非常强大的接口。这个JNI接口提供了Java与操作系统本地代码相互调用的功能。,10,最简单的Java调用C/C+代码的步骤,首先在Java类中声明一个声明为native的方法。 使用Javah命令生成包含native方法声明的C/C+头文件。 按照生成的C/C+头文件来写C/C+源文件。 将C/C+源文件编译成动态连接库(DLL或者SO)。 将动态连接库(

8、DLL或者SO)加入PATH环境变量中。 Java类中加载动态连接库(DLL或者SO),然后调用声明的native方法。,11,最简单的Java调用C/C+代码的核心步骤示例,1,Java类文件: public class TestNative public native void sayHello(); public static void main(String args) System.loadLibrary(“nativeCode”); TestNative testNative = new TestNative(); testNative.sayHello(); 2,用Java的ja

9、vah工具生成头文件,主要内容如下: JNIEXPORT void JNICALL Java_TestNativesayHello(JNIEnv *, jobject); 3,C/C+实现文件(jni.h和jni_md.h) nativeCode.cpp JNIEXPORT void JNICALL Java_TestNativesayHello(JNIEnv *, jobject) cout“Hello JNI!”endl; 4,编译生成动态库文件(nativeCode.dll或者nativeCode.so),并加入Path中供Java加载使用,12,使用JNI的一些弊端,使用了JNI,那么

10、这个Java Application将不能跨平台了。如果要移植到其它平台上,那么native代码就需要重新编写。 Java是强类型的语言,而C/C+不是。因此,你必须在写JNI时更加小心。 很难调试出现在运行期间的错误 潜在的安全风险,13,使用JNI的一些好处,复用任何语言实现的本地功能 使用本地系统的API 提高程序的执行速度,尤其复用C/C+编写的功能,14,本地代码访问Java代码,在被调用的C/C+函数中可以反过来访问Java程序中的代码 Javah工具生成的C/C+函数声明中,可以看到两个参数: JNIEXPORT void JNICALL Java_sayHello(JNIEnv

11、 *env, jobject object) / ,15,JNIEnv类型,JNIEnv类型实际上代表了Java环境。通过JNIEnv*指针,就可以对Java端的代码进行操作。例如,创建Java类的对象,调用Java对象的方法,获取Java对象的属性等。 JNIEnv的指针会被JNI传入到 本地的实现函数中来,对Java端的代码进行操作。 JNIEnv中有很多函数可以使用: NewObject/NewString/NewArray Get/SetFile Get/SetStaticField CallMethod/CallStaticMethod 等许多函数,16,jobject解析,通过jn

12、i.h头文件可以看出:jobject其实是一个指针,对应于Java中对对象的引用;同时jni.h的定义也符合Java中一切皆继承Object原则。 如果Java中声明的是静态方法,则jobject传递的为类本身这个对象,即clz.class;如果使用的是非静态方法,则jobject传递的为类的实例化对象。,17,Java的类型在C/C+中的映射关系,见JNI.pptx第十页,18,jclass的取得,为了能够在C/C+中使用Java类,jni.h头文件中专门定义了jclass类型来表示Java中的Class类。 JNIEnv类中有如下几个简单的函数可以取得jclass: jclass Find

13、Class(const char* clsName); jclass GetObjectClass(jobject obj); jclass GetSuperClass(jclass obj); findClass会在classpath系统环境变量下寻找类。传入完整的类名,注意包与包之间使用/而不是.来分割。例如: jclass cls_string = env-FindClass(“java/lang/String”);,19,访问Java类中的属性与方法,在C/C+本地代码中访问Java端的代码,一个常见的应用就是获取类的属性和方法。为了能够在C/C+中表示属性和方法,JNI在jni.h头

14、文件中定义了jfieldID和jmethodID类型来分别代表Java端的属性和方法。 访问或设置Java属性的时候,首先要在本地代码中取得代表该Java属性的jfieldID,然后才能在本地代码中进行Java属性操作;同样的,在我们使用Java端的方法时,也需要取得代表该方法的jmethodID才能进行Java方法的调用。 使用JNIEnv的: GetFieldID/GetMethodID GetStaticFieldID/GetStaticMethodID 来取得相应的jfieldID和jmethodID,20,GetFieldID/GetStaticFieldIDGetMethodID/

15、GetStaticMethodID,GetFieldID(jclass clazz, const char* name, const char* sign); GetStaticFieldID(jclass clazz, const char* name, const char* sign); GetMethodID(jclass clazz, const char* name, const char* sign); GetStaticMethodID(jclass clazz, const char* name, const char* sign); GetMethodID也能够取得构造函数

16、的jmethodID。创建一个Java对象时可以调用指定的构造方法,例如:env-GetMethodID(data_Clazz, “”, “()V”); 类似Java的Reflect机制,需要指定类和属性/方法名来取得相应的jfieldID和jmethodID,ersign又是什么呢?,21,Sign是什么?,见JNI.pptx,22,Sign签名,见JNI.pptx,23,使用签名取得属性/方法ID的例子,见JNI.pptx,24,解析,对刚才的例子而言: 取得的property是int类型的,所以在签名中传入“I” 取得function的ID时: int function(int foo,

17、 Date date, int arr); ( I Ljava/util/Date;I) I,25,使用javap命令产生签名,JDK提供了javap这个工具来查看一个类的声明,可以通过javap设置输出每个属性/方法的签名。 Javap s p full Class Name -s表示输出签名信息 -p同-private,输出包括private访问权限的成员信息,26,取得Java属性/设置Java属性,见JNI.pptx,27,Java方法的调用,JNIEnv提供了众多的CallMethod和CallStaticMethod,还有CallNonvirtualMethod函数。需要通过Get

18、MethodID取得相应方法的jmethodID来传入到上述的函数中。 调用实例方法的三种形式: CallMethod(jobject obj, jmethodID id, ); CallMethodV(jobject obj, jmethodID id, va_list lst); CallMethodA(jobject obj, jmethodID id, jvalue* v); 第一种是最常用的方式; 第二种是当调用这个函数的时候有一个指向参数表的va_list变量时使用的; 第三种是当调用这个函数的时候有一个指向jvalue或者jvalue数组的指针时使用的。 调用静态方法的三种形式:

19、 CallMethod(jclass clazz, jmethodID id, ); CallMethodV(jclass clazz, jmethodID id, va_list lst); CallMethodA(jclass clazz, jmethodID id, jvalue* v);,28,其它的JNI内容,见JNI.ppx,29,Android中进程沟通的两种方式,使用BroadcastReceiver来相互传递Intent对象:很好的伸缩性,但是效率不高; Android提供的Ibinder界面:高效,特别适用于不同进程间频繁快速的传递数据。,30,以MediaPlayer为例

20、剖Android的JNI机制、Ibinder机制等之分析篇,Android框架已经提供 了MediaPlayer.java背后的.so,包括libmedia_jni.so、libmedia.so等。 分析分层结构和C/C+服务机制,31,以MediaPlayer为例剖Android的JNI机制、Ibinder机制等之Service篇,public class Mp3RemoteService extends Service private Ibinder mBinder = null; override public void onCreate() mBinder = new Mp3Binde

21、r(getApplicationContext); override public Ibinder onBind(Intent intent) return mBinder; ,32,以MediaPlayer为例剖Android的JNI机制、Ibinder机制等之Binder篇之一,public class Mp3Binder extends Binder private MediaPlayer mPlayer = null; private Context context; public Mp3Binder(Context context)this.contex = context Over

22、ride public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.osRemoteException reply.writeString(data.readString()+” mp3”); if (code = 1) this.play(); else if (code = 2) this.stop(); return true; ,33,以MediaPlayer为例剖Android的JNI机制、Ibinder机制等之Binder篇之二,public class Mp3B

23、inder extends Binder / public void play() if(mPlayer != null) return; mPlayer = MediaPlayer.create(context,R.raw,test_music); try mPlayer.start(); catch(Exception e)/. public void stop() if(mPlayer != null) mPlayer.stop(); mPlayer.release(); mPlayer = null; ,34,以MediaPlayer为例剖Android的JNI机制、Ibinder机制

24、等之使用篇之一,public class OperationActivity extends Activity implements OnClickListener private Ibinder ib = null; onCreate bindService(new Intent(), mConnection, Context.BIND_AUTO_CREATE); private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName classN

25、ame, Ibinder ibinder) ib = ibinder; public void onServiceDisconnected(ComponentName className) ,35,以MediaPlayer为例剖Android的JNI机制、Ibinder机制等之使用篇之二,public class OperationActivity extends Activity implements OnClickListener . public void onClick(View view) . Parcel pc = Parcel.obtain(); Parcel pc_reply

26、= Parcel.obtain(); pc.writeString(“Playing”); try ib.transact(1, pc, pc_reply, 0); pc_reply.readString(); catch(Exception e) e.printStackTrace(); ,36,以MediaPlayer为例剖Android的JNI机制、Ibinder机制等之配置篇,在AndroidManifest.xml下: ,37,对MediaPlayer示例的总结,基本结构:Java类别+*.so 常规升级方式:加入Service。 遵循Android的JNI等相关规范,使现有的C/C

27、+组件均能够加入Android体系,38,以MediaPlayer为例撰写C+层服务的Proxy及Stub之一,在跨进程通信中可以使用AIDL定义接口 AIDL定义产生的内容使用的依旧是Binder机制,只是方式不同而已。 AIDL这种跨进程方式也是非常高效的。 在Android SDK的/tools/中有一个aidl.exe工具,可以将接口定义文件(*.aidl)编译为支持跨进程(IPC)的Java接口,39,以MediaPlayer为例撰写C+层服务的Proxy及Stub之接口定义,Interface Mp3PlayerInterface void play(); void stop();

28、 ,40,以MediaPlayer为例撰写C+层服务的Proxy及Stub之aidl.exe编译接口,public interface Mp3PlayerInterface extends android.os.IInterface public Stub(). public static.asInterface(Ibinder obj) Proxy. ,41,以MediaPlayer为例撰写C+层服务的Proxy及Stub之Service和AIDL, Public class Mp3Service extends Servic Ibinder ib = null; onCreate() ib = new Mp3PlayerBinder(); onBind ,42,以MediaPlayer为例撰写C+层服务的Proxy及Stub之Binder的Stub,public class Mp3PlayerBinder extend

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论