android .so深入理解 abiFilters的使用等

Android应用打包必知:如何用abiFilters优化APK体积(附最新Gradle配置) 本文详细解析了Android应用打包时如何利用abiFilters配置优化APK体积。通过精准过滤不必要的CPU架构(如x86),仅保留主流的arm64-v8a和armeabi-v7a,可有效减少原生库(.so文件)带来的冗余,显著缩减安装包大小。文章提供了最新的Gradle配置示例与ABI选择策略,帮助开发者在兼容性与包体积间取得最佳平衡。 阅读详情

为什么使用so

  • so机制让开发者最大化利用已有的C和C++代码,达到重用的效果,利用软件世界积累了几十年的优秀代码;
  • so是二进制,没有解释编译的开消,用so实现的功能比纯java实现的功能要快;
  • so内存分配不受Dalivik/ART的单个应用限制,减少OOM;
  • 相对于java代码,二进制代码的反编译难度更大,一些核心代码可以考虑放在so中。

 

说起.so文件就必须提一下arm64、armeabi、armeabi-v7a、x86、x86_64等文件夹了,这些文件夹分别代表不同的CPU架构。他们存在的意义就是来做不同CPU架构手机的兼容的。

文件夹下,.so文件存在用来做各种手机CPU架构不同的兼容的。而apicloud 模块开发的云平台的云编译,只会保留armeabi这个.所以就有用到了abiFilters来指定NDK需要兼容的架构。

例:

ndk {
    abiFilters "armeabi"  // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi-v7a,arm-v8之类的so会被过滤掉)
}

apk安装过程中对so的选择

在Android上安装应用程序时,Package Manager会扫描整个apk文件,寻找符合下面文件路径格式的动态连接库:


 

lib/<primary-abi>/lib<name>.so

在这里,primary-abi是上面表中的abi的值,name对应的是我们在Android.mk中定义的LOCAL_MODULE的值,

如果在apk内并没有找到适合当前机器primary-abi的so,Package Manager会尝试寻找适合secondary-abi的so文件:


 

lib/<secondary-abi>/lib<name>.so

即安装应用时,系统会根据当前CPU架构选择最优ABI适配,如果找到了合适的so文件,包管理器会将该ABI文件夹下所有so库全部拷贝至应用的data目录下:data/data/<package_name>/lib/

注意:apk安装过程对so选择是基于整个ABI文件夹的,而非以单个so文件为粒度,也就是说把lib/armeabi 、lib/armeabi-v7a、lib/x86等等文件夹的其中一个文件夹内所有.so复制到应用的data目录下。

如果我们在代码中调用了某个so的功能,而最终拷贝的ABI文件夹下并没有提供这个文件,apk的安装过程中并不会报错,但是运行时会遇到java.lang.UnsatisfiedLinkError。

so的加载

对于so的加载,Android在System类中提供了两种方法:


 

/**

* See {@link Runtime#loadLibrary}.

*/

public static void loadLibrary(String libName) {

Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());

}

/**

* See {@link Runtime#load}.

*/

public static void load(String pathName) {

Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader());

}

System.loadLibrary

这是我们最常用的一个方法,System.loadLibrary只需要传入so在Android.mk中定义的LOCAL_MODULE的值即可,
系统会调用System.mapLibraryName把这个libName转化成对应平台的so的全称并去尝试寻找这个so加载。
比如我们的so文件全名为libmath.so,加载该动态库只需要传入math即可:


 

System.loadLibrary("math");

System.load

对于System.load方法,官方是这样介绍的:

Loads a code file with the specified filename from the local file system as a dynamic library.
The filename argument must be a complete path name.

所以它为动态加载非apk打包期间内置的so文件提供了可能,也就是说可以使用这个方法来指定我们要加载的so文件的路径来动态的加载so文件。
比如我们在打包期间并不打包so文件,而是在应用运行时将当前设备适用的so文件从服务器上下载下来,放在/data/data/<package-name>/mydir下,然后在使用so时调用:


 

