Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textview.setText(JNIUtils.sayHelloFromJNI());
}
});
}
}
上面代码中的JNIUtils.sayHelloFromeJNI()就是我们在与MainActivity相同的包中新建JNIUtils类后在里面编写的native方法。如下所示:
可以看到我们上面的sayHelloFromJNI()方法显示的是警告红色。把鼠标放到上面,它会提示我们对应的JNI头文件没有查找到。那么接下来我们要做的就是去生成与这个sayHelloFromJNI()方法所对应的头文件。
4.生成头文件。快捷键alt + F12调出AS下的Terminal窗口,在Terminal命令行窗口中输入如下几条指令,回车:
前面两个cd命令没什么好说的,就是先进入当前项目的app目录下,然后再进入Java目录下。我们重点说一下最后一条命令:javah -d …/jni com.example.zhangxudong.jindemo.JNIUtils。首先,要生成Java类对应的头文件我们就必须要用到javah这个命令,其次-d表示生成一个目录,那生成一个什么样的目录,具体又在哪里去生成这个目录呢?后面的…/jni告示了我们。…/表示在当前目录的上一层目录,我们当前在Java目录下,那么它的上层目录就是main目录了。而jni就表示我们生成的目录的名称。所以整个…/jni就表示在main目录下生成一个名为jni的目录。最后一个com.example.zhangxudong.jindemo.JNIUtils就是我们在上面新建的JNIUtils的完整类名了。执行完这几天指令后,刷新一下目录我们就可以在main目录下看到jni这个目录,并且在它里面生成了我们JNIUtils类所对应的头文件。进入头文件中,代码是如下这个样子:
/* DO NOT EDIT THIS FILE - it is machine generated /
#include <jni.h>
/ Header for class com_example_zhangxudong_jnidemo_JNIUtils */
#ifndef _Included_com_example_zhangxudong_jnidemo_JNIUtils
#define _Included_com_example_zhangxudong_jnidemo_JNIUtils
#ifdef __cplusplus
extern “C” {
#endif
/*
- Class: com_example_zhangxudong_jnidemo_JNIUtils
- Method: sayHelloFromJNI
- Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_zhangxudong_jnidemo_JNIUtils_sayHelloFromJNI
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
5.头文件生成以后,我们就需要编写我们的C/C++代码了。右键jni目录---->new—>C/C++ Source File
输入要新建的C/C++文件名称JNIHello,这里我们用C++来编写,所以Type为.cpp,如果你选择用C来编写,那么Type选为.c,点击ok。这里说一下,在我们进行NDK开发的时候,选择用C还是C++,在编写代码的时候除了C和C++基本的语法不同外,还是有许多不同地方需要注意。我们后续会慢慢介绍。这里先默认跟着我的步骤来。
JNIHello.cpp代码如下:
#include “com_example_zhangxudong_jnidemo_JNIUtils.h”
JNIEXPORT jstring JNICALL Java_com_example_zhangxudong_jnidemo_JNIUtils_sayHelloFromJNI
(JNIEnv *env, jclass jclass){
return env->NewStringUTF(“Hello World From JNI!!!”);
}
可以看到我们首先需要把原来生成的JNIUtlis对应的头文件引入进来,下面的代码基本都是从com_example_zhangxudong_jnidemo_JNIUtils.h中复制粘贴过来的一部分,然后稍加修改。修改的地方主要有sayHelloFromJNI的两个参数和里面的简单实现,参数方面就是加了env和jclass两个字段。函数里面的实现呢,就是简单的返回一个字符串“Hello World From JNI!!!”,至于为什么这么写,我会在下一篇文章进行讲解,大家现在就需要知道如果要在这里返回一个字符串就必须要通过env->NewStringUTF(“xxxxxx”);这行代码。
6.上面的搞定以后,我们需要在app的build.gradle中的defaultConfig中加入如下代码。它表示项目在编译时生成的动态库的名字。
最后,我们还需在JNIUitls中加载我们生成的动态库:
public class JNIUtils {
static {
System.loadLibrary(“JNIHello”);
}
public static native String sayHelloFromJNI();
}
我们把加载动态库的代码放到静态代码块中,就是表示在JNIUtils这个类在加载的时候就去加载我们的动态库。
7.经过上面的5步,关于如何在AS中进行简单的NDK所需要的步骤差不多就讲完了。不过还有最后一点需要注意。到这里我们基本就可以执行一下我们的项目了,现在运行一下项目试一试…不出意外的话项目是build不成功的,它会报如下的错误:
Error:Execution failed for task ‘:app:compileDebugNdk’.
Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.
Consider using CMake or ndk-build integration. For more information, go to:
https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile
To get started, you can use the sample ndk-build script the Android
plugin generated for you at:
E:\JNIDemo\app\build\intermediates\ndk\debug\Android.mk
Alternatively, you can use the experimental plugin:
https://developer.android.com/r/tools/experimental-plugin.html
To continue using the deprecated NDK compile for another 60 days, set
android.deprecatedNdkCompileLease=1515317190556 in gradle.properties
因为我这里用的是Android Studio3.0,报出的这个错误很可能和原来版本的AS不同,以前出现类似错误的时候,我们的解决方案一般都是在gradle.properties中添加一行这样的代码:android.useDeprecatedNdk=true就搞定了。但是AS换为3.0后你可以再试一下这种方案,肯定是不行的,它会提示你“Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.”大体意思就是最新的AS已经不支持useDeprecatedNdk这个标记了,并且在后续版本的AS中,它将被移除。所以我们新的解决方案就是按照它的提示在gradle.properties中添家android.deprecatedNdkCompileLease=1515317190556这行代码。
最后我们运行一下项目,点击button,效果如下。可以看到,我们成功的通过java代码调用了C++的代码,并返回Hello World From JNI!!!这个字符串。
那我们生成的动态库(.so文件)都在哪里呢?点开app—>build—>intermediates—>ndk—>debug—>libs,可以看到各个平台对应的动态库都已经生成了。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
最后
光有这些思路和搞懂单个知识的应用是还远远不够的,在Android开源框架设计思想中的知识点还是比较多的,想要搞懂还得学会整理和规划:我们常见的**Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、IOC依赖注入框架、最近架构组件Jetpack等等Android第三方开源框架,**这些都是属于Android开源框架设计思想的。如下图所示:
这位阿里P8大佬针对以上知识点,熬夜整理出了一本长达1042页的完整版如何解读开源框架设计思想PDF文档,内容详细,把Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、IOC依赖注入框架、最近架构组件Jetpack等等Android第三方开源框架这些知识点从源码分析到实战应用都讲的简单明了。
由于文档内容过多,篇幅受限,只能截图展示部分
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断!!!
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中…(img-ENEpkqJv-1712803182548)]