您的位置:首页 > 移动开发 > Android开发

JNI 在Android中的详细用法

2016-10-20 15:00 501 查看
jni在正常的Android开发中不是特别常用,所以你懂得,为了以后会用上,今天就在这里累一篇文章:

工具:pc 一台 Android Studio

第一步:配置开发环境,这个就不啰嗦了,网上大把大把的教程,百度一下你就知道;

第二步:新建JNI工程,上图!

没想到图片是这样的 新建工程

算了还是贴代码吧!

第三步:声明native方法,注意静态代码块的加载

package com.game.my.jnigongcheng;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public native void say();
}


配置gradle ndk

apply plugin: 'com.android.application'

android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
defaultConfig {
ndk {
moduleName "hello"
}
applicationId "com.game.my.jnigongcheng"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
}


第四步,执行生成头文件 javah 命令

打开下面的终端,输入命令: cd app\src\main\java

接着输入命令 : javah -jni com.game.my.jnigongcheng.MainActivity

后面的参数-jni 不要丢掉,接着的就是包含native方法的类名全称

第五步,新建jni目录,把上一步生成的头文件剪切进去,注意Android studio 2.2.2版本看到的是cpp目啥也不说了,上图:


第五步,配置gradle.properties文件,这个很重要哦!不然没有语法提示,还会报错

一定要加上 android.useDeprecatedNdk=true

一定要加上 android.useDeprecatedNdk=true

一定要加上 android.useDeprecatedNdk=true

好了不解释,重要的事情说三遍。

第六步,创建c文件

//
// Created by my on 2016/10/20.
//
#include "com_game_my_jnigongcheng_MainActivity.h"

JNIEXPORT void JNICALL Java_com_game_my_jnigongcheng_MainActivity_say
(JNIEnv *env, jobject obj){

}


第七步,调用native方法

package com.game.my.jnigongcheng;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
say();
}
public native void say();
}


到此,就完成了java调用c语言的方法了,赶紧运行下啊!

程序完美运行了!出现了hello world!可是……,狗日的,调用了C语言,怎么什么效果都没呢??

hold 住,现在我们添加一个方法——弹吐司!!

在代码中添加方法:

public void toast(){
Toast.makeText(this, "java from C", Toast.LENGTH_SHORT).show();
}


然后在c代码中找到这个方法后执行,上代码:

//
// Created by my on 2016/10/20.
//
#include "com_game_my_jnigongcheng_MainActivity.h"

JNIEXPORT void JNICALL Java_com_game_my_jnigongcheng_MainActivity_say
(JNIEnv *env, jobject obj){
//先找到类
jclass jcla = (*env)->FindClass(env,"com/game/my/jnigongcheng/MainActivity");
if(jcla == 0){
//没找到类,直接返回
return;
}
//再找方法。第一个参数不解释,第二个参数就是找到的class ,第三个参数是方法名,第四个参数是方法签名
jmethodID mid  = (*env)->GetMethodID(env,jcla,"toast","()V");
if(mid ==0){
//不解释
return;
}

//执行方法
(*env)->CallVoidMethod(env,obj,mid);
}


好了,点下锤子,运行下,吐司出来了!!可以看到,我们只是调用了say方法,而那个吐司是c代码里调用的!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息