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.pswp.cn/pingmian/93051.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/93051.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/93051.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于SpringBoot的旅游網站系統

1. 項目簡介 旅游線路管理系統是一個基于Spring Boot的在線旅游服務平臺&#xff0c;提供旅游線路展示、分類、預訂、訂單管理等功能。系統包含前臺用戶界面和后臺管理模塊&#xff0c;支持用戶注冊登錄、線路瀏覽、收藏、下單支付、客服咨詢等核心功能。管理員可管理線路信息、…

CVPR 2025 | 機器人操控 | RoboGround:用“掩碼”中介表示,讓機器人跨場景泛化更聰明

點擊關注gongzhonghao【計算機sci論文精選】1.導讀1.1論文基本信息論文標題&#xff1a;ROBOGROUND: Robotic Manipulation with Grounded Vision-Language Priors作者&#xff1a;Haifeng Huang, Xinyi Chen, Hao Li&#xff0c; Xiaoshen Han, Yilun Chen, Tai Wang, Zehan W…

構建Node.js單可執行應用(SEA)的方法

如果為了降低部署復雜度&#xff0c;可以考慮使用vercel/ncc。除非有特別理由&#xff0c;不建議使用SEA。1. 環境準備1.1. 基礎要求Node.js: > 19.0.0 (推薦最新LTS版本)1.2. 安裝依賴npm install postject typescript1.3. 驗證環境node -v # 確認版本 > 19 ts…

Java19 Integer 位操作精解:compress與expand《Hacker‘s Delight》(第二版,7.4節)

compress(int i, int mask) 這個方法是Java 19中新增的一個強大的位操作函數。compress 方法的核心功能可以理解為 “按位過濾和壓縮” 。過濾 (Filter): 它使用 mask&#xff08;掩碼&#xff09;作為過濾器。對于輸入整數 i&#xff0c;只有那些在 mask 中對應位為 1 的比特才…

minio部署和雙機熱備

安裝單機版MinIO&#xff08;準備2臺機器A、B,A、B服務器操作一致&#xff09;切換目錄并下載MinIO二進制文件cd /usr/local/bin wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio chmod x minio編輯配置文件vi /etc/default/minio.confMINIO_VOLUMES&quo…

【Java】 Java 21 革命性升級:虛擬線程與結構化并發的深度實踐指南

還在為高昂的AI開發成本發愁?這本書教你如何在個人電腦上引爆DeepSeek的澎湃算力! Java 21 作為 Oracle JDK 的長期支持版本,引入了多項革命性特性,其中虛擬線程(Virtual Threads)和結構化并發(Structured Concurrency)尤為突出。這些特性旨在解決傳統線程模型在高并發…

Apache IoTDB 全場景部署:基于 Apache IoTDB 的跨「端-邊-云」的時序數據庫 DB+AI

Apache IoTDB 全場景部署&#xff1a;基于 Apache IoTDB 的跨「端-邊-云」的時序數據庫 DBAI 文章目錄Apache IoTDB 全場景部署&#xff1a;基于 Apache IoTDB 的跨「端-邊-云」的時序數據庫 DBAIApache IoTDB 介紹Docker部署指導企業版數據庫配套工具 WorkbenchTimechoDB&…

計算機網絡---傳輸控制協議Transmission Control Protocol(TCP)

一、TCP的定位與核心特性 TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;是TCP/IP協議棧中傳輸層的核心協議&#xff0c;與UDP&#xff08;用戶數據報協議&#xff09;共同承擔端到端數據傳輸功能。其設計目標是在不可靠的IP網絡上提供可靠…

week1-[分支嵌套]公因數

week1-[分支嵌套]公因數 題目描述 給定 444 個正整數 a,b,c,ka,b,c,ka,b,c,k。如果 a,b,ca,b,ca,b,c 都是 kkk 的倍數&#xff0c;那么稱 kkk 是 a,b,ca,b,ca,b,c 的公因數。否則如果某兩個數都是 kkk 的倍數&#xff0c;那么稱 kkk 是這兩個數的公因數。問 kkk 是哪些數的公因…

C#枚舉/結構體講一講

先展示一段簡單代碼// 定義枚舉 public enum thisday {吃飯,不吃 }// 定義結構體 public struct person {public string name;public int age;public thisday zhuangtai; // 使用枚舉類型作為字段 }static void Main(string[] args) {// 創建結構體實例person thisperson;thisp…

