执行System.loadLibrary()函数时,VM会反向调用*.so里的JNI_OnLoad()函数。用途有二:
1. VM询问此*.so使用的JNI版本编号。
2. VM要求*.so做一些初期设定工作(Initialization),例如登记<函数名称表>。

•例如,在Android的jniload.so档案里,就提供了JNI_OnLoad()函数,其程序码片段为:

/* com.misoo.counter.CounterNative.cpp */
#include <stdio.h>
#include<jni.h>
#include <pthread.h>
#include<android/log.h>
#include "com_misoo_counter_CounterNative.h"
//LOGE("ERROR: GetEnv failed\n");
#define LOGE(x) __android_log_print(ANDROID_LOG_INFO,TAG,(x))
jmethodID mid;
jclass mClass;
JavaVM *jvm;
pthread_t thread;
int n, sum;
const char *TAG="JniTest";
//int ANDROID_LOG_INFO= 0;
void* trRun(void*);
void JNICALL Java_com_misoo_counter_CounterNative_nativeSetup(JNIEnv *env,
jobject thiz) {
jclass clazz = env->GetObjectClass(thiz);
mClass = (jclass) env->NewGlobalRef(clazz);
mid = env->GetStaticMethodID(mClass, "callback", "(I)V");
}
void JNICALL Java_com_misoo_counter_CounterNative_nativeExec(JNIEnv *env,
jobject thiz, jint numb) {
n = numb;
pthread_create(&thread, NULL, trRun, NULL);
}
void* trRun(void*) {
int status;
JNIEnv *env;
bool isAttached = false;
status = jvm->GetEnv((void **) &env, JNI_VERSION_1_4);
if (status < ) {
status = jvm->AttachCurrentThread(&env, NULL);
if (status < )
return NULL;
isAttached = true;
}
sum = ;
for (int i = ; i <= n; i++)
sum += i;
env->CallStaticVoidMethod(mClass, mid, sum);
if (isAttached)
jvm->DetachCurrentThread();
return NULL;
} static const char *classPathName = "com/misoo/counter/CounterNative";
static JNINativeMethod methods[] = { { "init", "()V",
(void *) Java_com_misoo_counter_CounterNative_nativeSetup }, {
"execute", "(I)V",
(void *) Java_com_misoo_counter_CounterNative_nativeExec } };
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods) {
__android_log_print(ANDROID_LOG_INFO,TAG,"registerNativeMethods");
if(env == NULL)
__android_log_print(ANDROID_LOG_INFO,TAG,"env is null");
jclass clazz = env->FindClass(className);
__android_log_print(ANDROID_LOG_INFO,TAG,"find class");
__android_log_print(ANDROID_LOG_INFO,TAG,"%s",className);
env->RegisterNatives(clazz, gMethods, numMethods);
__android_log_print(ANDROID_LOG_INFO,TAG,"end registerNativeMethods");
return JNI_TRUE;
}
static int registerNatives(JNIEnv* env) {
__android_log_print(ANDROID_LOG_INFO,TAG,"registerNatives");
registerNativeMethods(env, classPathName, methods,
sizeof(methods) / sizeof(methods[]));
__android_log_print(ANDROID_LOG_INFO,TAG,"end registerNatives");
return JNI_TRUE;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
__android_log_print(ANDROID_LOG_INFO,TAG,"JNI_OnLoad");
JNIEnv *env = NULL;
jvm = vm;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed\n");
// return -1;
}
// assert(env == NULL);
if (registerNatives(env) != JNI_TRUE)
return -;
__android_log_print(ANDROID_LOG_INFO,TAG,"JNI_OnLoad end");
return JNI_VERSION_1_4;
}

Android.mk文件是:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog
LOCAL_MODULE :=jniload
LOCAL_SRC_FILES :=archMultiThread.cpp include $(BUILD_SHARED_LIBRARY)

Application.mk文件:

APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions
APP_ABI:=armeabi armeabi-v7a
APP_PLATFORM=android-8

CounterNative.java

package com.misoo.counter;

import com.example.hellondk.MainActivity;

