当前位置: 首页 > news >正文

Android POS应用在android运行常见问题及解决方案

概述

本文档记录了在Android POS应用开发过程中遇到的两个关键问题及其解决方案:

  1. UnsatisfiedLinkError: couldn't find "libnative.so" 错误
  2. ActivityNotFoundException 错误
  3. 商户信息一致性检查绕过

问题1:UnsatisfiedLinkError - libnative.so库加载失败

问题描述

应用在ARM64架构设备上运行时出现以下完整错误信息:

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/~~9LvQGgl7HMUBJBdLUqNzVw==/com.rkxch.hspos-bYGBfqmXoa7gEGiO_MP_-g==/base.apk"],nativeLibraryDirectories=[/data/app/~~9LvQGgl7HMUBJBdLUqNzVw==/com.rkxch.hspos-bYGBfqmXoa7gEGiO_MP_-g==/lib/arm64, /system/lib64, /system_ext/lib64]]] couldn't find "libnative.so"at java.lang.Runtime.loadLibrary0(Runtime.java:1071)at java.lang.Runtime.loadLibrary0(Runtime.java:1007)at java.lang.System.loadLibrary(System.java:1667)at com.ccb.clientauth.ClientAuth.<clinit>(ClientAuth.java:21)at com.rkxch.hspos.ui.common.AuthUtil.getAuthCode(AuthUtil.java:18)at com.rkxch.hspos.ui.login.LoginActivity.getMerchantId(LoginActivity.java:215)at com.rkxch.hspos.ui.login.LoginActivity.onCreate(LoginActivity.java:179)at android.app.Activity.performCreate(Activity.java:8051)at android.app.Activity.performCreate(Activity.java:8031)at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)at android.os.Handler.dispatchMessage(Handler.java:106)at android.os.Looper.loopOnce(Looper.java:201)at android.os.Looper.loop(Looper.java:288)at android.app.ActivityThread.main(ActivityThread.java:7872)at java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

根本原因

  • clientauth-release.aar 库中只包含 armeabi-v7a 架构的 libnative.so 文件
  • 设备运行在 arm64 架构上,无法找到对应架构的native库
  • Android系统默认不会在ARM64设备上加载armeabi-v7a架构的库

解决方案

步骤1:检查AAR文件内容
jar -tf app\libs\clientauth-release.aar | Select-String -Pattern "lib/"

确认AAR文件中只包含:

lib/armeabi-v7a/libnative.so
步骤2:修改build.gradle配置

问题原因: 应用运行在ARM64设备上,但native库只提供了armeabi-v7a版本,系统默认会尝试加载arm64-v8a版本导致找不到库文件。

解决方案: 通过配置ABI过滤器,明确告诉Android系统应用只支持armeabi-v7a架构,利用ARM64设备的向下兼容性来运行32位库。

具体操作:

  1. 打开 app/build.gradle 文件
  2. android 块的 defaultConfig 部分添加 ndk 配置:
android {compileSdkVersion 30buildToolsVersion "30.0.3"defaultConfig {applicationId "com.example.hspos"minSdkVersion 21targetSdkVersion 30versionCode 1versionName "1.0"// 添加ABI过滤器,只支持armeabi-v7a架构ndk {abiFilters "armeabi-v7a"}testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}// 其他配置...
}

配置说明:

  • abiFilters "armeabi-v7a" 限制应用只支持armeabi-v7a架构
  • 这样配置后,即使在ARM64设备上,系统也会使用armeabi-v7a版本的native库
  • ARM64设备具有向下兼容性,可以正常运行32位的armeabi-v7a代码
步骤3:重新构建项目
./gradlew clean build

技术原理

  • abiFilters "armeabi-v7a" 配置告诉Android系统只支持armeabi-v7a架构
  • ARM64设备具有向下兼容性,可以运行armeabi-v7a架构的代码
  • 这种配置确保应用在ARM64设备上能够正确加载armeabi-v7a的native库

问题2:ActivityNotFoundException - 外部应用调用失败

问题描述

应用尝试启动建行支付应用时出现以下完整错误信息:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rkxch.hspos/com.ccb.smartpos.bankpay.ui.MainActivity}: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.ccb.smartpos.bankpay/com.ccb.smartpos.bankpay.ui.MainActivity}; have you declared this activity in your AndroidManifest.xml?at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3654)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)at android.app.ActivityThread.-wrap12(Unknown Source:0)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)at android.os.Handler.dispatchMessage(Handler.java:106)at android.os.Looper.loopOnce(Looper.java:201)at android.os.Looper.loop(Looper.java:288)at android.app.ActivityThread.main(ActivityThread.java:7872)at java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.ccb.smartpos.bankpay/com.ccb.smartpos.bankpay.ui.MainActivity}; have you declared this activity in your AndroidManifest.xml?at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2005)at android.app.Instrumentation.execStartActivity(Instrumentation.java:1673)at android.app.Activity.startActivityForResult(Activity.java:5315)at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)at android.app.Activity.startActivityForResult(Activity.java:5273)at com.rkxch.hspos.ui.login.LoginActivity.getMerchantId(LoginActivity.java:230)at com.rkxch.hspos.ui.login.LoginActivity.onCreate(LoginActivity.java:179)at android.app.Activity.performCreate(Activity.java:8051)at android.app.Activity.performCreate(Activity.java:8031)at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608)... 10 more

根本原因

  • 应用尝试通过 ComponentName 显式启动建行支付应用的Activity
  • 目标设备上未安装建行支付应用 (com.ccb.smartpos.bankpay)
  • 缺少异常处理机制,导致应用崩溃

解决方案

涉及的文件和方法
  1. LoginActivity.java - getMerchantId() 方法
  2. ScanPaySecondStepActivity.java - consumeByScan()queryTransInfo() 方法
  3. SwipeCardSecondStepActivity.java - consumeBySwipe() 方法
修改示例(以LoginActivity为例)

修改前:

private void getMerchantId() {String authIndex = null;String authCode = null;Intent intent = new Intent();intent.setComponent(new ComponentName("com.ccb.smartpos.bankpay", "com.ccb.smartpos.bankpay.ui.MainActivity"));// ... 其他代码startActivityForResult(intent, 999);
}

修改后:

private void getMerchantId() {try {String authIndex = null;String authCode = null;Intent intent = new Intent();intent.setComponent(new ComponentName("com.ccb.smartpos.bankpay", "com.ccb.smartpos.bankpay.ui.MainActivity"));// ... 其他代码startActivityForResult(intent, 999);} catch (Exception e) {Log.e(TAG, "CCB bankpay app not found or not available: " + e.getMessage());merchantId = "DEFAULT_MERCHANT_ID";Toast.makeText(this, "CCB银行支付应用未安装,使用默认配置", Toast.LENGTH_SHORT).show();}
}
异常处理策略
  • 捕获异常:使用try-catch块捕获所有可能的异常
  • 日志记录:记录详细的错误信息便于调试
  • 用户提示:显示友好的中文提示信息
  • 默认处理:设置默认值确保应用继续运行
  • 防止崩溃:确保应用在外部依赖缺失时仍能正常工作

问题3:商户信息一致性检查绕过

问题描述

应用在登录时会检查登录用户的商户信息与POS设备的商户信息是否一致,不一致时会阻止登录。

解决方案

修改LoginActivity.java

将商户信息一致性检查代码注释掉:

修改前:

if (merchantId != null) { // 从建行收单应用中读取到商户编号List<Supplier> list = user.getSupplierList();boolean matched = false;for (Supplier supplier : list) {if (supplier.getMerchantId().equals(merchantId)) {matchSupplier = supplier;matched = true;break;}}if (!matched) {Toast.makeText(LoginActivity.this, "登录用户的商户信息与POS的商户信息不一致", Toast.LENGTH_LONG).show();matchSupplier = null;}
}

修改后:

// 跳过商户信息一致性检查
// if (merchantId != null) { // 从建行收单应用中读取到商户编号
//     List<Supplier> list = user.getSupplierList();
//     
//     boolean matched = false;
//     for (Supplier supplier : list) {
//         if (supplier.getMerchantId().equals(merchantId)) {
//             matchSupplier = supplier;
//             matched = true;
//             break;
//         }
//     }
//     
//     if (!matched) {
//         Toast.makeText(LoginActivity.this, "登录用户的商户信息与POS的商户信息不一致", Toast.LENGTH_LONG).show();
//         matchSupplier = null;
//     }
// }

构建和验证

构建命令

# 清理并构建Debug版本
./gradlew clean assembleDebug# 或者构建所有版本
./gradlew clean build

验证步骤

  1. 检查APK内容

    jar -tf app\build\outputs\apk\debug\app-debug.apk | Select-String -Pattern "lib/"
    

    确认输出包含:lib/armeabi-v7a/libnative.so

  2. 安装测试:在ARM64设备上安装APK并测试native库加载

  3. 功能测试:验证应用在建行支付应用未安装的情况下不会崩溃

最佳实践和建议

1. Native库兼容性

  • 在发布应用前,确保所有依赖的AAR文件包含目标架构的native库
  • 考虑使用 splits 配置为不同架构生成单独的APK
  • 定期检查第三方库的架构支持情况

2. 外部应用依赖处理

  • 始终为外部应用调用添加异常处理
  • 提供降级方案或默认行为
  • 使用 PackageManager.resolveActivity() 检查目标应用是否存在

3. 错误处理策略

  • 实现全局异常处理机制
  • 提供用户友好的错误提示
  • 记录详细的错误日志便于问题排查

4. 测试建议

  • 在不同架构的设备上进行测试
  • 模拟外部依赖缺失的场景
  • 进行兼容性测试确保应用稳定性

总结

通过以上解决方案,我们成功解决了:

  1. ✅ ARM64设备上native库加载失败的问题
  2. ✅ 外部应用调用导致的崩溃问题
  3. ✅ 商户信息一致性检查的限制

这些修改确保了应用在各种环境下都能稳定运行,提升了用户体验和应用的健壮性。

http://www.dtcms.com/a/331348.html

相关文章:

  • 当消息队列遇上AI:飞算JavaAI实现智能流量调度与故障自愈实践
  • 在 Windows 系统中解决 Git 推送时出现的 Permission denied (publickey) 错误,请按照以下详细步骤操作:
  • LE AUDIO---Common Audio Service
  • C#WPF实战出真汁02--登录界面设计
  • STM32学习笔记11-通信协议-串口基本发送与接收
  • 从轨道根数计算惯性系到轨道系旋转矩阵
  • 2020/12 JLPT听力原文 问题二 1番
  • [激光原理与应用-268]:理论 - 几何光学 - 人眼结构与颜色感知
  • Nacos 配置热更新:Spring Boot Bean 自动获取最新配置
  • 【21-倾斜数据集的误差指标】
  • 金融风控实战:从数据到模型的信用评分系统构建全解析
  • 使用马尔可夫链如何解码、预测股市模式
  • 西门子PLC通过稳联技术EtherCAT转Profinet网关连接baumuller伺服器的配置案例
  • ThreadPoolExecutor 最佳实践
  • 8月AI面试工具测评:破解规模化招聘难题
  • 哈希表特性与unordered_map/unordered_set实现分析
  • 风电功率预测实战:从数据清洗到时空建模​​
  • 从单机到分布式:用飞算JavaAI构建可扩展的TCP多人聊天系统
  • 大规模分布式光伏并网后对电力系统的影响
  • 用SQL实现对DuckDB rusty_sheet插件批量测试
  • 前端-vue全局路由守卫的详情
  • 地测管理部绩效考核关键指标与地质数据分析
  • 如果未来出现了意识移植技术,如何确保移植后的意识是原本的意识而不是复制了一份
  • C++-setmap详解
  • 无人机图传模块——智能飞行的关键技术
  • 解锁AI潜能:五步写出让大模型神级指令
  • Cloudflare Tunnels穿透ssh
  • 51单片机-驱动LED模块教程
  • 【C#】Region、Exclude的用法
  • 无需公钥的无损加密解密