AGP8 混淆打包,反射实例化启动闪退

Cocos Creator 3.8.6安卓打包全流程:从构建到真机部署实战指南 移动游戏开发中,将游戏引擎项目打包成可在安卓设备上运行的应用程序是一个核心环节。其原理在于通过构建工具链,将游戏资源、脚本和引擎运行时库编译、链接并封装成符合安卓系统规范的安装包。这一过程的技术价值在于打通了从开发到分发的关键路径,是实现游戏产品化的必要步骤。在实际应用场景中,开发者常面临环境配置复杂、版本兼容性以及构建优化等挑战。本文聚焦于Cocos Creator引擎,详细解析了**NDK配置**与**Gradle构建**这两个关键环节,提供了从编辑器设置、环境变量配置到APK生成与真机调试的完整、可操 阅读详情

在这里插入图片描述

1、问题

正如标题所示

同一个工程打包,配置 AGP8+ 打包启动闪退,配置 AGP7+ 打包启动运行正常

Process: com.primer.hello, PID: 29758
	java.lang.RuntimeException: Unable to instantiate application com.primer.hello.ai_reply_keyborad.AiKeyboardApplication 
	package com.primer.hello: java.lang.NullPointerException:
	Attempt to invoke virtual method 'java.lang.String com.channel.reader.ChannelReader.getChannel(android.content.Context)' on a null object reference

	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1495)
	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1424)
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7274)
	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2374)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:223)
	at android.os.Looper.loop(Looper.java:324)
	at android.app.ActivityThread.main(ActivityThread.java:8524)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:582)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1059)
Caused by: java.lang.NullPointerException: 
	Attempt to invoke virtual method 'java.lang.String com.channel.reader.ChannelReader.getChannel(android.content.Context)' on a null object reference

	at com.primer.core.kinetic.common.param.Utils.getChannel(Unknown Source:23)
	at com.primer.core.kinetic.common.param.Utils.setContext(Unknown Source:11)
	at com.primer.core.kinetic.api.CoreManager.applicationAttachBaseContext(Unknown Source:14)
	at com.primer.core.kinetic.api.DNSDK.applicationAttachBaseContext(Unknown Source:15)
	at com.primer.hello.ai_reply_keyborad.AiKeyboardApplication.attachBaseContext(SourceFile:48)
	at android.app.Application.attach(Application.java:374)
	at android.app.Instrumentation.newApplication(Instrumentation.java:1233)
	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1487)
	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1424) 
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7274) 
	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0) 
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2374) 
	at android.os.Handler.dispatchMessage(Handler.java:106) 
	at android.os.Looper.loopOnce(Looper.java:223) 
	at android.os.Looper.loop(Looper.java:324) 
	at android.app.ActivityThread.main(ActivityThread.java:8524) 
	at java.lang.reflect.Method.invoke(Native Method) 
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:582) 
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1059) 
Caused by: java.lang.NullPointerException: 
	Attempt to invoke virtual method 'java.lang.String com.channel.reader.ChannelReader.getChannel
  • 代码是在 Android application applicationAttachBaseContext下执行的
  • ChannelReader 是一个静态单例对象,通过 newInstance() 反射调用无参构造函数实例化对象 【注:按道理类加载时或调用就被初始化了】

显然,是 ChannelReader 对象实例化异常导致空指针!

2、猜想

反射让人很容易联想到代码混淆:

  • 可能是混淆了 ChannelReader 类,导致无法 newInstance 实例化
  • 可能是混淆了 ChannelReader 构造方法,导致无法 newInstance 实例化
  • 可能是混淆移除了 ChannelReader 构造方法,导致无法 newInstance 实例化

以上猜想很容易验证

2.1 构造函数

查看 apk 内 ChannelReader 类是否有无参构造方法

为什么要找的是无参构造方法?

因为该对象是通过 newInstance() 实例化的!

在这里插入图片描述

没有无参构造方法,不过还不能确定是没有无参构造方法的问题。

因为一个类没有显式写无参构造方法,会默认存在一个无参构造方法的,看个例子:

这样运行和编译都是没有问题的

public class Animal {
}


public class C {
    public static void main(String[] args) {
        new Animal();
    }
}

以 smali 方法查看字节码更加直观,这个 <init> ()V 就是无参构造方法,从字节码层面称它为实例初始化方法,从 java 层面看他就是构造方法(无参构造方法),区别于 <clinit> 类的初始化方法

