android JNI学习之一
执行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学习之一的更多相关文章
- Android JNI学习(五)——Demo演示
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- Android JNI学习(四)——JNI的常用方法的中文API
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- Android JNI学习(三)——Java与Native相互调用
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- Android JNI学习(二)——实战JNI之“hello world”
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- Android JNI 学习(一):JNI 简介
JNI 即 Java Native Interface 是 native 编程接口,它允许在Java虚拟机(VM)内运行Java代码与其他编程语言(主要是C和C++)编写的应用程序和库进行交互操作. ...
- Android JNI学习之javah命令的正确使用(找了好半天才找到的,汉,网上好多说法都没用)
按照网上抄来的javah用法一般出错,今天查了一下午在一篇文章(http://www.ibm.com/developerworks/cn/java/j-jtctips/part6/index2.htm ...
- Android JNI 学习(十一):Invocation Api
1. 简介 Invocation API允许软件提供商在原生程序中内嵌Java虚拟机.因此可以不需要链接任何Java虚拟机代码来提供Java-enabled的应用程序. 以下代码演示如何使用: #in ...
- Android JNI 学习(十):String Operations Api & Other Apis
一.String Operations(字符串操作) 1. NewString jstring NewString(JNIEnv *env, const jchar *unicodeChars, js ...
- Android JNI 学习(九):Static Fields Api & Static Methods Api
一.Accessing Static Fields(访问静态域) 1. GetStaticFieldID jfieldIDGetStaticFieldID(JNIEnv *env, jclass cl ...
随机推荐
- 类4(可变数据成员/基于const的重载)
可变数据成员: 有时我们希望能修改某个类的数据成员,即使是在一个 const 成员函数内.可以通过在变量的声明中加入 mutable 关键字来声明一个可变数据成员.mutable 是为突破 const ...
- 【bzoj2813】 奇妙的Fibonacci数列 线性筛
Description Fibonacci数列是这样一个数列: F1 = 1, F2 = 1, F3 = 2 . . . Fi = Fi-1 + Fi-2 (当 i >= 3) pty忽然对这个 ...
- 未来it行业发展方向
https://www.zhihu.com/question/24222456 IT行业,未来10年和20年,技术发展方向会是什么? 本人CS 本科刚毕业,正在选择工作方向.希望之后专注一个方向发展. ...
- linux系统安全及应用——端口扫描
NMAP是一款强大的网络扫描安全监测工具,通过扫描网络中不需要的服务端口来关闭这些服务,提高安全性.官网是http://nmap.org/,linux安装光盘中自带软件nmap-5.51.3.el6. ...
- SimpleDateFormat线程不安全及解决办法
原文链接:https://blog.csdn.net/csdn_ds/article/details/72984646 以前没有注意到SimpleDateFormat线程不安全的问题,写时间工具类,一 ...
- 【离散数学】 SDUT OJ 哪款赛车最佳?
哪款赛车最佳? Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 四名专家对四款赛车进行 ...
- TX2 Clone
由于给TX2配置了很多的开发环境,也修改了一些驱动,想将这些环境能够完整的迁移到一块bare TX2,于是尝试了clone的方法. 这种方法的优点是: 确保了移植的TX2 与已经配置好的环境是一致的: ...
- 网址访问量统计插件 FlagCounter
网址或博客访问量统计插件 ---> FlagCounter. 网址:http://s01.flagcounter.com/more/ERP2/
- String Reduction问题分析
问题描述: Given a string consisting of a,b and c's, we can perform the following operation: Take any two ...
- tornado 04 模板
一.模板 #模板就是一个HTML文件,只是其中添加了模板语法,需要服务器的渲染才能正常显示数据 #通过render可以返回一个html网页,不过那都是固定的页面,固定的数据,如果数据是不确定的,是会不 ...