import android.os.Handler;
import android.os.Message;
import android.util.Log; //CounterNative.java
// ………
public class CounterNative {
private static Handler h;
public static final String TAG = "JniTest";
static {
Log.i(CounterNative.TAG, "try to load libMyJT002.so");
System.loadLibrary("jniload");
Log.i(CounterNative.TAG, "end try to load libMyJT002.so");
} public CounterNative() {
Log.i(CounterNative.TAG, "new CounterNative");
init();
Log.i(CounterNative.TAG, "init finished"); h = new Handler() {
public void handleMessage(Message msg) {
MainActivity.ref.setTitle("Hello …");
}
};
} private static void callback(int a) {
Message m = h.obtainMessage(1, a, 3, null);
h.sendMessage(m);
} private native void init(); public native void execute(int numb);
}
package com.example.hellondk;

import java.sql.Ref;

import com.huml.ndk1.NativeJniAdder;
import com.misoo.counter.CounterNative; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View; public class MainActivity extends Activity {
public static MainActivity ref = null;
CounterNative obj;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ref= this;
Log.i(CounterNative.TAG, "onCreate");
obj = new CounterNative();
} //对应一个Button的onClick事件,布局文件中一个Button按钮,布局文件很简单我就不列出来了
public void TestNDK(View view){
Log.i(NativeJniAdder.TAG, "start NDK");
obj.execute(11);
} }

android JNI学习之一的更多相关文章

  1. Android JNI学习(五)——Demo演示

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  2. Android JNI学习(四)——JNI的常用方法的中文API

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  3. Android JNI学习(三)——Java与Native相互调用

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  4. Android JNI学习(二)——实战JNI之“hello world”

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  5. Android JNI 学习(一):JNI 简介

    JNI 即 Java Native Interface 是 native 编程接口,它允许在Java虚拟机(VM)内运行Java代码与其他编程语言(主要是C和C++)编写的应用程序和库进行交互操作. ...

  6. Android JNI学习之javah命令的正确使用(找了好半天才找到的,汉,网上好多说法都没用)

    按照网上抄来的javah用法一般出错,今天查了一下午在一篇文章(http://www.ibm.com/developerworks/cn/java/j-jtctips/part6/index2.htm ...

  7. Android JNI 学习(十一):Invocation Api

    1. 简介 Invocation API允许软件提供商在原生程序中内嵌Java虚拟机.因此可以不需要链接任何Java虚拟机代码来提供Java-enabled的应用程序. 以下代码演示如何使用: #in ...

  8. Android JNI 学习(十):String Operations Api & Other Apis

    一.String Operations(字符串操作) 1. NewString jstring NewString(JNIEnv *env, const jchar *unicodeChars, js ...

  9. Android JNI 学习(九):Static Fields Api & Static Methods Api

    一.Accessing Static Fields(访问静态域) 1. GetStaticFieldID jfieldIDGetStaticFieldID(JNIEnv *env, jclass cl ...

随机推荐

  1. BST_insert

    #include <stdio.h> /* printf, scanf, NULL */ #include <stdlib.h> /* malloc, free */ stru ...

  2. Nagios监控平台搭建及配置文件详解

    Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员, ...

  3. win7/win8/win10 系统

    WIN7/WIN8/WIN10 系统安装 http://www.windows7en.com/Win7/18572.html

  4. Spring学习笔记(一)—— Spring介绍及入门案例

    一.Spring概述 1.1 Spring是什么 Spring是一个开源框架,是于2003年兴起的一个轻量级的Java开发框架, 由Rod Johnson 在其著作<Expert one on ...

  5. Codeforces Round #549 (Div. 2) Solution

    传送门 A.The Doors 看懂题目就会写的题 给一个 $01$ 序列,找到最早的位置使得 $0$ 或 $1$ 已经全部出现 #include<iostream> #include&l ...

  6. HDU - 1085 母函数

    年轻人的第一道母函数入门题 #include<bits/stdc++.h> using namespace std; const int maxn = 1000+2000+5000+1; ...

  7. 详解Oracle hints PQ_DISTRIBUTE

    PQ_DISTRIBUTE是并行的hints中稍微复杂一点的一个 下面就这个hints做以下说明: 1.使用格式 /+ PQ_DISTRIBUTE(tablespec outer_distributi ...

  8. maven-javadoc-plugin

    <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javad ...

  9. PIE SDK定向滤波

    1. 算法功能简介 定向滤波又称为匹配滤波,是通过一定尺寸的方向模板对图像进行卷积计算,并以卷积值代替各像元点灰度值,强调的是某一些方向的地面形迹,例如水系.线性影像等. 方向模板是一个各元素大小按照 ...

  10. 7.使用jenkins+marathon+docker完成自动化部署

    1.前置条件 1)Docker开启TCP端口,CloudBees Docker Build and Publish plugin插件会向目标主机docker生成docker镜像 开启docker ap ...