在这里插入图片描述

<clinit> 从我们看就是静态代码块

public class Animal {
    static {

    }
}

在这里插入图片描述

这两个初始化方法的执行顺序是:

  • 先执行<clinit>:静态代码块
  • 再执行<init>:构造函数

查看一个类及成员是否被移除:查看 usage.txt 文件
查看一个类及成员被混淆成什么样:查看 mapping.txt 文件
查看一个类及成员那部分 keep 了:查看 seeds.txt 文件

这三个文件是开启混淆后,在build/outputs/mapping 目录下生成

反射与混淆关联,不妨分别查看两次不同 AGP 版本打包这个ChannelReader类的混淆情况

2.2 AGP7+ 运行正常

seeds.txt

在这里插入图片描述

说明这个 ChannelReader 类的无参构造方法是需要 keep 的(实际上是否 keep 还要查看生成的包是否存在无参构造方法或查看 smali 是否有 init 实例初始化方法)

usage.txt

没有 ChannelReader 相关信息输出,说明没有该类的任何成员等没有被移除


既然类没有被混淆、也没有被移除构造函数,反射 ChannelReader 通过 newInstance 实例化对象是没有问题的,所以没有空指针异常

2.3 AGP8.5 运行闪退

seeds.txt

在这里插入图片描述

跟上述 AGP7+ 一样,说这个类的无参构造方法是需要被 keep 的,不能移除

usage.txt

在这里插入图片描述

重点:

说明 ChannelReader 类的无参构造方法需要被移除,这问题就出现了!

练默认的构造方法都被移除了,还怎么实例化对象,怎么 new 对象?


再仔细查看闪退日志,果然是 newInstance 实例化对象失败,原因是缺少无参构造方法

在这里插入图片描述

查看该类是否存在实例初始化方法,是没有找到的,证明<init>方法确实被移除,不能正确通过反射实例化对象

在这里插入图片描述

3. 解决

当然了,目标就是保留无参构造方法在混淆打包过程中不被移除,反射实例化对象才正常

所以,需要新增一条混淆规则 keep ,禁止 ChannelReader <init> 实例初始化方法被移除

-keep class com.channel.reader.ChannelReader{*;}

这可能只是临时解决方法,投机取巧

实际上真正的疑惑还没解决:

为什么 AGP8.5 混淆打包,明明 seeds.txt 输出说明要 keep ChannelReader() 无参构造方法,实际结果得到的安装包查看该类却没有无参构造方法 <init>?

Cocos Creator安卓APK构建实战:从环境配置到多渠道打包 在移动游戏开发中,APK构建是将游戏项目打包为安卓可安装应用的关键环节,它直接关系到应用的最终分发与用户体验。其核心原理在于通过构建工具链(如Gradle)将代码、资源与原生库进行编译、压缩与签名,生成符合安卓平台规范的安装包。这一过程的技术价值在于确保应用的完整性、安全性,并优化其性能与体积。在实际应用场景中,开发者常需处理环境配置、签名管理、资源优化及多渠道适配等问题。本文聚焦于Cocos Creator引擎下的安卓构建,详细解析了**JDK版本选择**与**Gradle配置**等基础但易错的热点环节, 阅读详情

相关推荐

2025年Flutter金融级应用安全加固实战指南

在移动应用开发领域,代码混淆与数据加密是保障应用安全的核心技术。代码混淆通过重命名类、方法和变量名,打乱控制流,有效增加反编译和逆向工程的难度,保护知识产权和业务逻辑。数据加密则确保敏感信息在传输与存储过程中的机密性与完整性,防止数据泄露和篡改。这两项技术的结合,为应用构建了从代码到数据的立体防护体系,在金融、政务等高安全要求场景中尤为重要。随着Flutter框架在跨平台开发中的普及,其应用面临独特的安全挑战。本文聚焦Flutter应用的金融级安全加固,深入探讨如何实施分层防御策略,并针对Dart与原生双平

weixin_30835649的博客 418

Android应用覆盖安装时crash问题

最近测试报了这样的问题, 在版本覆盖安装的时候会报如下crash, 实验一下果然,具体跟进了一下,发现要必现该问题是需要条件的:1,4.0或者4.1系统2,覆盖前Activitystack 栈中有三个以上Activity经查很多同仁遇到了同样的问题,收集备忘于此。目前没有太好的解决办法。在高版本系统上或者低版本上没有该种问题。有在排查同样问题的兄弟们没时间不要再去查了。意义不大。java.lang