System.load("/data/data/<package-name>/mydir/libmath.so");

即可成功加载这个so,开始调用本地方法了。

其实loadLibrary和load最终都会调用nativeLoad(name, loader, ldLibraryPath)方法,只是因为loadLibrary的参数传入的仅仅是so的文件名,所以,loadLibrary需要首先找到这个文件的路径,然后加载这个so文件。
而load传入的参数是一个文件路径,所以它不需要去寻找这个文件路径,而是直接通过这个路径来加载so文件。

但是当我们把需要加载的so文件放在SdCard中,会发生什么呢?把上面so的路径改成/mnt/sdcard/libmath.so,再尝试加载时,会得到如下错误:


 

java.lang.UnsatisfiedLinkError: dlopen failed: couldn't map "/mnt/sdcard/libmath.so" segment 1: Permission denied

这是因为SD卡等外部存储路径是一种可拆卸的(mounted)不可执行(noexec)的储存媒介,不能直接用来作为可执行文件的运行目录,使用前应该把可执行文件复制到APP内部存储下再运行。所以使用System.load加载so时要注意把so拷贝至/data/data/<package-name>/下。

通过精简so来减小包大小

现在的apk动辄几十M或者更大,apk包大小的精简成为了开发过程中的重要一环。通过上面的介绍,我们知道x86、x86_64、armeabi-v7a、arm64-v8a设备都支持armeabi架构的so,因此,通过移除不必要的so来减小包大小是一个不错的选择。

按照ABI分别单独打包APK

我们可以选择在Google Play上传指定ABI版本的APK,生成不同ABI版本的APK可以在build.gradle中进行如下配置:


 

android {

// Some other configuration here...

splits {

abi {

enable true

reset()

include 'x86', 'armeabi', 'armeabi-v7a', 'mips' //select ABIs to build APKs for

universalApk false // generate an additional APK that contains all the ABIs

}

}

}

只提供armabi的so

上面的方法需要应用市场提供用户设备CPU类型更识别的支持,在国内并不是一个十分适用的方案。常用的处理方式是利用gradle中的abiFilters配置。
首先配置修改主工程build.gradle下的abiFilters:


 

android {

// Some other configuration here...

defaultConfig {

ndk {

abiFilters 'armeabi'

}

}

}

abiFilters后面的ABI类型即为要打包进apk的ABI类型,除此以外都不打包进apk里。
然后在项目的根目录下的gradle.properties(没有的话新建一个)中加入下面这行:


 

android.useDeprecatedNdk=true

通过上面方法减少的apk体积是十分可观的,也是目前比较主流的处理方案。

进阶版方案

如果进一步,会发现上面的方案并不完美。首先是性能问题:使用兼容模式去运行arm架构的so,会丢失专门为当前ABI优化过的性能;其次还有兼容性问题,虽然x86设备能兼容arm类型的函数库,但是并不意味着100%的兼容,某些情况下还是会发生crash,所以x86的arm兼容只是一个折中方案,为了最好的利用x86自身的性能和避免兼容性问题,我们最好的做法仍是专为x86提供对应的so。
针对这些问题,我们可以采用一个相对更好的方案:让所有so都来自于网路,应用下载服务器上的so库后,利用System.load方法动态加载当前设备对应的so.

需要注意的问题

不要把so放错地方

首先要注意的是不要把另一个ABI下的so文件放在另一个ABI文件夹下(每个ABI文件夹下的so文件名是相同的,有可能会搞错)。

尽可能为所有ABI提供so

理想状况下,应该尽可能为所有ABI都提供对应的so,这一点的好处我们已经在上面讨论过了:在可以发挥更好性能的同时,还能减少由于兼容带来的某些crash问题。当然,这一点要结合实际情况(如SDK提供的so不全、芯片市场占有率、apk包大小等)去考量,如果使用的so本身就很小,我们大可为尽可能多的ABI都提供so。
若是局限于包大小等因素,可以结合通过精简so来减小包大小一节中提供的第三个方案来调整so的使用策略。

