导航:首页 > 操作系统 > androidjni线程

androidjni线程

发布时间:2024-06-02 09:25:08

⑴ 濡备綍鍦╝ndroid镄刯ni绾跨▼涓瀹炵幇锲炶皟

鎭ㄥソ锛屽緢楂桦叴鑳藉府锷╂偍濡傛灉鏄疌/C++锲炶皟,浣犲彧瑕佸弬钥僱inux镄勭嚎绋嬫寚鍗楋纴鍦ㄧ嚎绋嫔嚱鏁颁腑浼犲叆锲炶皟鍑芥暟鍦板潃灏辫屼简銆傚傛灉鏄瑕佸洖璋冨埌java灞傦纴绋嶅井澶嶆潅镣广傞栧厛锛屼綘闇瑕佸湪onload镄勬椂鍊欙纴镓惧埌锲炶皟鍑芥暟镓鍦ㄧ殑绫伙纴鐢ㄥ叏灞鍙橀噺淇濆瓨锛钦NIEXPORTjintJNICALLJNI_OnLoad(JavaVM*vm,void*reserved){LOGE("JNI_OnLoadstart");jintversion;g_vm=vm;//鍏ㄥ眬鍙橀噺淇濆瓨JNIEnv*env;jobjectcls;version=vm->GetEnv((void**)&env,JNI_VERSION_1_2);if(env){g_clazz=env->FindClass(CLASS_CustomSurfaceView);//鍏ㄥ眬鍙橀噺淇濆瓨}LOGE("JNI_OnLoadfinishg_clazz=0x%x",g_clazz);returnJNI_VERSION_1_2;}鍦↗NI钖锷ㄧ嚎绋嬬殑镞跺欙纴闇瑕佹妸绾跨▼鎸傚埌JVM涓婏纴涓岖劧涓嶈兘璁块梾Java銆备綘链変简g_vm,g_clazz,浠ュ强env锛屽氨鍙浠ュ仛锲炶皟镎崭綔浜嗐//绾跨▼鍑芥暟void*threadFunc(void*data){JNIEnv*env=MNull;intret=g_vm->AttachCurrentThread((JNIEnv**)&env,MNull);//鎸傚埌JVMif(retDetachCurrentThread();//浠嶫VM鍗歌浇return;}浣犵殑閲囩撼鏄鎴戝墠杩涚殑锷ㄥ姏锛岃板缑濂借瘎鍜岄噰绾筹纴绛旈树笉鏄掳纴浜掔浉甯锷╋纴

⑵ 如何在android下使用JNI

1.引言
我们知道,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 plainprint?
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 plainprint?
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 plainprint?
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 plainprint?
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官网http://developer.android.com/sdk/ndk/index.html下载ndk,目前最新版本为android-ndk-r6b-linux-x86.tar.bz2.
(2)解压ndk到工作目录:
[plain] view plainprint?
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 plainprint?
01.$sudo vim /etc/profile
02.exportPATH=/usr/local/ndk:$PATH
$sudo vim /etc/profile
exportPATH=/usr/local/ndk:$PATH

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

(4)验证安装

[plain] view plainprint?
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文件如下:编辑res/layout/main.xml文件
我们在主界面上添加了一个EditText控件和一个Button控件。

(3)编辑JNITest.java文件


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

再看这一段:

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

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

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

(4)编译工程,生成.class文件。

3.2.用javah工具生成符合JNI规范的c语言头文件

在终端中,进入android工程所在的bin目录

[plain] view plainprint?
01.$cd ~/project/Android/JNITest/bin
$cd ~/project/Android/JNITest/bin
我们用ls命令查看,可以看到bin目录下有个classes目录,其目录结构为classes/org/tonny/jni,即classes的子目录结构是android工程的包名org.tonny.jni。请注意,下面我们准备执行javah命令的时候,必须进入到org/tonny/jni的上级目录,即classes目录,否则javah会提示找不到相关的java类。

下面继续:

[plain] view plainprint?
01.$cd classes
02.$javah org.tonny.jni.JNITest
03.$ls
04.org org_tonny_jni_JNITest.h
$cd classes
$javah org.tonny.jni.JNITest
$ls
org org_tonny_jni_JNITest.h

执行javahorg.tonny.jni.JNITest命令,在classes目录下会生成org_tonny_jni_JNITest.h头文件。如果不进入到classes目录下的话,也可以这样:

[plain] view plainprint?
01.$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest
$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest
-classpath 参数表示装载类的目录。

3.3.编写c/c++代码
生成org_tonny_jni_JNITest.h头文件后,我们就可以编写相应的函数代码了。下面在android工程目录下新建jni目录,即~/project/Android/JNITest/jni,把org_tonny_jni_JNITest.h头文件拷贝到jni目录下,并在jni目录下新建org_tonny_jni_JNITest.c文件,编辑代码如下:

[cpp] view plainprint?
01.#include<jni.h>
02.#include<string.h>
03.#include"org_tonny_jni_JNITest.h"
04.
05.
06.JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply
07.(JNIEnv *env, jobject obj){
08.return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");
09.}
#include<jni.h>
#include<string.h>
#include"org_tonny_jni_JNITest.h"

JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply
(JNIEnv *env, jobject obj){
return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");
}

我们可以看到,该函数的实现相当简单,返回一个字符串为:"Hello,JNITest"

3.4.编写Android.mk文件
在~/project/Android/JNITest/jni目录下新建Android.mk文件,android可以根据这个文件的编译参数编译模块。编辑Android.mk文件如下:

[plain] view plainprint?
01.LOCAL_PATH:= $(call my-dir)
02.include$(CLEAR_VARS)
03.LOCAL_MODULE := libJNITest
04.LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c
05.include$(BUILD_SHARED_LIBRARY)
LOCAL_PATH:= $(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE := libJNITest
LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c
include$(BUILD_SHARED_LIBRARY)

LOCAL_MODULE表示编译的动态库名称

LOCAL_SRC_FILES 表示源代码文件

3.5.用ndk工具编译并生成.so文件
进入到JNITest的工程目录,执行ndk-build命令即可生成libJNITest.so文件。

[plain] view plainprint?
01.$cd ~/project/Android/JNITest/
02.$ndk-build
03.Invalidattribute name:
04.package
05.Install : libJNITest.so => libs/armeabi/libJNITest.so
$cd ~/project/Android/JNITest/
$ndk-build
Invalidattribute name:
package
Install : libJNITest.so => libs/armeabi/libJNITest.so
可以看到,在工程目录的libs/armeabi目录下生成了libJNITest.so文件。

3.6.在模拟器上运行
(1)首先,我们把android模拟器启动起来。进入到emulator所在目录,执行emulator命令:

[plain] view plainprint?
01.$cd ~/software/android/android-sdk-linux/tools
02.$./emulator @AVD-2.3.3-V10 -partition-size 512
$cd ~/software/android/android-sdk-linux/tools
$./emulator @AVD-2.3.3-V10 -partition-size 512
AVD-2.3.3-V10表示你的模拟器名称,与在Eclipse->AVDManager下的AVDName对应,-partition-size表示模拟器的存储设备容量。

(2)接下来,我们需要把libJNITest.so文件拷贝到模拟器的/system/lib目录下,执行以下命令:

[plain] view plainprint?
01.$cd ~/project/Android/JNITest/libs/armeabi/
02.$adb remount
03.$adb push libJNITest.so /system/lib
04.80 KB/s (10084 bytes in 0.121s)
$cd ~/project/Android/JNITest/libs/armeabi/
$adb remount
$adb push libJNITest.so /system/lib
80 KB/s (10084 bytes in 0.121s)

当在终端上看到有80 KB/s (10084 bytes in 0.121s)传输速度等信息的时候,说明拷贝成功。

(3)在终端上执行JNITest程序,这个我们可以在Eclipse下,右键点击JNITest工程,RunAs->Android Application,即可在模拟器上启动程序

⑶ android开发中线程有几种状态,分别是哪些

【答案】:1)、新建状态(New):新创建了一个线程对象。
2)、就绪状态(Runnable):线程对象创建后,前蚂消其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3)、运行状态(Running):就绪状态的线程获取了CPU,执行run()方法。
4)、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞慧知:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁物卜池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5)、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
当调用start方法的时候,该线程就进入就绪状态。等待CPU进行调度执行,此时还没有真正执行线程。
当调用run方法的时候,是已经被CPU进行调度,执行线程的主要任务。

阅读全文

与androidjni线程相关的资料

热点内容
程序员预研的项目 浏览:342
新华保险服务器登录不上怎么回事 浏览:391
气温高时汽车空调压缩机振动 浏览:559
分配器python 浏览:222
outlook服务器怎么查询 浏览:400
python预测疫情代码 浏览:982
普通化学原理pdf 浏览:908
java的圣经 浏览:41
python遍历两个数组 浏览:396
手游搭建云服务器 浏览:401
视易锋云服务器启动黑屏 浏览:139
python怎么获取网页a标签内容 浏览:982
app更新后老的安装包去哪里了 浏览:199
集合运算法则差集 浏览:310
x2pdf 浏览:271
python源码cs 浏览:101
数控机床自动编程软件 浏览:738
方舟的服务器号是什么 浏览:111
没有服务器怎么发现其他节点 浏览:337
文明传奇怎么开服务器 浏览:57