Delion 5842

Android MVVM实战:LiveData+DataBinding架构避坑指南

MVVM是Android开发中用于解耦UI与业务逻辑的经典架构模式,其核心在于通过可观察数据(如LiveData)驱动声明式UI(如DataBinding),实现生命周期安全、类型安全与响应式更新。LiveData专为Android UI生命周期设计,自动规避内存泄漏与后台更新异常;DataBinding则将数据绑定前置到编译期,消除findViewById、杜绝空指针、提升IDE智能提示与运行时性能。二者组合形成‘数据自驱动UI’闭环,显著降低Fragment臃肿度、减少胶水代码、提升线上稳定性。本文聚焦

weixin_33749131的博客 435

Android APG8.8 开启混淆后 需要注意的一些配置

请添加缺失的类或应用在xxx\app\build\outputs\mapping\debug\missing_rules.txt中生成的其他保留规则。这里只要按提示将这里给出的路径找到这个missing_rules.txt文件,然后把里面的内容复制到项目app目录下的proguard-rules.pro文件里即可。协程的 Continuation 类被混淆后,Retrofit 无法正确识别协程的返回类型结构。Retrofit 尝试解析挂起函数(suspend function)的返回类型时。

qq_32798811的博客 998

用Python和Kivy开发Android应用:从构建到上线的实战避坑指南

跨平台移动开发始终是技术选型的热门话题,Python开发者常因生态丰富而希望复用既有技能。Kivy作为基于OpenGL的Python UI框架,通过python-for-android与buildozer工具链,可以将纯Python代码打包成Android APK,在内部工具、数据采集、行业Demo等场景下展现出独特的工程价值。本文从真实项目切入,梳理了从环境搭建、SDK/NDK版本匹配、触控适配、R8混淆闪退到性能优化的完整链路,并分享了真机调试与Android高版本权限适配的经验。无论你是纯Python

weixin_42741930的博客 334

实测对比:Gromacs GPU版vsCPU版性能差异到底有多大?2023最新基准测试

本文通过2023年最新基准测试,详细对比了Gromacs GPU版与CPU版的性能差异。测试显示,GPU版本在计算速度上可提升54倍,同时显著降低内存需求和能耗成本。文章还提供了GPU版安装优化实践和硬件选购指南,为计算生物学研究提供关键参考。

weixin_29243063的博客 337

Android AGP升级到8.x导致的混淆问题(Class cannot be cast to java.lang.reflect.ParameterizedType)

最近在gradle8.0(gradle-8.0-bin.zip) 的项目中,添加混淆,网络框架使用的是retrofit,当发送http请求时,接口包400,提示:类型转换异常(Class cannot be cast to java.lang.reflect.ParameterizedType),刚开始还以为是解析定义的泛型和注解被混淆导致,配置了后还是一样报错,最后发现是gradle8.x引发Retrofit的混淆问题导致的。在混淆规则proguard-rules.pro里面添加下面语句,问题得到处理。

以后会多把工作中总结的知识、问题处理思路和方法通过博客分享出来,欢迎大家关注和共同探讨! 1176

TMS320F28377D的sys/bios双核工程配置详解——从零搭建到RAM优化

本文详细解析了TMS320F28377D双核系统在sys/bios环境下的工程配置与RAM优化策略。从开发环境搭建、SYS/BIOS工程创建到双核CMD文件配置,提供了实战技巧和常见问题解决方案,帮助开发者高效实现电力电子控制系统中的双核协作与性能优化。

weixin_28292761的博客 600

修复Android更新AGP8后retrofit2混淆出现错误:Unable to create call adapter for interface retrofit2.Call,并附上完整混淆规则

修复Android更新AGP8后retrofit2混淆出现错误:Unable to create call adapter for interface retrofit2.Call,并附上完整混淆规则

s894792409的博客 2367

TMS320F280049C 学习笔记4 Led_ex1_blinky 初始化函数及系统时钟

承接上一篇学习笔记,这次开始实际运行例程。本文概述了280049C的第一个实验 Led灯闪烁。同时也总结了系统的初始化函数和时钟配置。

whyorwhnt的专栏 7034

matlab 计算点云粗糙度

A Correspondence Framework for ALS Strip Adjustments based on Variants of the ICP Algorithm

点云侠的博客 1830

哔哩哔哩APP的 AGP8 升级之旅

以上就是本次升级的全部过程,虽然过程比较曲折,但是最终还是完成了。路漫漫其修远兮,吾将上下而求索。

chuyouyinghe的专栏 1587

26届数字IC秋招笔试面试全攻略 - CPU基础架构-数字IC设计专家

本文介绍了CPU基础架构的三大关键技术:流水线、冒险处理和指令集设计。首先解析了经典五级流水线结构(取指、译码、执行、访存、写回)及其性能指标。其次详细阐述了三种流水线冒险(数据、控制、结构)及解决方案,如数据前递、分支预测等。最后对比了RISC与CISC指令集特点,并以RISC-V为例说明指令格式设计原则。全文系统梳理了CPU核心架构知识,为数字IC设计提供重要参考。

2301_79143213的博客 931

京东Android真题复盘:从Java基础到Handler机制与AMS

Android开发岗位的笔试与面试,往往从Java基础与系统机制两个层面同时考察候选人的工程功底。在Java集合、并发编程等基础概念之上,理解HashMap的扩容与树化阈值、volatile的内存语义,是写出稳定代码的前提;而Handler的消息循环、Activity启动模式与AMS的进程管理,则决定了能否定位线上复杂问题。随着工程化程度加深,Gradle构建工具链、代码混淆与R8规则、性能优化也成为高频考点。这些技术不仅支撑电商类App的高并发场景与多版本适配,更是校招笔试和社招回炉的关键得分点。本文以京

weixin_34393428的博客 351

鸿蒙应用发布实战:应用热更新的实现

在移动应用开发领域,应用更新是持续交付价值的关键环节。传统的应用更新方式需要用户手动下载完整安装包,不仅用户体验差,而且更新率往往不理想。热更新技术(也称为OTA更新)允许应用在不重新安装的情况下动态更新部分功能,极大提升了用户体验和迭代效率。本文专注于鸿蒙操作系统下的应用热更新实现方案,涵盖从原理到实践的完整知识体系。鸿蒙热更新的技术架构差分更新算法实现动态部署机制实际项目中的最佳实践安全与性能优化策略首先介绍鸿蒙热更新的背景和核心概念深入分析技术原理和算法实现。

操作系统内核探秘的博客 965

YOLO26优化:原创自研 | 自研独家创新DSAM注意力 ,基于BiLevelRoutingAttention注意力升级

提出新颖的注意力DSAM(Deformable Bi-level SpatialAttention Module),创新度极佳,适合科研创新,效果秒杀CBAM,Channel Attention+Spartial Attention升级为新颖的Deformable Bi-level Attention+Spartial Attention

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 368

移动应用终极防护:PiliPlus级代码混淆与加固实战指南

在移动应用开发领域,代码混淆与加固是保障应用安全的核心技术。其基本原理是通过对源代码或编译后的二进制文件进行变形、加密和隐藏,增加逆向工程的难度,从而保护核心算法、业务逻辑和敏感数据不被窃取或篡改。这项技术的核心价值在于,它能将潜在攻击者的破解成本提升到远超其收益的水平,有效抵御静态分析、动态调试、二次打包等常见威胁。在实际应用场景中,无论是涉及金融交易的App,还是拥有核心算法的工具,都需要根据其价值和安全需求,构建多层次、立体化的防护体系。本文以PiliPlus级别的防护理念为例,深入探讨了从基础的标识

weixin_30386713的博客 427

TPAMI 2025 | 从缺失碎片到杰作:基于上下文自适应扩散的图像修复

图像修复是一项具有挑战性的任务,尤其是要确保生成的内容与图像的现有部分无缝融合。尽管最近的扩散模型展现出了潜力,但它们在保持已知区域和未知(缺失)区域之间的连贯性方面常常遇到困难。这个问题源于扩散过程中缺乏明确的空间和语义对齐,导致生成的内容无法与原始图像平滑融合。此外,扩散模型通常依赖全局学习分布,而非局部特征,这使得生成的图像部分与现有图像部分之间存在不一致。在这项工作中,作者提出了ConFill,这是一个新颖的框架,引入了上下文自适应差异(CAD)模型,以确保在整个扩散过程中,已知区域和未知区域的中间

小白学视觉 240

爱奇艺Android校招面试:从Handler到性能优化的核心考点复盘

