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 ...
随机推荐
- 品味ZooKeeper之Watcher机制_2
品味ZooKeeper之Watcher机制 本文思维导图如下: 前言 Watcher机制是zookeeper最重要三大特性数据节点Znode+Watcher机制+ACL权限控制中的其中一个,它是zk很 ...
- bdd相关整理介绍
BDD介绍 什么是BDD Behavior-driven development In software engineering, behavior-driven development (BDD) ...
- HTTP原理 请求方法
HTTP的工作过程 一次HTTP操作称为一个事务,其工作过程分为四步: 1.客户机与服务器建立连接:客户单击某个超级链接,HTTP的工作开始,接下来进行TCP连接的三次握手过程. 2.建立连接后,客户 ...
- P2468 [SDOI2010]粟粟的书架
传送门 二合一题.... 前面 $50$ 分: 考虑取书显然优先取厚的,所以答案满足单调性 发现 $P_{i,j}$ 不大,所以考虑二分最小厚度 $mid$,把大于等于 $mid$ 的书取走 维护 $ ...
- AtCoder Beginner Contest 113 A
A - Discount Fare Time limit : 2sec / Memory limit : 1024MB Score: 100 points Problem Statement Ther ...
- BZOJ - 3757 树上莫队解决离线路径问题 & 学习心得
题意:给你一棵树,求u,v最短路径的XXX(本题是统计权值种类) 今天课上摸鱼学了一种有意思的处理路径方式(其实是链式块状树翻车了看别的),据说实际运行跑的比XX记者还快 大概就是像序列莫队那样 首先 ...
- 关于vue2非表单元素使用contenteditable="true"实现textarea高度自适应
<template> <div ref="sendContent" contenteditable="true" v-html="s ...
- scrapy模块之分页处理,post请求,cookies处理,请求传参
一.scrapy分页处理 1.分页处理 如上篇博客,初步使用了scrapy框架了,但是只能爬取一页,或者手动的把要爬取的网址手动添加到start_url中,太麻烦接下来介绍该如何去处理分页,手动发起分 ...
- 【研究】Metasploit自动攻击模块
环境:kali-linux-2017.3-vm-amd64 一.安装postgresql数据库 apt-get install postgresql apt-get install rubygems ...
- 2019.3.13 Java实现分数的四则运算
Java实现分数的四则运算 自己的写法 markdown太久没写格式不会用了--将就着看 Fraction.java package com.lanou; public class Fraction ...