所有ABI文件夹提供的so要保持一致

这是一个十分容易出现的错误。
如果我们的应用选择了支持多个ABI,要十分注意:对于每个ABI下的so,但要么全部支持,要么都不支持。不应该混合着使用,而应该为每个ABI目录提供对应的.so文件。

先举个例子,Bugtags的so支持所有的ABI:


 

libs

|

├── arm64-v8a

│   └── libBugtags.so

├── armeabi

│   └── libBugtags.so

├── armeabi-v7a

│   └── libBugtags.so

├── mips

│   └── libBugtags.so

├── mips64

│   └── libBugtags.so

├── x86

│   └── libBugtags.so

└── x86_64

└── libBugtags.so

但不是所有开发者提供的so都支持所有ABI:


 

lib

|

├── armeabi

│   └── libImages.so

└── armeabi-v7a

└── libImages.so

如果不做任何设置,最终打出来的apk的lib目录会是这样的:


 

lib

|

├── arm64-v8a

│   └── libBugtags.so

├── armeabi

│   ├── libBugtags.so

│   └── libImages.so

├── armeabi-v7a

│   ├── libBugtags.so

│   └── libImages.so

├── mips

│   └── libBugtags.so

├── mips64

│   └── libBugtags.so

├── x86

│   └── libBugtags.so

└── x86_64

└── libBugtags.so

参考上面apk安装过程中对so的选择一节,假设当前设备是x86机器,包管理器会先去lib/x86下寻找,发现该文件夹是存在的,所以最终只有lib/x86下的so–即只有libBugtags.so会被安装。当尝试在运行期间加载libImages.so时,就会遇上下面常见的UnsatisfiedLinkError错误:


 

E/xxx (10674): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/xxx-2/base.apk"],nativeLibraryDirectories=[/data/app/xxx-2/lib/x86, /vendor/lib, /system/lib]]] couldn't find "libImages.so"

E/xxx (10674): at java.lang.Runtime.loadLibrary(Runtime.java:366)

所以,我们需要遵循这样的准则:

  • 对于so开发者:支持所有的平台,否则将会搞砸你的用户。
  • 对于so使用者:要么支持所有平台,要么都不支持。

然而,因为种种原因(遗留so、芯片市场占有率、apk包大小等),并不是所有人都遵循这样的原则。

一种可行的处理方案是:取你所有的so库所支持的ABI的交集,移除其他(可以通过上面介绍的abiFilters来实现)。
如上面的例子,最终生成的apk可以是:


 

lib

|

├── armeabi

│   ├── libBugtags.so

│   └── libImages.so

└── armeabi-v7a

├── libBugtags.so

└── libImages.so

动态加载 so 注意事项&案例,hashmap和concurrenthashmap的区别 android.os.Build.SUPPORTED_ABIS android.os.Build.CPU_ABI android.os.Build. CPU_ABI2 这些变量用于查询设备支持的架构,其中 SUPPORTED_ABIS 是API Level 21引入来代替CPU_ABI, CPU_ABI2的。 如果目标平台的 API Level 小于 21,只能使用 CPU_ABI 要 CPU_ABI2 来选择了,而 CPU_ABI 要优于 CPU_ABI2。 API Level >=21的推 阅读详情

相关推荐

Android APK安全加固与脱壳技术:攻防实战深度解析

在移动应用安全领域,代码保护与逆向分析构成了持续演进的技术对抗。APK加固与脱壳技术作为这场攻防的核心,其本质是通过加密、混淆和运行时保护等手段,防止应用代码被静态分析和动态调试。从技术原理层面看,加固方案通过代码混淆、字符串加密、反调试检测等多层防护,提升逆向工程门槛;而加壳技术则采用“外壳程序”动态加载加密原程序的架构,实现静态分析的失效。这些技术的工程价值在于平衡应用安全与性能开销,广泛应用于金融、游戏等高价值场景。随着VMP(虚拟机保护)等高级加固方案的普及,脱壳技术也同步演进,其中基于Frida的

