写在前面的话:
?? 这篇文章很早就发表在我自己原先的那个blog中,因为忍受不了原先blog的乱码问题所以才在这里开了这个blog,现在把它正式地移到这个blog上来,不要说我抄袭哦^-^。
?
练习:从jni层获得一个字符串,在屏幕上显示,当然是手机屏幕
要求:
1.需要包含三层结构:JNI, java framework, java application
2.字符串的内容为“Hello from JNI !”,必须在JNI层定义
这个练习是在Android的源码工程下做的,我的Android源代码路径为/Android/android-1.6_r2
开工:
1.?
JNI层
:在
/Android/android-1.6_r2/frameworks/base/core/jni
路径下创建例子
android_mytest_hellojni.cpp
文件,这个文件就是在
JNI
层实现接口。文件内容如下:(可参考同一目录下的
android_debug_JNITest.cpp
文件编写)
#
define
LOG_TAG "HelloJNI"
#
include
"jni.h"
#
include
"nativehelper/JNIHelp.h"
#
include
"utils/Log.h"
#
include
"utils/misc.h"
namespace
android {
static
jstring android_mytest_hellojni_displayString(
JNIEnv *
env,
jclass clazz)
{
?return
env-
>
NewStringUTF(
"Hello from JNI!"
)
;
}
/*
?* JNI registration.
?*/
static
JNINativeMethod gMethods[
]
=
{
????/* name, signature, funcPtr */
????{
"displayString"
,
"()Ljava/lang/String;"
,
????????????(
void
*
)
android_mytest_hellojni_displayString }
,
???? }
;
int
register_android_mytest_hellojni(
JNIEnv*
env)
{
//此处的目录结构就是在Javaframework层的文件目录,且必须一致
return
jniRegisterNativeMethods(
env,
"android/mytest/hellojni"
,
????????gMethods,
NELEM(
gMethods)
)
;
}
}
;
|
2.
JNI
层:对编译的修改配置
? 2.1修改/Android/android-1.6_r2/frameworks/base/core/jni目录下的Android.mk
文件,在LOCAL_SRC_FILES:= \
下面加上
android_mytest_hellojni.cpp \
?? 2.2修改/Android/android-1.6_r2/frameworks/base/core/jni目录下的AndroidRuntime.cpp
文件在extern int
后面添加
extern int register_android_mytest_hellojni(JNIEnv* env);
然后在static const RegJNIRec gRegJNI[] =
{下面添加
REG_JNI(register_android_mytest_hellojni),
这样,JNI层的修改就到此为止了。
?
3. ?
Javaframework
层:在
/Android/android-1.6_r2/frameworks/base/core/java/android/
新建文件目录
mytest
,在该目录下新建文件
hellojni.java
声明接口。内容如下:(可以参考
android-1.6_r2/frameworks/base/core/java/android/debug
目录下的
JNITest.java
文件编写)
package
android.
mytest;
public
class
hellojni{
????public
hellojni(
)
{
}
//此处声明为public所以才可以被application调用
????public
static
native
String
displayString(
)
;
}
|
4
.下面我们要对我们做过更改的
libandroid_runtime.so
和
framework.jar
进行重新编译。
在源代码工程目录下输入
make libandroid_runtime
重新编译生成
libandroid_runtime.so
…
target thumb C++: libandroid_runtime <= frameworks/base/core/jni/android_mytest_hellojni.cpp
target thumb C++: libandroid_runtime <= frameworks/base/core/jni/AndroidRuntime.cpp
target
SharedLib: libandroid_runtime
(out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_runtime_intermediates/LINKED/libandroid_runtime.so)
target Prelink: libandroid_runtime (out/target/product/generic/symbols/system/lib/libandroid_runtime.so)
target Strip: libandroid_runtime (out/target/product/generic/obj/lib/libandroid_runtime.so)
Install: out/target/product/generic/system/lib/libandroid_runtime.so
然后再输入
make framework
重新编译生成
framework.jar
…
Install: out/target/product/generic/system/framework/framework.jar
5. ?
然后在
eclipse
里面或者在记事本等编辑器(这么说只是为了说明只需要源代码),新建
Android project
,例子的结构如下:
在
testApp.java
文件中的内容如下:
package
com.
integration.
test;
import
android.
app.
Activity
;
import
android.
os.
Bundle;
import
android.
widget.
TextView;
//需要import自己定义的包,包名可以根据文件目录结构得到
import
android.
mytest.
hellojni;
public
class
testAPP extends
Activity
{
????/** Called when the activity is first created. */
????private
TextView tv;
????@Override
????public
void
onCreate(
Bundle savedInstanceState)
{
????????super
.
onCreate(
savedInstanceState)
;
????????setContentView(
R.
layout
.
main)
;
????????tv =
(
TextView)
findViewById(
R.
id
.
tv)
;
????????hellojni hello =
new
hellojni(
)
;
//调用自己写的JNI
????????tv.
setText
(
hello.
displayString(
)
+
""
)
;
????}
}
|
然后将上述文件复制到
/Android/android1.6_r2/packages/apps
,然后看教程《在源码中编译自己的
Android project
》就可以在模拟器中看到该应用运行如下图: