美文网首页android收集Android干货Android之路
JNI其实很简单(一)之HelloWorld(Android S

JNI其实很简单(一)之HelloWorld(Android S

作者: Zach_C | 来源:发表于2016-12-21 20:12 被阅读173次

JNI(Java Native Interface)

目的:

** 实现了Java和其他语言(主要是c和c++)的通信**
通过JNI我们可以从java调用c/c++中的代码,或c/c++中调用java中的代码。

今天我们来看看JNI到底有多简单,根据国际惯例,我们先从HelloWorld开始,下面我们用java调用c中的方法。

前提:

  • NDK环境(具体怎么配置我这就不讲了,问Google和度娘都行)
  • 新建一个Android项目
    项目右击,打开Module Settings
open_module_settings.png

在Module Settings中配置ndk路径,如下图:

ndk_location.png

正文:

  • 新建一个JNI类,在里面写一个本地方法printHelloWorld,用来调用c中的函数
    <code>
    public class JNI {
    public native String printHelloWorld();
    }
    </code>

  • 生成c语言中与java中printHelloWorld方法匹配的函数,C语言方法的格式:<b>返回类型 Java_包名(包名用_代替原来的.)_类名</b>,这里我们可以使用<b>javah</b>命令防止我们将方法写错和在很多方法的情况下快速的生成。

  • 打开AS的Terminal,进入java目录下
    <code>cd /d D:\work\work_as\JNIDemo\app\src\main\java
    </code>


    进入java目录.png
  • 使用javah命令生成.h文件(javah -jni 包名.类名)
    <code>>javah -jni com.chen.jnidemo.JNI
    </code>


    进入java目录,使用javah命令.png
  • 刷新项目,你会发现在java目录下多了一个.h文件。


    javah命令之后.png
  • 在java目录下新建jni文件夹,在其中添加c文件

在java目录下添加JNI文件夹.png 新建c文件.png
  • 将生成的.h文件中的 <code>JNIEXPORT jstring JNICALL Java_com_chen_jnidemo_JNI_printHelloWorld (JNIEnv *, jobject);</code>方法复制到c文件中,实现该方法:
    <code>
    /#include <jni.h>
    JNIEXPORT jstring JNICALL Java_com_chen_jnidemo_JNI_printHelloWorld
    (JNIEnv env, jobject jobj) {
    return (
    env)->NewStringUTF(env, "Hello World");
    }
    </code>
jnitest.png
  • 在gradle.properties文件中添加<code>android.useDeprecatedNdk=true</code>

  • 在app下的build.gradle添加
    <code>
    defaultConfig {
    ...
    ndk {
    moduleName "jnitest"
    abiFilters "armeabi", "armeabi-v7a", "x86"
    }
    }</code>
    (注意:注意这里的moduleName,就是在类里面加载的so库名)

  • 在类中加载库名,使用System.loadLibrary("库名");
    <code>
    package com.chen.jnidemo;
    public class JNI {
    static {
    System.loadLibrary("jnitest");
    }
    public native String printHelloWorld();
    }
    </code>

  • 设置源码路径(可以不设置,不设置的话Rebuild Project,然后去app\build\intermediates\ndk\debug\lib下将各个版本的so文件拷到lib目录下,和我们平时导入so文件一样)
    <code>
    sourceSets.main {
    jni.srcDirs = ['src/main/jni']
    }
    </code>
    不设置源码路径时的so文件


    不设置源码路径.png
  • 在windows中的AS下ndk编译有一个bug,如果只有一个源文件(.C和.cpp文件,不算.h),则会编译错误,目前还没有修复,所以我们可以新建一个空的.c文件就可以编译通过了
empty.c.png
  • 代码中调用JNI中的方法
    <code>
    package com.chen.jnidemo;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Toast;
    public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.main_btn).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    showToast();
    }
    });
    }
    private void showToast() {
    JNI jni = new JNI();
    Toast.makeText(this, jni.printHelloWorld(), Toast.LENGTH_SHORT).show();
    }
    }

</code>

  • 完成


    完成.jpg

相关文章

网友评论

    本文标题:JNI其实很简单(一)之HelloWorld(Android S

    本文链接:https://www.haomeiwen.com/subject/twiqvttx.html