在Android开发中,消息驱动机制是系统运行的基石,Handler作为线程通信的核心组件,其背后的Looper、MessageQueue与同步屏障原理,直接决定了开发者能否深入理解系统行为。与此同时,性能优化始终是工程实践中的关键能力,无论是ANR排查、布局层级精简还是Bitmap内存管理,都考验着开发者对系统底层机制的掌握程度。这些技术素养不仅在日常开发中决定应用质量,更是大厂校招和面试中高频考察的焦点。从消息循环到View绘制,从AMS调度到R8混淆,系统地掌握这些核心知识,能够帮助开发者构建完整的A

cmff98425的博客 346

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

小满Android研发岗笔试复盘:从四组件到构建工具链的思维升级

Android开发的核心不只在于UI编写,更涉及组件生命周期、进程优先级、Binder跨进程通信等系统级原理。理解Activity和Service的运行机制,以及AMS/WMS如何协同管理界面与任务,是进阶的基础。在工程化层面,构建工具链中的AGP版本兼容、R8混淆与资源适配直接影响发布质量,而android ota、APEX等系统组件更新机制则成为中大型公司考察的新热点。从文件分享的FileProvider权限设计,到蓝牙音频焦点联动,再到CoordinatorLayout嵌套滚动实战,这些场景均在检验开

weixin_34072637的博客 413

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Debug/Release配置指南:从Gradle到Keil的profile实战

在软件开发中,同一份代码如何在不同场景下自动切换行为?这依赖于一套贯穿构建、运行与发布的profile机制。debug与release并非简单的编译器开关,而是涵盖优化级别、宏定义、依赖作用域、日志级别与API地址的完整配置集合。理解这一原理,能帮助开发者高效管理多环境工程,避免手动改参带来的混乱。无论是Java后端通过Maven的-P参数切换环境,Android工程利用Gradle的buildTypes与productFlavors组合出构建变体,还是嵌入式Keil中Target级别的隔离,抑或前端通过V

cuibinmo3519的博客 330

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Android开发基础技能练习场:RYG分级实战训练指南

在Android开发的学习与工程实践中,开发者常面临从看懂Demo到独立交付的鸿沟,构建一套系统化的技能训练体系至关重要。通过将Android基础能力拆解为Red、Yellow、Green三个等级,围绕四大组件、UI布局、数据存储、网络与蓝牙等核心技能点,以真实功能反推练习清单,并结合版本兼容、依赖配置、性能调优与真机适配等工程实践,能有效提升从需求拆解到落地实现的能力。以实战项目为线索,从环境搭建到数据持久化再到性能分析,这套方法论可帮助开发者摆脱单点练习的碎片化学习,逐步养成“知其所以然”的工程思维。对

weixin_33835103的博客 393

Unity集成Android原生应用实战:从原理到通信与性能优化

在移动应用开发中,模块化与组件化是提升开发效率和用户体验的关键架构思想。其核心原理在于将复杂系统拆分为独立、可复用的功能单元,通过清晰的接口协议进行通信与协作。这种架构模式的技术价值在于,它允许团队并行开发、简化测试流程,并能灵活地集成第三方引擎或SDK来扩展应用能力。在电商、教育、AR等应用场景中,常需嵌入高性能的3D渲染或交互内容,Unity引擎因其强大的图形处理能力成为首选。将Unity作为库(Unity as a Library)集成到原生Android应用,正是这一思想的典型实践。它涉及Andro

weixin_34055787的博客 368

从 AGP 4.1.2 到 7.5.1——自定义混淆映射失效?

通常我们配置混淆规则都是在我们知道就是一个数组,内容是混淆文件路径列表,可以是相对路径、也可以是绝对路径。

Primer5 1373

代码混淆之调用Class类的newInstance方法抛异常

相信大家在日常开发中,都有用到过Class.newInstance()方法,如果有人没有接触过,也没关系,我会给大家介绍下这个方法的使用方式。① 方法使用介绍:该方法属于静态方法,调用方式Class.newInstance(),返回的是Class对象所对应的类的实例,用于在知道Class对象情况下,创建实例对象。② 方法异常介绍:IllegalAccessException:如果该类或其空(nul...

chun_long的博客 4801
上一篇: Android LifecycleOwner 闪退,java 继承、多态特性!
下一篇: AGP 升级,适配 8.5 版本(一)
Primer@.com
博客等级 码龄9年 524粉丝 292原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值