Android Studio 使用JNI入门

本文适合于在Android Studio使用JNI的新手,也适合于从Eclipse中转移到Android Studio过来的开发者。
本人见识有限,若有纰漏,欢迎批评指正。极客精神,人人共享~
1. 开发平台:
Operating System:Mac OS X 10.11.3
Software: Android Studio 1.5.1

2. 开始搭建JNI平台:
1)确保本地上已经有NDK:
如果没有,可以在Android NDK location处下载,或者在他处下载之后指定路径。

2)新建一个新的Module。
3)修改配置,打开如下图所示的三个文件:

在build.gradle(Android Studio Tab上显示为Module的名字)文件中添加ndk的说明:

moduleName是JNI库的名字,在此处JNI库的名字是“libmyjnitest.so”。
在gradle.properties文件的末尾添加“android.useDeprecatedNdk=true”。
在local.properties文件中注明路径:
一般Android Studio帮你做好了这些路径,你只要检查一下是否存在。
4)添加jni目录:
右击module,可以直接添加jni,如下图:

平台基本搭建完成,以下可以开始写代码了。
3. 新建一个Java文件作为具有native方法的测试类。
	/**
	 * Created by zhuozengsi on 3/6/16.
	 */
	public final class MyJNITest {
	
	    public static native String printSomething(String str);
	    public static native long calFromJNI(int n);
	
	    static {
	        System.loadLibrary("myjnitest");
	    }
	
	    public static long calFromJava(int n){
	        long sum = 0;
	        for (int i = 1; i <= n; i++){
	            sum += i;
	        }
	        return sum;
	    }
	
	}

我新建了一个MyJNITest 类,并在类中声明了两个native方法,并在static块中加载JNI库,注意:
该处的JNI库要和第2步中配置的ndk的moduleName相同。
4. Build -> Make Project 或者Build -> Make Module,目的是编译一下Java文件,生成class文件。
此时应该能在build/intermediates/classes/bebug 中看到编译成功的class文件,如下图所示:

5. 在terminal中将用cd命令将目录切换到build/intermediates/classes/bebug,然后执行以下命令:
javah -jni packageName.classFile
 packageName是包名称,classFile是具有native方法的Class文件,如此处的 MyJNITest应该为:
 javah -jni com.sige.test1.MyJNITest
执行成功的话,会在debug目录下生成一个头文件,此处是:com_sige_test1_MyJNITest.h,一般命名都是按照包名加类名来的,如下图。
将头文件剪切到创建的jni目录中。头文件的内容为:
	/* DO NOT EDIT THIS FILE - it is machine generated */
	#include <jni.h>
	/* Header for class com_sige_test1_MyJNITest */
	
	#ifndef _Included_com_sige_test1_MyJNITest
	#define _Included_com_sige_test1_MyJNITest
	#ifdef __cplusplus
	extern "C" {
	#endif
	/*
	 * Class:     com_sige_test1_MyJNITest
	 * Method:    printSomething
	 * Signature: (Ljava/lang/String;)Ljava/lang/String;
	 */
	JNIEXPORT jstring JNICALL Java_com_sige_test1_MyJNITest_printSomething
	  (JNIEnv *, jclass, jstring);
	
	/*
	 * Class:     com_sige_test1_MyJNITest
	 * Method:    calFromJNI
	 * Signature: (I)J
	 */
	JNIEXPORT jlong JNICALL Java_com_sige_test1_MyJNITest_calFromJNI
	  (JNIEnv *, jclass, jint);
	
	#ifdef __cplusplus
	}
	#endif
	#endif

6. 在jni目录中创建C文件或者创建C++文件,名字自定,我这里是:myjnitest.cpp。
将头文件中定义的方法复制到C/C++文件中,实现那些方法:
	//
	// Created by Zhuozengsi on 3/6/16.
	//
	#include "com_sige_test1_MyJNITest.h"
	#include <stdio.h>
	#include "test_cpp.h"
	JNIEXPORT jstring JNICALL Java_com_sige_test1_MyJNITest_printSomething
	        (JNIEnv * env, jclass clazz, jstring str){
	
	    printf("Hello, JNI");
	
	    //return env->NewString((const jchar *) str, sizeof(str));
	    return get_string(env);
	
	
	}
	
	JNIEXPORT jlong JNICALL Java_com_sige_test1_MyJNITest_calFromJNI
	        (JNIEnv *env, jclass, jint n){
	
	    jlong sum = 0;
	    for (int i = 1; i <= n; ++i) {
	        sum += n;
	    }
	    return sum;
	}


可以在该文件调用其他C/C++代码,如get_string(env)就是调用自己定义的函数。

7. 可以在其他地方调用native方法了。如在MainActivity中调用:
String strFromJNI = MyJNITest.printSomething("hello");
Log.i("TAG", "message from jni: " + strFromJNI);
输出结果为:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值