如何在Android下使用JNI

 我来答
huanglenzhi
2015-01-02 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517196
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  我们知道,Android系统的底层库由c/c++编写,上层Android应用程序通过Java虚拟机调用底层接口,衔接底层c/c++库与Java应用程序间的接口正是JNI(JavaNative Interface)。本文描述了如何在ubuntu下配置AndroidJNI的开发环境,以及如何编写一个简单的c函数库和JNI接口,并通过编写Java程序调用这些接口,最终运行在模拟器上的过程。

  2.环境配置

  2.1.安装jdk1.6
  (1)从jdk官方网站下载jdk-6u29-linux-i586.bin文件。
  (2)执行jdk安装文件
  [html] view plaincopyprint?
  01.$chmod a+x jdk-6u29-linux-i586.bin
  02.$jdk-6u29-linux-i586.bin
  $chmod a+x jdk-6u29-linux-i586.bin
  $jdk-6u29-linux-i586.bin
  (3)配置jdk环境变量

  [html] view plaincopyprint?
  01.$sudo vim /etc/profile
  02.#JAVAEVIRENMENT
  03.exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
  04.exportJRE_HOME=$JAVA_HOME/jre
  05.exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
  06.exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
  $sudo vim /etc/profile
  #JAVAEVIRENMENT
  exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
  exportJRE_HOME=$JAVA_HOME/jre
  exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
  exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
  保存后退出编辑,并重启系统。

  (4)验证安装

  [html] view plaincopyprint?
  01.$java -version
  02.javaversion "1.6.0_29"
  03.Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
  04.JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
  05.$javah
  06.用法:javah[选项]<类>
  07.其中[选项]包括:
  08.-help输出此帮助消息并退出
  09.-classpath<路径>用于装入类的路径
  10.-bootclasspath<路径>用于装入引导类的路径
  11.-d<目录>输出目录
  12.-o<文件>输出文件(只能使用-d或-o中的一个)
  13.-jni生成JNI样式的头文件(默认)
  14.-version输出版本信息
  15.-verbose启用详细输出
  16.-force始终写入输出文件
  17.使用全限定名称指定<类>(例
  18.如,java.lang.Object)。
  $java -version
  javaversion "1.6.0_29"
  Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
  JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
  $javah
  用法:javah[选项]<类>
  其中[选项]包括:
  -help输出此帮助消息并退出
  -classpath<路径>用于装入类的路径
  -bootclasspath<路径>用于装入引导类的路径
  -d<目录>输出目录
  -o<文件>输出文件(只能使用-d或-o中的一个)
  -jni生成JNI样式的头文件(默认)
  -version输出版本信息
  -verbose启用详细输出
  -force始终写入输出文件
  使用全限定名称指定<类>(例
  如,java.lang.Object)。2.2.安装android应用程序开发环境
  ubuntu下安装android应用程序开发环境与windows类似,依次安装好以下软件即可:
  (1)Eclipse
  (2)ADT
  (3)AndroidSDK
  与windows下安装唯一不同的一点是,下载这些软件的时候要下载Linux版本的安装包。
  安装好以上android应用程序的开发环境后,还可以选择是否需要配置emulator和adb工具的环境变量,以方便在进行JNI开发的时候使用。配置步骤如下:
  把emulator所在目录android-sdk-linux/tools以及adb所在目录android-sdk-linux/platform-tools添加到环境变量中,android-sdk-linux指androidsdk安装包android-sdk_rxx-linux的解压目录。
  [plain] view plaincopyprint?
  01.$sudo vim /etc/profile
  02.exportPATH=~/software/android/android-sdk-linux/tools:$PATH
  03. exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
  $sudo vim /etc/profile
  exportPATH=~/software/android/android-sdk-linux/tools:$PATH
  exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
  编辑完毕后退出,并重启生效。

  2.3.安装NDK
  NDK是由android提供的编译android本地代码的一个工具。
  (1)从androidndk官网下载ndk,目前最新版本为android-ndk-r6b-linux-x86.tar.bz2.
  (2)解压ndk到工作目录:
  [plain] view plaincopyprint?
  01.$tar -xvf android-ndk-r6b-linux-x86.tar.bz2
  02.$sudo mv android-ndk-r6b /usr/local/ndk
  $tar -xvf android-ndk-r6b-linux-x86.tar.bz2
  $sudo mv android-ndk-r6b /usr/local/ndk
  (3)设置ndk环境变量

  [plain] view plaincopyprint?
  01.$sudo vim /etc/profile
  02.exportPATH=/usr/local/ndk:$PATH
  $sudo vim /etc/profile
  exportPATH=/usr/local/ndk:$PATH

  编辑完毕后保存退出,并重启生效

  (4)验证安装

  [plain] view plaincopyprint?
  01.$ cd/usr/local/ndk/samples/hello-jni/
  02.$ ndk-build
  03.Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
  04.Gdbsetup : libs/armeabi/gdb.setup
  05.Install : libhello-jni.so => libs/armeabi/libhello-jni.so
  $ cd/usr/local/ndk/samples/hello-jni/
  $ ndk-build
  Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
  Gdbsetup : libs/armeabi/gdb.setup
  Install : libhello-jni.so => libs/armeabi/libhello-jni.so

  3.JNI实现
  我们需要定义一个符合JNI接口规范的c/c++接口,这个接口不用太复杂,例如输出一个字符串。接下来,则需要把c/c++接口的代码文件编译成共享库(动态库).so文件,并放到模拟器的相关目录下。最后,启动Java应用程序,就可以看到最终效果了。

  3.1.编写Java应用程序代码
  (1)启动Eclipse,新建android工程

  Project:JNITest

  Package:org.tonny.jni

  Activity:JNITest

  (2)编辑资源文件

  编辑res/values/strings.xml文件如下:

  [html] view plaincopyprint?
  01.<?xmlversionxmlversion="1.0"encoding="utf-8"?>
  02.<resources>
  03.<stringnamestringname="hello">HelloWorld, JNITestActivity!</string>
  04.<stringnamestringname="app_name">JNITest</string>
  05.<stringnamestringname="btn_show">Show</string>
  06.</resources>
  <?xmlversion="1.0"encoding="utf-8"?>
  <resources>
  <stringname="hello">HelloWorld, JNITestActivity!</string>
  <stringname="app_name">JNITest</string>
  <stringname="btn_show">Show</string>
  </resources>

  编辑res/layout/main.xml文件如下:

  [html] view plaincopyprint?
  01.<?xmlversionxmlversion="1.0"encoding="utf-8"?>
  02.<LinearLayoutxmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  03.android:layout_width="fill_parent"
  04.android:layout_height="fill_parent"
  05.android:orientation="vertical">
  06.<TextView
  07.android:layout_width="fill_parent"
  08.android:layout_height="wrap_content"
  09.android:text="@string/hello"/>
  10.<EditText
  11.android:id="@+id/ed_name"
  12.android:layout_width="match_parent"
  13.android:layout_height="wrap_content"
  14.android:layout_gravity="center_horizontal"
  15.android:layout_marginLeft="5dp"
  16.android:layout_marginRight="5dp"/>
  17.<Button
  18.android:id="@+id/btn_show"
  19.android:layout_width="109dp"
  20.android:layout_height="wrap_content"
  21.android:layout_gravity="center_horizontal"
  22.android:text="@string/btn_show"/>
  23.</LinearLayout>
  <?xmlversion="1.0"encoding="utf-8"?>
  <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical">
  <TextView
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="@string/hello"/>
  <EditText
  android:id="@+id/ed_name"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:layout_marginLeft="5dp"
  android:layout_marginRight="5dp"/>
  <Button
  android:id="@+id/btn_show"
  android:layout_width="109dp"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="@string/btn_show"/>
  </LinearLayout>

  我们在主界面上添加了一个EditText控件和一个Button控件。

  (3)编辑JNITest.java文件

  [java] view plaincopyprint?
  01.packageorg.tonny.jni;
  02.
  03.importandroid.app.Activity;
  04.importandroid.os.Bundle;
  05.importandroid.view.View;
  06.importandroid.widget.EditText;
  07.importandroid.widget.Button;
  08.
  09.
  10.publicclassJNITestextendsActivity {
  11.static{
  12.System.loadLibrary("JNITest");
  13.}
  14.privatenativeString GetReply();
  15.privateEditTextedtName;
  16.privateButtonbtnShow;
  17.Stringreply;
  18./**Called when the activity is first created. */
  19.@Override
  20.publicvoidonCreate(Bundle savedInstanceState) {
  21.super.onCreate(savedInstanceState);
  22.setContentView(R.layout.main);
  23.reply= GetReply();
  24.edtName= (EditText)this.findViewById(R.id.ed_name);
  25.btnShow= (Button)this.findViewById(R.id.btn_show);
  26.btnShow.setOnClickListener(newButton.OnClickListener() {
  27.publicvoidonClick(View arg0) {
  28.edtName.setText(reply);
  29.}
  30.});
  31.}
  32.}
  packageorg.tonny.jni;

  importandroid.app.Activity;
  importandroid.os.Bundle;
  importandroid.view.View;
  importandroid.widget.EditText;
  importandroid.widget.Button;

  publicclassJNITestextendsActivity {
  static{
  System.loadLibrary("JNITest");
  }
  privatenativeString GetReply();
  privateEditTextedtName;
  privateButtonbtnShow;
  Stringreply;
  /**Called when the activity is first created. */
  @Override
  publicvoidonCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  reply= GetReply();
  edtName= (EditText)this.findViewById(R.id.ed_name);
  btnShow= (Button)this.findViewById(R.id.btn_show);
  btnShow.setOnClickListener(newButton.OnClickListener() {
  publicvoidonClick(View arg0) {
  edtName.setText(reply);
  }
  });
  }
  }

  我们看这一段代码:

  [java] view plaincopyprint?
  01.static{
  02.System.loadLibrary("JNITest");
  03.}
  static{
  System.loadLibrary("JNITest");
  }

  static表示在系统第一次加载类的时候,先执行这一段代码,在这里表示加载动态库libJNITest.so文件。

  再看这一段:

  [java] view plaincopyprint?
  01.privatenativeString GetReply();
  privatenativeString GetReply();
  native表示这个方法由本地代码定义,需要通过jni接口调用本地c/c++代码。

  [java] view plaincopyprint?
  01.publicvoidonClick(View arg0) {
  02.edtName.setText(reply);
  03.}
  publicvoidonClick(View arg0) {
  edtName.setText(reply);
  }

  这段代码表示点击按钮后,把native方法的返回的字符串显示到EditText控件。

  (4)编译工程,生成.class文件。