weixin_30764883的博客 565

Android NDK开发必看:如何通过abiFilters配置动态库打包,让你的APK瘦身30%

本文深入解析Android NDK开发中如何通过abiFilters配置动态库打包,实现APK瘦身。通过精准筛选armeabi-v7a和arm64-v8a等架构,可有效移除冗余的.so文件,在保证应用兼容性的前提下,显著减小安装包体积,提升用户下载体验。

weixin_29169899的博客 343

Android Studio中三种JNI开发方式实战详解

JNI(Java Native Interface)是Java虚拟机与本地代码交互的关键桥梁,允许Java调用C/C++函数并反之。在Android开发中,JNI广泛应用于高性能计算、音视频编解码、游戏引擎(如Unity/Unreal)、加密算法及AI推理等场景。通过NDK,开发者可利用CMake或Android.mk构建原生库,实现跨平台能力复用与底层系统API访问。尽管Kotlin与Java生态持续演进,但对性能敏感型应用而言,掌握JNI仍是不可或缺的核心技能。

weixin_32673065的博客 901

边实验边分析-NDK篇-abiFilters配置分析

默認情況下,cmake會構建x86_64,x86,arm64-v8a,armeabi-v7a四個架構的ABI(应用程序二进制接口), 我們可以通過在defaultConfig.externalNativeBuild.cmake 块中添加abiFilters标记,来告诉ndk,我们真正需要构建的ABI defaultConfig { externalNativeBuild { cmake { abiFilters 'x86_64',

卡卡尔的专栏 5598

生成对抗网络(GAN、DCGAN、ACGAN)-----学习笔记

生成对抗网络学习笔记 生成对抗网络有两个关键结构:生成模型、判别模型。 生成模型:输入是一个服从正态分布的N维向量,利用这个N维向量生成一张图片。 判别模型:对于生成模型输出的图像判别它是不是真的图像。 生成模型和判别模型的博弈关系在于:生成模型的目的是生成让判别模型无法判别真伪的图像,而判别模型的目的是判断输入图像的真伪。 结合代码来看生成对抗网络中,生成器和判别器的训练过程: 判别模型的训...

weixin_43227526的博客 5489

【Autosar】学习总结-MCAL

一、简介 MCAL:微控制器抽象层;位于BSW层中的最下层; MCAL细分,可将驱动分为:微控制器驱动、存储器驱动、通信驱动、IO驱动: 二、MCAL的配置(EB-Tresos) 1.PORT 我理解的PORT:MCAL层中的IO驱动组中的pin脚总体配置: Port就是芯片上的每个pin脚,可以配置成DIO ADC PWM ICU等单引脚的功能,也能配置成CAN的TX或者RX、SPI的MOSI等等其他功能的单个pin脚功能; 总之,PORT就是芯片上的具体的某个引脚。 配置

zDavid_2018的博客 3万+

Android编译架构选择

具体选哪一种就看自己的考量了,以性能换兼容就arm64-v8,以兼容换性能armeabi,二者稍微平衡一点的就armeabi-v7a。只适配armeabi的APP可以跑在armeabi,x86,x86_64,armeabi-v7a,arm64-v8上。: 只适配了armeabi-v7a,那如果APP装在其他架构的手机上,如arm64-v8a上,会崩吗?只适配armeabi-v7a可以运行在armeabi-v7a和arm64-v8a。只适配arm64-v8a 可以运行在arm64-v8a上。

老猿的自留地 611

基于STM32和K210的自动驾驶小车设计

自动驾驶技术正在迅速发展,成为了汽车行业和智能交通领域的热点之一。随着科技的发展,STM32和K210这两款芯片为自动驾驶小车提供了优秀的硬件支持。本文我们将学习如何使用STM32和K210打造一个简单的自动驾驶小车。提示:以下是本篇文章正文内容,下面案例可供参考通过这篇文章,掌握了如何使用STM32和K210构建一个简单的自动驾驶小车。通过了解基本的电路设计,并编写了STM32和K210的代码。通过这个例子,可以更好地理解如何在嵌入式系统中使用STM32和K210,以及如何实现自动驾驶小车的简单功能。

Kyle_Chan_zMH的博客 2216

android module 引用libs里面的so文件_Android中的JNI开发,你了解多少?

一,什么是任务及管理任务是用户在执行某项工作时与之互动的一系列 Activity 的集合。一、步骤,修改build.gradle,添加cmakelists,写JNI接口,写c++,这个是不是流水线的方式集成,不了解每一步是做什么的;.so文件so是shared object的缩写,见名思义就是共享的对象,机器可以直接运行的二进制代码。我们通过C/C++开发的软件,如果以动态链接库的形式输...

weixin_29638987的博客 964

从零构建基于ZYNQ与AD9361的SDR信号源:FPGA逻辑与射频前端的协同设计

本文详细介绍了从零开始构建基于ZYNQ与AD9361的SDR信号源的完整流程。通过解析FPGA逻辑与射频前端的协同设计,重点阐述了如何利用FPGA生成基带信号,并通过ARM处理器配置AD9361,最终实现一个可编程的2.4GHz载波信号发生器。内容涵盖硬件选型、Vivado环境搭建、AXI总线通信、LVDS接口设计及软件驱动开发,为SDR开发者提供了实用的实战指南。

weixin_29200485的博客 214

Qwen 三代进化全景对比:从 Qwen2.5 到 Qwen3 再到 Qwen3.5

本文对比了阿里巴巴通义千问三代大模型(Qwen2.5、Qwen3、Qwen3.5)的技术演进。18个月内,模型在架构、训练数据和能力上实现显著突破:从纯稠密结构(Qwen2.5)发展为混合注意力架构(Qwen3.5),支持语言从29种扩展至201种,并实现原生多模态融合。关键进展包括引入MoE架构、Gated DeltaNet混合注意力机制(计算效率提升10倍)、以及从独立模态到早期视觉语言联合训练的转变。模型阵容从7个通用尺寸发展为8+个混合架构,最大参数量达397B,上下文窗口扩展至256K(托管版1M

m0_47999117的博客 1万+

从ABI到性能优化:Android SO库架构选择的艺术与科学

本文深入探讨了Android开发中SO库架构选择对应用性能和兼容性的关键影响。通过分析ABI与CPU架构的关系,提供了arm64-v8a等主流架构的优化策略,包括Gradle配置、动态加载和体积优化技巧,帮助开发者平衡性能与兼容性,提升应用效率。

j2k3l4的博客 578

网络摄像头(IPC)介绍:类型、供电、镜头、夜视等

IPC(Internet Protocol Camera,网络摄像头),它是一种由传统摄像机与网络技术结合所产生的新一代摄像机。它可以将视频、音频、报警及控制信号通过网络传输,接受网络监控主机(NVR或监控管理平台)的管理。IPC可与路由器、交换机、NVR等设备组建成为监控系统。

学无止境,Fighting! 1万+

深入理解JNI

JNI相关

qq_37776700的博客 333

MT4/MT5 第三代移动平均线(MetaTrader 指标)

第三代移动平均线(3G-MA)是传统MA指标的升级版本,通过"时滞压缩"算法将信号滞后降至理论极限(λ=2)。该指标在保留平滑性的同时,信号速度比EMA快1.5-2.3倍,适用于MT4/MT5平台。核心参数包括计算周期(默认34)、滞后压缩系数(2-10)和应用价位选择,支持斜率变色功能。安装简单,无需外部依赖,通过多周期共振可提升12-18%胜率。指标代码包含完整的MT4/MT5实现方案,采用双缓冲计算结构,通过相位前移算法抵消群延迟。风险提示:需配合其他技术指标和严格风控(≤2%账户

JanLEE 579

多物理场耦合仿真-主题032-电磁-流体耦合

电磁-流体耦合,即磁流体动力学(MHD, Magnetohydrodynamics),是研究导电流体在电磁场中运动规律的学科,涉及电磁场与流体力学的深度耦合。本主题系统阐述磁流体动力学的基本理论、控制方程和数值方法。首先介绍MHD的基本概念和物理基础,包括导电流体的性质、电磁场基本方程;然后详细推导MHD控制方程组,包括连续性方程、动量方程、能量方程和电磁场方程;接着讨论MHD流动的特征参数,如Hartmann数、磁雷诺数、相互作用参数等;最后通过六个典型工程案例展示MHD分析的实际应用,包括电磁泵、磁流体

2401_87715305的博客 424

llama.cpp Android移植实战:端侧大模型推理工程化指南

端侧大模型推理是移动AI落地的核心能力,其本质是将轻量化LLM(如Qwen2、Phi-3)在资源受限的Android设备上实现低延迟、高稳定性的本地运行。技术原理涉及C/C++推理引擎(llama.cpp)与Android NDK工具链的深度适配,关键在于ARM64指令集支持、JNI线程安全调用、量化模型(GGUF/Q4_K_M)内存布局优化及沙箱权限绕行。该能力显著提升隐私性、离线可用性与响应实时性,广泛应用于本地聊天助手、智能硬件嵌入式AI、教育类App离线问答等场景。本文聚焦llama.cpp在And

weixin_33701617的博客 633

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

安卓面试题总结

Android 的四大组件分别是:Activity、Service、Broadcast Receiver 和 Content Provider. 1)Activity:这是你与用户进行交互的入口。每一个 Activity 都是一个单独的界面,负责显示 UI和响应用户操作。 2)Service:Service 是运行在后台且不直接与用户交互的组件。适用于需要在后台执行长时间运行操作的任务,类似播放音乐或下载文件等。 3)Broadcast Receiver:用于

my_power520的博客 587

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

安卓端侧AI实战:纯C++集成YOLOv26实现实时目标检测

目标检测是计算机视觉的核心任务之一,旨在识别图像中的物体并定位其位置。其原理通常基于深度学习模型,通过卷积神经网络提取特征并预测边界框与类别。这项技术具有极高的技术价值,是实现自动驾驶、安防监控、移动应用智能化的关键。在应用场景上,云端部署面临延迟和隐私挑战,因此端侧AI(Edge AI)成为重要方向,它直接在设备上运行模型,保障了实时性与数据安全。本文聚焦于在安卓平台,通过纯Native C++代码集成YOLOv26模型,深入剖析从模型转换、JNI桥接到预处理与后处理(NMS)的完整工程实践,为开发者提供

weixin_33736832的博客 418

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

安卓端YOLOv26模型部署:TFLite与QNN委托的纯Native集成实战

在移动端AI模型部署中,硬件加速是提升推理性能、降低功耗的关键。其核心原理在于通过委托机制,将神经网络计算任务从通用CPU卸载到专用硬件处理器上执行。TensorFlow Lite作为主流的移动端推理框架,通过其委托接口,能够对接不同厂商的硬件加速库,从而实现模型推理的极致优化。这一技术对于实时视频分析、AR应用和移动机器人等对延迟和能效要求极高的场景具有重要价值。以高通骁龙平台的Hexagon DSP为例,其专用的QNN库能充分发挥硬件潜力。本文聚焦于如何绕过复杂的Java/JNI层,在安卓项目中通过纯N

cigang4063的博客 399

Android平台FFmpeg集成指南:从编译到JNI调用的完整实践

音视频处理是移动应用开发中的常见需求,涉及编解码、格式转换、剪辑合成等核心技术。其原理基于对多媒体数据的解析、转换与重构,通过算法实现高效处理。在Android开发中,本地音视频处理能力能显著提升应用性能与用户体验,避免云端传输延迟,增强离线功能。FFmpeg作为开源音视频处理库,提供了完整的解决方案,支持多种编解码器和封装格式。通过JNI技术,开发者可将FFmpeg集成到Android应用中,实现视频转码、音频提取等核心功能。本文详细介绍了FFmpeg在Android平台的编译配置、CMake集成及JNI

weixin_34151004的博客 402

Android ART函数抽取壳原理与实现:从Dex保护到运行时修复

在Android应用安全领域,加壳技术是保护代码逻辑的核心手段。其基本原理是通过对Dex文件进行加密或混淆,防止逆向工程直接分析关键代码。随着Android Runtime(ART)的引入,传统的整体加密方案面临兼容性挑战,促使技术向更精细化的函数级保护演进。函数抽取壳作为一种高级保护方案,通过有选择性地抽空关键方法的字节码指令,仅在运行时动态解密和填充,实现了对核心逻辑的隐蔽保护。这种技术不仅提升了应用的安全性,还能有效对抗静态分析和动态调试。在实际工程中,实现函数抽取壳需要深入理解ART虚拟机的类加载、

weixin_30613433的博客 405

安卓系统开发全解析:从架构原理到适配实战与优化

操作系统是连接硬件与应用的桥梁,移动操作系统更是现代智能设备的核心神经。理解其底层架构与运行机制,是每一位移动开发者的基本功。安卓系统凭借开源策略与硬件适配优势,成为全球覆盖最广的移动平台。其分层的系统架构、四大组件、Handler消息机制等概念,构成了应用开发的基础框架。在实际开发中,屏幕适配、字体缩放、视频全屏等场景常因系统定制差异而引发兼容性问题,需要开发者掌握针对性的适配方案。同时,合理运用AndroidAutoSize等工具、遵循组件生命周期规范,配合性能优化与安全实践,能显著提升应用的稳定性和用

weixin_34387468的博客 376

Android音视频开发:FFmpeg集成与JNI调用实战指南

音视频编解码是多媒体应用开发的核心技术,它涉及将原始音视频数据转换为特定格式进行存储或传输。其原理基于编码算法对数据进行压缩,解码则进行还原。在移动开发领域,Android系统虽然提供了MediaCodec等硬件加速方案,但在处理非标准格式、复杂滤镜或需要跨平台一致性的场景时,原生API往往能力有限。此时,集成功能强大的开源库成为关键解决方案,能够为应用带来专业级的处理能力和广泛的格式兼容性。FFmpeg作为业界公认的“瑞士军刀”,通过其libavcodec、libavformat等核心库,为开发者提供了从

weixin_34038293的博客 474

XopProtector开源Android加固:PVM虚拟化实现Dex/So/资源全栈防护

Android应用加固本质是提升逆向分析门槛,其核心在于破坏攻击者对Dex字节码、Native so符号、明文资源的静态可读性。传统商业基础版多依赖简单加壳与基础混淆,易被Frida内存dump或IDA脱壳绕过;而基于PVM(便携式虚拟机)理念的加固方案,通过将关键逻辑编译为自定义字节码、运行时解释执行,从根本上消除标准.class文件和JNI函数映射,实现‘不可见’而非‘难发现’。该技术显著增强APK抗静态反编译与动态调试能力,适用于金融、医疗等高安全要求场景,同时支持CI/CD集成与策略定制,兼顾合规性

weixin_34280237的博客 191

Android studio gradle文件说明与配置

.gradle 文件简单介绍一个 Android Studio 项目中,会存在多个 .gradle 文件。其中, project 目录下存在一个 build.gradle 文件和一个 settings.gradle 文件;每一个 module 会存在一个 build.gradle 文件。project中的build.gradlebuildscript { repositories { jce

Android移动开发 5234
上一篇: android studio module 导入本地aar
下一篇: android waiting for debugger
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值