- 注册时间
- 2011-10-23
- 最后登录
- 2011-10-27
- 阅读权限
- 30
- 积分
- 434
- 精华
- 0
- 帖子
- 140
 
升级   78%
|
相关的主题文章:
再也不会有免费的面包跟牛奶
STUVVUVV
要经由良多战斗
谢里曼就本人挣钱营生
大家能够对比看
bail:
jint JNI_OnLoad(JavaVM* vm, void* reserved)
#ifdef __cplusplus
这请求VM去载入Android的/system/lib/libmedia_jni.so档案。载入*.so之后,Java类与*.so档案就会合起
来,一起履行了。
extern "C"
#endif
数组则以"["开端,用两个字符表示
};
import android.app.Activity;
setTitle("The Native Add Result is " + String.valueOf(cal.nadd(10, 19)));
arm-none-linux-gnueabi-gcc -I/home/a/work/android/jdk1.6.0_17/include -I/home/a/work/android/jdk1.6.0_17/include/linux -fpic -c com_hello_jnitest_Nadd.c
此外,在执行Java类的进程中,如果Java类需要与C组件沟通时,VM就会去载入C组件,然后让Java的函数顺利地调用到C组件的函数。此时,VM
扮演着桥梁的角色,让Java与C组件能通过尺度的JNI介面而彼此沟通。
当VM载入libmedia_jni.so档案时,就呼叫JNI_OnLoad()函数。接着,JNI_OnLoad()呼叫
register_android_media_MediaPlayer()函数。此时,就呼叫到
AndroidRuntime::registerNativeMethods()函数,向VM(即AndroidRuntime)登记
gMethods[]表格所含的本地函数了。简而言之,registerNativeMethods()函数的用途有二:
/** Called when the activity is first created. */
"()V"
package com.hello.jnitest;
*/
4.Andoird 中使用了一种不同传统Java JNI的方法来定义其native的函数。其中很重要的区别是Andorid使用了一种Java 和 C 函数的映射表数组,并在其中描述了函数的参数和返回值。这个数组的类型是JNINativeMethod,定义如下:
goto bail;
| |-- Android.mk
if (register_android_media_MediaMetadataRetriever(env) < 0)
#endif
"_reset", "()V", (void *)android_media_MediaPlayer_reset,
return (a+b);
I jint int
if ((*env)->MonitorExit(env, obj) != JNI_OK)
jnitest.java文件:
运用层级的Java种别透过VM而呼叫到本地函数。个别是仰赖VM去寻找*.so里的本地函数。如果需要持续呼叫很屡次,每次都需要寻找一遍,会多
花许多时光。此时,组件开发者能够自即将本地函数向VM进行登记。例如,在Android的/system/lib/libmedia_jni.so档案
里的代码段如下:
4 directories, 4 files
Ljava/lang/String; String jstring
字符 Java类型 C类型
例如 "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z"
对二中天生的so文件也可采取一中的方式push到avd中运行。
//#define LOG_NDEBUG 0
if (register_android_media_MediaPlayer(env) < 0) {
APP_PROJECT_PATH := $(call my-dir)/project
if (register_android_media_MediaPlayer(env) < 0)
assert(env != NULL);
LOGE("ERROR: MediaPlayer native registration failed\n");
"android/media/MediaPlayer", gMethods, NELEM(gMethods));
# See the License for the specific language governing permissions and
a@ubuntu:~/work/android/ndk-1.6_r1/apps$ tree myjni
LOCAL_SRC_FILES := myjni.c
#include <string.h>
jint result = -1;
"(II)V"
"_start", "()V", (void *)android_media_MediaPlayer_start,
D jdouble double
#endif
goto bail;
}
以上在windows中实现。
Android JNI编程实际
`-- project
{"native_setup", "(Ljava/lang/Object;)V",
# distributed under the License is distributed on an "AS IS" BASIS,
6.在eclipsh中运行原应用程序即可。
"_release", "()V", (void *)android_media_MediaPlayer_release,
goto bail;
/*
LOGE("ERROR: MediaMetadataRetriever native registration failed\n");
#
goto bail;
Java Native Interface (JNI)标准是java平台的一局部,它容许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码可能与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。
jint JNI_OnLoad(JavaVM* vm, void* reserved)
"prepare", "()V", (void *)android_media_MediaPlayer_prepare,
LOCAL_PATH := $(call my-dir)
(2)可在执行期间进行抽换。因为gMethods[]是一个<名称,函数指针>对比表,在程序执行时,可多次呼叫
registerNativeMethods()函数来调换本地函数之指针,而到达弹性抽换本地函数之目标。
4.编译.c文件生存动态库。
package com.hello.NdkTest;
public class MediaPlayer{
(1)更有效力去找到函数。
[I jintArray int[]
# Licensed under the Apache License, Version 2.0 (the "License");
(1)告知VM此C组件使用那一个JNI版本。如果你的*.so档不供给JNI_OnLoad()函数,VM会默认该*.so档是使用最老的
JNI 1.1版本。因为新版的JNI做了很多裁减,假如须要使用JNI的新版功效,例如JNI 1.4的java.nio.ByteBuffer,就必需藉由JNI_OnLoad()函数来告诉VM。
2.如何撰写*.so的进口函数
详细的每一个字符的对应关联如下
TextView tv = new TextView(this);
jint JNI_OnLoad(JavaVM* vm, void* reserved){
APP_MODULES := myjni
/* success -- return valid version number */
return (*env)->NewStringUTF(env, "Hello from My-JNI !");
if (register_android_media_MediaPlayer(env) < 0)
* Signature: (II)I
#ifdef __cplusplus
setContentView(R.layout.main);
`-- libs
"(Ljava/lang/String;Ljava/lang/String;)V"
}
static int register_android_media_MediaPlayer(JNIEnv *env)
#include "com_hello_jnitest_Nadd.h"
[S jshortArray short[]
#
例如,Android框架里所提供的MediaPlayer.java类,含指令:
利用层的Java类是在虚构机(VM: Vitual Machine)上执行的,而C件不是在VM上执行,那么Java程式又如何要求VM去载入(Load)所指定的C组件呢? 可应用下述指令:
3.编纂.c文件实现native方法。
(void *)android_media_MediaPlayer_setDataSource,
if (register_android_media_MediaScanner(env) < 0) {
return result;
由于VM通常是多执行绪(Multi-threading)的执行环境。每一个执行绪在呼叫JNI_OnLoad()时,所传递进来的JNIEnv
指标值都是不同的。为了配合这种多执行绪的环境,C组件开发者在撰写本地函数时,可藉由JNIEnv指标值之不同而防止执行绪的资料矛盾问题,才干确保所
写的本地函数能保险地在Android的多执行绪VM里平安地执行。基于这个理由,当在呼叫C组件的函数时,都会将JNIEnv指标值传递给它,如下:
Adb push libNadd.so /system/lib
例如,在register_android_media_MediaPlayer()函数里,可撰写下述指令:
jint JNI_OnLoad(JavaVM* vm, void* reserved)
(JNIEnv *, jobject, jint, jint);
#
"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition,
{
"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize,
* Method: nadd
Nadd.java文件:
JNIEXPORT jint JNICALL Java_com_hello_jnitest_Nadd_nadd
1.从如何载入.so档案谈起
{
jint JNI_OnLoad(JavaVM* vm, void* reserved){
JNI_OnUnload()函数与JNI_OnLoad()绝对应的。在载入C组件时会即时呼叫JNI_OnLoad()来进行组件内的初期动
作;而当VM开释该C组件时,则会呼叫JNI_OnUnload()函数来进行善后肃清动作。当VM呼叫JNI_OnLoad()或
JNI_Unload()函数时,都会将VM的指针(Pointer)传递给它们,其参数如下:
# you may not use this file except in compliance with the License.
# limitations under the License.
"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying,
} JNINativeMethod;
Android.mk文件:
"_pause", "()V", (void *)android_media_MediaPlayer_pause,
public native int& |
|