收藏
1
0
分享
举报
·4 小时前发布·60次阅读

一次 Android 更新后应用无法启动:我是如何用 ADB L

独立开发商业增长付费用户

最近,我在更新自己的 FinTech 应用 TransferIQ 时遇到了一个非常典型、也非常折磨人的问题:

AAB 可以正常构建。
Google Play 可以正常上传。
应用也可以完成更新。

但是——

更新后的应用一打开就无法正常启动。

最麻烦的是,表面上看不出明显原因。

一开始,我怀疑过很多东西:

  • AsyncStorage 中保留了旧版本数据
  • 新旧版本状态结构不兼容
  • Expo / React Native 缓存问题
  • API 初始化失败
  • Supabase 配置异常
  • 更新后的 JavaScript Bundle 冲突

这些猜测听起来都合理。

但最后证明,真正的问题完全不在 JavaScript 层。

一、第一步:不要继续猜,先看设备日志

我的项目使用:

  • React Native
  • Expo SDK 54
  • Android AAB
  • Google Play
  • react-native-google-mobile-ads

首先通过 USB 连接 Android 手机,然后运行:

adb devices

一开始设备状态是:

unauthorized

这意味着电脑已经识别到手机,但手机还没有授权 ADB 调试。

在手机上重新允许 USB debugging 后,状态变成:

device

到这里,才真正具备读取设备日志的条件。

二、清理旧日志,再复现问题

为了避免系统日志太多,我先清空 Logcat:

adb logcat -c

然后强制停止应用:

adb shell am force-stop com.jkim1285.TransferIQMobile

接下来:

  1. 在手机上重新打开应用
  2. 复现启动失败
  3. 等待几秒
  4. 导出当前日志

使用:

adb logcat -d > transferiq-fresh.txt

这一步对我非常重要。

与其一直盯着实时 Logcat,不如先复现问题,再一次性导出日志。这样不需要一直保持终端运行,也更容易分析。

三、最终找到真正的错误

日志中出现了:

FATAL EXCEPTION: main

以及:

Unable to get provider
com.google.android.gms.ads.MobileAdsInitProvider

更关键的是:

Invalid application ID

看到这里,问题终于清楚了。

应用甚至还没有真正进入 React Native 的 JavaScript 逻辑。

它在 Android 原生初始化阶段就已经崩溃了。

真正的问题是:

AdMob Application ID 配置错误。

四、一个非常容易混淆的细节:App ID 和 Ad Unit ID 不是一回事

这是这次问题里最容易踩坑的地方。

AdMob App ID 通常类似:

ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx

注意中间是:

~

而 Banner Ad Unit ID 通常类似:

ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx

注意中间是:

/

两者看起来很像,但用途完全不同。

App ID 用于应用级别的 AdMob 初始化。

Ad Unit ID 用于具体广告位,例如:

  • Banner
  • Interstitial
  • Rewarded Ad

在我的项目代码里,Banner Ad Unit ID 本身没有问题。

真正的问题出现在 Native Config。

也就是说,广告组件代码可以是正确的,但如果 Android 原生层没有正确配置 Application ID,应用仍然可能在启动阶段直接崩溃。

五、React Native / Expo 项目不能只修改 App.js

这是我这次学到的另一个关键点。

对于 Expo 项目,AdMob 初始化涉及 Android 原生配置。

不能只修改:

App.js

还需要在 Expo config 中正确设置类似:

[
"react-native-google-mobile-ads",
{
"androidAppId": "ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx"
}
]

然后重新构建新的 Android AAB。

换句话说:

App.js 修改
≠
Native Config 修改

很多移动端问题,尤其是下面这些功能:

  • Ads
  • Notifications
  • Permissions
  • Deep Links
  • Native SDK
  • Android Providers

都不能只从 JavaScript 层思考。

六、为什么这个问题特别容易误判?

因为整个发布流程表面上都可能是正常的。

例如:

  • npm install 成功
  • Expo build 成功
  • EAS Build 成功
  • AAB 文件成功生成
  • Google Play 上传成功
  • Google Play 更新成功
  • 用户完成安装成功

但应用依然可以在启动瞬间崩溃。

也就是说:

Build Success
≠
Runtime Success

Store Upload Success
≠
Native Configuration Correct

这对 AI-assisted development 尤其重要。

AI 很容易告诉你:

“可能是缓存问题”
“可能是 AsyncStorage”
“可能是状态迁移”
“可能是 API”
“可能是 Expo”
“可能是旧版本数据”

这些可能性都不是完全错误。

但真正的问题必须通过证据确认。

七、我这次最大的教训

这次问题让我重新确认了一件事:

当 Android 应用出现“更新后启动即崩溃”时,不要长时间依赖猜测。

更有效的顺序是:

  1. 确认设备连接
  2. 确认 adb devices 显示 device
  3. 清理旧日志
  4. 强制停止应用
  5. 重新打开并复现问题
  6. 导出 Logcat
  7. 搜索 FATAL EXCEPTION
  8. 判断问题发生在 JS 层还是 Native 层
  9. 再修改代码或配置

我前面花了不少时间怀疑:

  • 缓存
  • 状态迁移
  • 旧数据
  • JavaScript Bundle
  • API 初始化

但真实日志最终只用了几行就告诉我:

Invalid application ID

问题其实非常直接。

八、对 AI 辅助开发的另一个提醒

我不是传统软件工程师。

我的主要背景是 8 年以上的 FinTech、Crypto、Operations 和 Product 经验。

目前我通过 AI 辅助方式独立开发 TransferIQ。

AI 可以:

  • 快速生成代码
  • 修改 UI
  • 分析错误
  • 提供命令
  • 提出可能原因
  • 帮助非工程背景的人完成真实产品

但这次经历再次说明:

AI 给出的“可能性”很多,
而真正的工程问题最终还是要依靠:

  • 日志
  • 复现
  • 证据
  • 配置检查
  • 实际运行结果

尤其在移动端,下面几个层次经常混在一起:

JavaScript
Native Android
Build Config
Expo Config
Third-party SDK
Google Play Update

只看 App.js,很容易找错方向。

九、最终结论

这次真正的问题不是:

  • AAB 构建失败
  • Google Play 上传失败
  • React Native 页面错误
  • AsyncStorage 冲突
  • Supabase 错误
  • API 错误

而是:

AdMob Native Initialization

Invalid Application ID

App crashes before JavaScript starts

如果你也遇到 Android 应用更新后无法启动,我非常建议先看 ADB Logcat,而不是继续猜。

有时候,一行真实日志,比几十个“可能原因”更有价值。

我正在继续开发 TransferIQ,一个用于比较跨境汇款、FX、Crypto、Stablecoin 和本地收款路径的独立平台。

TransferIQ 不托管用户资金,也不执行支付。

产品的目标是帮助用户在正式发送资金之前,比较不同路线的预估接收金额、费用、FX spread 和路径差异,再前往官方 provider 或 exchange 确认最终报价。

这次故障排查,也是我一个人构建、发布和维护真实产品过程中的一部分。

对我来说,这可能不是最后一次遇到这种问题。

但至少下一次,我会先打开日志,而不是先猜。

讨论 (0)

    关于作者

    分享案例

    这家伙很懒,什么都没留下

    Solo 独立开发者社区support@solo.xin
    关于社区隐私政策用户协议商务合作友情链接订阅更新(RSS)投稿赞助

    © 2023 SOLO · 为独立开发者而生