C++-setmap詳解

Cset&map 1. 序列式容器和關聯式容器 1.1 序列式容器 序列式容器按照線性順序存儲元素&#xff0c;元素的位置取決于插入的時間和位置&#xff0c;與元素的值無關。 主要特點&#xff1a;元素按插入順序存儲可以通過位置&#xff08;索引&#xff09;直接訪問元素不自動排序…

解決程序連不上RabbitMQ:Attempting to connect to/access to vhost虛擬主機掛了的排錯與恢復

前言&#xff1a;在分布式系統里&#xff0c;RabbitMQ作為消息中間件&#xff0c;是服務間通信的關鍵紐帶。但實際使用中&#xff0c;程序連接RabbitMQ失敗的情況時有發生。本文結合真實報錯&#xff0c;細致呈現從問題發現到解決的完整排錯思路&#xff0c;還會深入講解Rabbit…

K8S中如何配置PDB(Pod Disruption Budget)

1. PDB 核心概念作用&#xff1a;控制自愿中斷&#xff08;如節點升級、縮容&#xff09;期間&#xff0c;應用的最小可用副本數或最大不可用比例。關鍵參數&#xff1a;minAvailable&#xff1a;必須保持運行的 Pod 數量&#xff08;如 2 或 50%&#xff09;。maxUnavailable&…

從 0 到 1:用 MyCat 打造可水平擴展的 MySQL 分庫分表架構

一、為什么要分庫分表&#xff1f; 單機 MySQL 的極限大致在&#xff1a;維度經驗值單表行數≤ 1 000 萬行&#xff08;B 樹三層&#xff09;單庫磁盤≤ 2 TB&#xff08;SSD&#xff09;單機 QPS≤ 1 萬&#xff08;InnoDB&#xff09;當業務繼續增長&#xff0c;數據量和并發…

電池模組奇異值分解降階模型

了解如何將奇異值分解 (SVD) 降階模型 (ROM) 應用于電池模塊熱模擬。挑戰隨著電池模塊在電動汽車和儲能系統中的重要性日益提升&#xff0c;其熱性能管理也成為一項重大的工程挑戰。高功率密度會產生大量熱量&#xff0c;如果散熱不當&#xff0c;可能導致電池性能下降、性能下…

《Python函數:從入門到精通,一文掌握函數編程精髓》

堅持用 清晰易懂的圖解 代碼語言&#xff0c;讓每個知識點變得簡單&#xff01; &#x1f680;呆頭個人主頁詳情 &#x1f331; 呆頭個人Gitee代碼倉庫 &#x1f4cc; 呆頭詳細專欄系列 座右銘&#xff1a; “不患無位&#xff0c;患所以立。” Python函數&#xff1a;從入門到…

【記錄貼】STM32 I2C 控制 OLED 卡死?根源在 SR1 與 SR2 的讀取操作

問題描述最近在復用以前STM32F407控制OLED的代碼&#xff0c;移植到STM32F103 上&#xff0c;使用硬件 I2C 通信方式。按照常規流程&#xff0c;先發送 OLED 的從機地址&#xff0c;OLED 有正常應答&#xff0c;但當發送第一個控制命令&#xff08;0xAE&#xff09;前的控制字節…

【AI驅動的語義通信:突破比特傳輸的下一代通信范式】

文章目錄1 語義通信簡介1.1 基本概念&#xff1a;什么是語義通信&#xff1f;語義通信的核心目標1.2 基本結構&#xff1a;語義通信系統結構語義通信系統的通用結構組成語義通信系統的結構關鍵模塊1.3 基于大模型的語義通信關鍵技術&#x1f9e0;語義通信系統中AI大模型的設計建…

網絡原理-HTTP

應用層自定義協議自定義協議是指根據特定需求設計的通信規則&#xff0c;用于設備或系統間的數據交換。其核心在于定義數據結構、傳輸方式及處理邏輯。協議結構示例典型的自定義協議包含以下部分&#xff1a;頭部&#xff08;Header&#xff09;&#xff1a;標識協議版本、數據…

ROS配置debug指南

一. 安裝插件 下面的這一個插件過期了需要用下面的這一個插件來替換:二. 設置CMakeLists.txt的編譯模式 set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAG…