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 ...
随机推荐
- java 实验2 类
共5道大题 最后一题为自动洗牌发牌系统 1) 编写一个类实现银行帐户的概念.包括的属性有:帐号.储户姓名.地址.存款余额,包括的方法有:存款.取款.查询.计算利息.累加利息等. public cla ...
- .NET clickonce修改发布名称等
见图
- 洛谷P3254 圆桌问题(最大流)
传送门 一道良心啊……没那么多麻烦了…… 从$S$向所有单位连边,容量为单位人数,从所有桌子向$T$连边,容量为桌子能坐的人数,从每一个单位向所有桌子连边,容量为$1$,然后跑一个最大流,看一看$S$ ...
- 基于openstack搭建百万级并发负载均衡器的解决方案
最近,喜欢研究一些国外技术大咖们的文章,而这篇文章是基于openstack负载均衡器的解决方案,做的一些总结~希望能够给小伙伴带来一些灵感或者帮助. openstack现有的负载均衡解决方案,无论是l ...
- 浅谈HTTP和TCP的理解
TCP协议对应于传输层,而Http协议对应于应用层,Http协议是建立在TCP协议之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求.HTTP会通过TCP建立一个连接通道,当HTT ...
- 百度地图中使用mouseover事件获取经纬度时无法拿到鼠标所在位置的经纬度。
用百度2.0的话使用mousemove 鼠标在地图区域移动过程中触发此事件.mouseover参数e中没有point参数
- js自定义对象 (转)
原文地址:https://sjolzy.cn/js-custom-object.html 29 March 2010 9:53 Monday by 小屋 javascript进阶之对象篇 一,概述 在 ...
- layer mobile开发layer.full
Layer For Mobile 之 layer.full() 背景介绍:layer mobile是专门针对手机页面开发的一套框架,具体介绍请看官方文档 http://layer.layui.com/ ...
- springcloud微服务总结二 注册中心
一:netflix和springcloud关系 netflix公司开源了很多组件,包括服务注册与发现(Netflix Eureka).断路器(Netflix Hystrix).负载均衡(Netflix ...
- JDK原生的HttpURLConnection请求实例
不想说啥,上代码! package com.my.https; import java.io.BufferedReader; import java.io.IOException; import ja ...