Android studio使用JNI实例(1)

注意:本人是初学Android开发,Android studio开发环境也是第一次使用,在本文及Android开发系列文章中均为本人个人的见解及网络资料,为自己的学习笔记,同时给初学者提供参考,不正确之处还望包含指正!

前言

本文Android studio使用JNI实例为最基础的JNI使用方法(不使用外部so库,使用外部so库将在ndroid studio使用JNI实例(2)中介绍),本文从新建工程开始记录其过程。
本例参考网络资料呕心沥血Android studio使用JNI实例而完成,该资料很详细,本人是按照其文章介绍的步骤完成该实例,其过程很详细,但是按照其方法在Windows7环境下没有编译成功,在Ubuntu 16.04下顺利编译通过,Ubuntu下环境也只是安装了Android studio、SDK和NDK,并没有其他特殊软件或配置,应该是Windows7系统环境的问题。

本例开发环境:

名称 版本号
系统版本 Ubuntu 16.04.05 64Bit
Android studio 2.3.3
SDK 24.4.1
NDK 14

Android studio使用JNI实例(1)_第1张图片

JNI实例

新建APK工程

新建工程名为HelloJni的APK工程:
Android studio使用JNI实例(1)_第2张图片
点击“Next”后选择Android版本,我选择的是5.0,具体与自己的平台一致:
Android studio使用JNI实例(1)_第3张图片
点击“Next”后选择Activity模板,此处选择“Empyt Activity”:
Android studio使用JNI实例(1)_第4张图片
点击“Next”后填写Activity Name,此处用默认的即可:
Android studio使用JNI实例(1)_第5张图片
点击“Finish”完成工程创建,创建完成后界面如下:
Android studio使用JNI实例(1)_第6张图片

JNI接口及实现

创建Native方法类

新建一个类(类名随意,此处为myJNI),声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。新建类内容如下:

public class myJNI {
    //load library
    static {
        System.loadLibrary("JniTest");
    }

    //native interface
    public static native String sayHello();
}

Android studio使用JNI实例(1)_第7张图片

生成class文件

打开Android studio终端(菜单栏View -> Tool Windows -> Terminal或使用快捷键Alt+F12),使用javac编译上述文件,生成class文件。
生成class文件命令:

$cd app/src/main/java/com/example/linux/hellojni/
$javac myJNI.java

此时就会生成myJNI.class文件:
Android studio使用JNI实例(1)_第8张图片

生成.h文件

后在上一级的位置使用javah生成.h头文件。一定要在上一级(并非上级目录,而是工程上的目录结构(从上边的几张截图的工程结构中可以知道工程结构),即java目录),不然不会报错:找不到xxx类。
比如我的myJNI.class在

/home/linux/AndroidStudioProjects/HelloJni/app/src/main/java/com/example/linux/hellojni

我的包名是:

package com.example.linux.hellojni

生成.h文件javah命令:

$cd ../../../..
$javah -jni com.example.linux.hellojni.myJNI
$ls
com com_example_linux_hellojni_myJNI.h

从ls指令可以看到在java目录下生成了com_example_linux_hellojni_myJNI.h文件:
Android studio使用JNI实例(1)_第9张图片

实现Native接口

新建一个jni文件夹,新建c文件(名称任意,此处为hello.c),把.h里面的内容复制进去(此处可以直接将.h文件移到jni文件夹,因为后边就不在需要它了),并实现里面的函数。
创建jni文件夹不要在文件夹中去创建,推荐使用方法:在Android标签下右键app -> New -> Folder -> JNI Folder,此时会弹出一个窗口,直接点击“Finish”完成即可。
Android studio使用JNI实例(1)_第10张图片

默认的文件名为jni,工程目录上Android标签显示的是cpp:
Android studio使用JNI实例(1)_第11张图片
Project标签上可以可以看到工程目录结构,可以看到在src/main下出现了jni目录,就是刚刚创建的JNI目录:
Android studio使用JNI实例(1)_第12张图片

生成的h文件:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_example_linux_hellojni_myJNI */

#ifndef _Included_com_example_linux_hellojni_myJNI
#define _Included_com_example_linux_hellojni_myJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_linux_hellojni_myJNI
 * Method:    sayHello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_linux_hellojni_myJNI_sayHello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

在Android标签cpp上右键“C/C++ Source File”新建hello.c,拷贝生成的.h文件的内容到hello.c中,并实现函数接口。

修改后的hello.c文件:

//
// Created by linux on 17-11-23.
//

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_example_linux_hellojni_myJNI */

#ifndef _Included_com_example_linux_hellojni_myJNI
#define _Included_com_example_linux_hellojni_myJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_linux_hellojni_myJNI
 * Method:    sayHello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_linux_hellojni_myJNI_sayHello
  (JNIEnv *env, jclass jobj)
{
    return (*env)->NewStringUTF(env,"JNI hahahahahahahaha");
}

#ifdef __cplusplus
}
#endif
#endif

修改配置文件

1.修改app Module的build.gradle文件,在defaultConfig节点里添加以下代码:

ndk {
    moduleName "JniTest"
    ldLibs "log", "z", "m"
    abiFilters "armeabi", "armeabi-v7a", "x86"
}

注意:这里的moduleName,是我们在之前自己编写的类里面加载的so库名

Android studio使用JNI实例(1)_第13张图片
2.修改gradle.properties文件,添加以下代码:

android.useDeprecatedNdk=true

Android studio使用JNI实例(1)_第14张图片

生成SO库

完成以上步骤之后,我们“Rebuild Project”或“Make Project”一下就可以生成so库了。
在项目的app\build\intermediates\ndk\debug\lib路径下:
Android studio使用JNI实例(1)_第15张图片
由上图可知,已经生成了所需平台的库,说明JIN实现及配置均成功了。

使用JNI

修改源文件

1.修改activity_main.xml文件
给activity_main.xml文件的TextView控件添加id,方便MainActivity等java模块引用:

android:id="@+id/text"

2.调用JNI接口
此处在MainActivity中使用JNI的sayHello接口:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Call JNI interface
        TextView text = (TextView)findViewById(R.id.text);
        text.setText(myJNI.sayHello());
    }
}

生成APK

完成源文件修改后执行“Build APK”开始编译APK:
Android studio使用JNI实例(1)_第16张图片
由此可知生成APK成功,可以在模拟器或实体Android机上安装试试。

调试

安装到仿真器后结果如下:
Android studio使用JNI实例(1)_第17张图片
由此可知其过程是正确的。

你可能感兴趣的:(android)