QQMSD8
2015-12-14 · 知道合伙人软件行家
QQMSD8
知道合伙人软件行家
采纳数:6788 获赞数:13239
没有做不到,只有想不到,帮助别人的同时也是对自己的提升

向TA提问 私信TA
展开全部
Android中JNI是编译so库的源代码,编译成功后会生成SO库,android中最终是使用SO库的。
1.android的NDK开发需要在linux下进行: 因为需要把C/C++编写的代码生成能在arm上运行的.so文件,这就需要用到交叉编译环境,而交叉编译需要在linux系统下才能完成。
2.安装android-ndk开发包,这个开发包可以在google android 官网下载: 通过这个开发包的工具才能将android jni 的C/C++的代码编译成库
3.android应用程序开发环境: 包括eclipse、java、 android sdk、 adt等。

NDK编译步骤:
1.选择 ndk 自带的例子 hello-jni ,我的位于E:\android-ndk-r5\samples\hello-jni( 根据具体的安装位置而定 ) 。
2.运行 cygwin ,输入命令 cd /cygdrive/e/android-ndk-r5/samples/hello-jni ,进入到 E:\android-ndk-r5\samples\hello-jni 目录。
3.输入 $NDK/ndk-build ,执行成功后,它会自动生成一个 libs 目录,把编译生成的 .so 文件放在里面。 ($NDK是调用我们之前配置好的环境变量, ndk-build 是调用 ndk 的编译程序 )
4.此时去 hello-jni 的 libs 目录下看有没有生成的 .so 文件,如果有,ndk 就运行正常啦。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2015-01-02
展开全部
我们知道,Android系统的底层库由c/c++编写,上层Android应用程序通过Java虚拟机调用底层接口,衔接底层c/c++库与Java应用程序间的接口正是JNI(JavaNative Interface)。本文描述了如何在ubuntu下配置AndroidJNI的开发环境,以及如何编写一个简单的c函数库和JNI接口,并通过编写Java程序调用这些接口,最终运行在模拟器上的过程。
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
iku快开始
2017-04-30 · TA获得超过1.5万个赞
知道小有建树答主
回答量:2万
采纳率:18%
帮助的人:983万
展开全部
你可以用mm来编译指定模块,也就是你要实现的jni方法,编译成so文件供自己调用
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式