字节跳动面试必问,Android-NDK开发入门,内含福利

Android Runtime

Android 5.0(API 21)之前,使用的是Dalvik虚拟机,之后被ART所取代。ART是Android操作系统的运行环境,通过运行虚拟机来执行dex文件。其中,dex文件是专为安卓设计的的字节码格式,Android打包和运行的就是dex文件,而Android toolchain(一种编译工具)可以将Java代码编译为dex字节码格式,转化过程如下图。

如上所示,Jack就是一种编译工具链,可以将Java 源代码编译为 DEX 字节码,使其可在 Android 平台上运行。

原生C/C++ 库

很多核心 Android 系统组件和服务都是使用C 和 C++ 编写的,为了方便开发者调用这些原生库功能,Android的Framework提供了调用相应的API。例如,您可以通过 Android 框架的 Java OpenGL API 访问 OpenGL ES,以支持在应用中绘制和操作 2D 和 3D 图形。

应用程序框架层

Android平台最常用的组件和服务都在这一层,是每个Android开发者必须熟悉和掌握的一层,是应用开发的基础。

Application层

Android系统App,如电子邮件、短信、日历、互联网浏览和联系人等系统应用。我们可以像调用Java API Framework层一样直接调用系统的App。

接下来我们看一下如何编写Android JNI ,以及需要的流程。

NDK

NDK是什么

NDK(Native Development Kit缩写)一种基于原生程序接口的软件开发工具包,可以让您在 Android 应用中利用 C 和 C++ 代码的工具。通过此工具开发的程序直接在本地运行,而不是虚拟机。

在Android中,NDK是一系列工具的集合,主要用于扩展Android SDK。NDK提供了一系列的工具可以帮助开发者快速的开发C或C++的动态库,并能自动将so和Java应用一起打包成apk。同时,NDK还集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so文件。

NDK配置

创建NDK工程之前,请先保证本地已经搭建好了NDK的相关环境。依次选择【Preferences…】->【Android SDK】下载配置NDK,如下所示。

然后,新建一个Native C++工程,如下所示。

然后勾选【Include C++ support】选项,点击【下一步】,到达【Customize C++ Support】设置页,如下所示。

然后,点击【Finish】按钮即可。

NDK 项目目录

打开新建的NDK工程,目录如下图所示。

我们接下来看一下,Android的NDK工程和普通的Android应用工程有哪些不一样的地方。首先,我们来看下build.gradle配置。

apply plugin: ‘com.android.application’

android {
compileSdkVersion 30
buildToolsVersion “30.0.2”

defaultConfig {
applicationId “com.xzh.ndk”
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName “1.0”

testInstrumentationRunner “androidx.test.runner.AndroidJUnitRunner”
externalNativeBuild {
cmake {
cppFlags “”
}
}
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android-optimize.txt’), ‘proguard-rules.pro’
}
}
externalNativeBuild {
cmake {
path “src/main/cpp/CMakeLists.txt”
version “3.10.2”
}
}
}

dependencies {
// 省略引用的第三方库
}

可以看到,相比普通的Android应用,build.gradle配置中多了两个externalNativeBuild配置项。其中,defaultConfig里面的的externalNativeBuild主要是用于配置Cmake的命令参数,而外部的
externalNativeBuild的主要是定义了CMake的构建脚本CMakeLists.txt的路径。

然后,我们来看一下CMakeLists.txt文件,CMakeLists.txt是CMake的构建脚本,作用相当于ndk-build中的Android.mk,代码如下。

设置Cmake最小版本

cmake_minimum_required(VERSION 3.4.1)

编译library

add_library( # 设置library名称
native-lib

设置library模式

SHARED模式会编译so文件,STATIC模式不会编译

SHARED

设置原生代码路径

src/main/cpp/native-lib.cpp )

定位library

find_library( # library名称
log-lib

将library路径存储为一个变量,可以在其他地方用这个变量引用NDK库

在这里设置变量名称

log )

关联library

target_link_libraries( # 关联的library
native-lib

关联native-lib和log-lib

${log-lib} )

关于CMake的更多知识,可以查看CMake官方手册

官方示例

默认创建Android NDK工程时,Android提供了一个简单的JNI交互示例,返回一个字符串给Java层,方法名的格式为:Java_包名_类名_方法名 。首先,我们看一下native-lib.cpp的代码。

#include <jni.h>
#include

extern “C” JNIEXPORT jstring JNICALL
Java_com_xzh_ndk_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = “Hello from C++”;
return env->NewStringUTF(hello.c_str());
}

然后,我们在看一下Android的MainActivity.java 的代码。

package com.xzh.ndk;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

static {
System.loadLibrary(“native-lib”);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}

public native String stringFromJNI();
}

初识Android JNI

1,JNI开发流程

  1. 编写java类,声明了native方法;
  2. 编写native代码;
  3. 将native代码编译成so文件;
  4. 在java类中引入so库,调用native方法;

2,native方法命名

extern “C”
JNIEXPORT void JNICALL
Java_com_xfhy_jnifirst_MainActivity_callJavaMethod(JNIEnv *env, jobject thiz) {

}

函数命名规则: Java_类全路径_方法名,涉及的参数的含义如下:

  • JNIEnv*是定义任意native函数的第一个参数,表示指向JNI环境的指针,可以通过它来访问JNI提供的接口方法。
  • jobject表示Java对象中的this,如果是静态方法则表示jclass。
  • JNIEXPORT和JNICALL: 它们是JNI中所定义的宏,可以在jni.h这个头文件中查找到。

3,JNI数据类型与Java数据类型的对应关系

首先,我们在Java代码里编写一个native方法声明,然后使用【alt+enter】快捷键让AS帮助我们创建一个native方法,如下所示。

public static native void ginsengTest(short s, int i, long l, float f, double d, char c,
boolean z, byte b, String str, Object obj, MyClass p, int[] arr);

//对应的Native代码
Java_com_xfhy_jnifirst_MainActivity_ginsengTest(JNIEnv *env, jclass clazz, jshort s, jint i, jlong l, jfloat f, jdouble d, jchar c,
jboolean z, jbyte b, jstring str, jobject obj, jobject p, jintArray arr) {

}

下面,我们整理下Java和JNI的类型对照表,如下所示。

Java 类型Native类型有无符合字长
booleanjboolean无符号8字节
bytejbyte有符号8字节
charjchar无符号16字节
shortjshort有符号16字节
intjint有符号32字节
longjlong有符号64字节
floatjfloat有符号32字节
doublejdouble有符号64字节

对应的引用类型如下表所示。

Java 类型Native类型
java.lang.Classjclass
java.lang.Throwablejthrowable
java.lang.Stringjstring
jjava.lang.Object[]jobjectArray
Byte[]jbyteArray
Char[]jcharArray

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于Flutter的学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的
还有高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。

跨平台开发:Flutter.png

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值