注意:本人是初学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 |
新建工程名为HelloJni的APK工程:
点击“Next”后选择Android版本,我选择的是5.0,具体与自己的平台一致:
点击“Next”后选择Activity模板,此处选择“Empyt Activity”:
点击“Next”后填写Activity Name,此处用默认的即可:
点击“Finish”完成工程创建,创建完成后界面如下:
新建一个类(类名随意,此处为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终端(菜单栏View -> Tool Windows -> Terminal或使用快捷键Alt+F12),使用javac编译上述文件,生成class文件。
生成class文件命令:
$cd app/src/main/java/com/example/linux/hellojni/
$javac myJNI.java
后在上一级的位置使用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文件:
新建一个jni文件夹,新建c文件(名称任意,此处为hello.c),把.h里面的内容复制进去(此处可以直接将.h文件移到jni文件夹,因为后边就不在需要它了),并实现里面的函数。
创建jni文件夹不要在文件夹中去创建,推荐使用方法:在Android标签下右键app -> New -> Folder -> JNI Folder,此时会弹出一个窗口,直接点击“Finish”完成即可。
默认的文件名为jni,工程目录上Android标签显示的是cpp:
Project标签上可以可以看到工程目录结构,可以看到在src/main下出现了jni目录,就是刚刚创建的JNI目录:
生成的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库名
2.修改gradle.properties文件,添加以下代码:
android.useDeprecatedNdk=true
完成以上步骤之后,我们“Rebuild Project”或“Make Project”一下就可以生成so库了。
在项目的app\build\intermediates\ndk\debug\lib路径下:
由上图可知,已经生成了所需平台的库,说明JIN实现及配置均成功了。
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());
}
}
完成源文件修改后执行“Build APK”开始编译APK:
由此可知生成APK成功,可以在模拟器或实体Android机上安装试试。