1. 程式人生 > >怎樣在64位安卓系統中使用32位SO庫

怎樣在64位安卓系統中使用32位SO庫

背景知識:

對於64位系統的編譯規則,可參考:http://source.android.com/source/64-bit-builds.html

關鍵點:JAVA編譯不分32bit和64bit(APK,JAR)可執行檔案,預設編譯64位動態庫和靜態庫,默認同時編譯32bit和64bit版本通過LOCAL_MULTILIB可以指定特定模組編譯32bit或64bit或都編譯JAVA載入JNI庫(so檔案)的規則:
如果APP需要載入的所有so都是32bit,則使用32bit方式載入so庫;如果APP需要載入的so庫中只要有一個so是64bit的,則必須以64bit方式載入so庫;不能同時載入32bit和64bit的so庫。

實際工程中,我們通常會遇到下面這樣的場景:
A. APK有原始碼,SO庫有原始碼 - 應用及so庫我們都能自己編譯出來
B. APK有原始碼,SO庫沒有原始碼 - 我們開發的應用使用了第三方的so庫,如ScanService
C. APK和SO庫都沒有原始碼 - 預置第三方的應用(應用中包括so庫)

對於場景A:

只要我們編譯預設對應的APP和SO庫(32bit+64bit)即可。
此種場景最為普通,本文不做詳細講解。

對於場景B:

如果APK需要載入的庫裡面有64bit的,則需要全部的庫都使用64bit。
如果APK呼叫的第三方so庫中有32bit的,則:要麼讓第三方提供64bit版本的so庫,要麼強制使所以的so庫都使用32bit版本。

對於場景C:

使用特定的預置規則即可。

場景A範例:APK的編譯規則不需要設定LOCAL_MULTILIBSO庫的編譯規則也不需要設定LOCAL_MULTILIB
所以,SO庫就會同時編譯出32bit和64bit版本,APK按照64bit方式呼叫so庫場景B範例:APK的編譯規則需要設定LOCAL_MULTILIBSO庫的編譯規則需要指定64bit或32bit(本地編譯或預置的都需要)需要顯示宣告APK的JNI庫
如:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_JAVA_LIBRARIES := odm conscrypt sp
LOCAL_PACKAGE_NAME := PosService

# to support on 64-bit system
LOCAL_JNI_SHARED_LIBRARIES := \
                          libmiscjni \
                          libttyjni \
                          libIAL \
                          libSDL \
                          libbarcodereader \
                          libHsmKil \
                          libHHPScanInterface \
                          libHSMDecoderAPI
LOCAL_MULTILIB := 32

include $(BUILD_PACKAGE)

其中某個本地編譯so的規則:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    com_odm_tty.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libttyjni
LOCAL_MULTILIB := 32
include $(BUILD_SHARED_LIBRARY)

某個第三方so的規則:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE := libHHPScanInterface
LOCAL_SRC_FILES := $(LOCAL_MODULE).so
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib
LOCAL_MULTILIB := 32
include $(BUILD_PREBUILT)
場景C範例:APK使用典型的預置應用規則SO庫不需要寫預置規則需要顯示宣告APK呼叫的SO庫
如:
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := BaiduIME
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := baidu_input_for_xiaomiV5.apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MULTILIB := 32
LOCAL_PREBUILT_JNI_LIBS := \
    @lib/armeabi/libBDVoiceRecognitionClient_V1.so \
    @lib/armeabi/libchiperencoder_v1_2_1.so \
    @lib/armeabi/librabjni-1.so \
    @lib/armeabi/libshare_v2.so
include $(BUILD_PREBUILT)

相關推薦

怎樣在64系統使用32SO

背景知識: 對於64位系統的編譯規則,可參考:http://source.android.com/source/64-bit-builds.html 關鍵點:JAVA編譯不分32bit和64bit(APK,JAR)可執行檔案,預設編譯64位動態庫和靜態庫,默認同時編譯32b

移動端系統,固定在底部的按鈕被輸入框的鍵盤頂上去的問題解決辦法

處理問題的思路:         監控螢幕大小的變化,當螢幕變小的時候讓按鈕隱藏起來,當螢幕大小與當前螢幕保持一致的時候,讓按鈕正常顯示。  解決辦法有2種: 1、原生辦法 (推薦) var h = document.body.scrollHeight; wi

系統讀寫資料

0.安卓儲存空間: 目錄結構在FileExplorer中檢視,可通過Windows/Show View/Others/FileExplorer開啟 內部儲存空間(internal storage):自帶的,必須有的 RAM記憶體:執行記憶體(電腦記憶體) ROM記憶體:儲存空間(電腦

系統的桌面啟動器Launcher

安卓系統桌面啟動器  Launcher是安卓系統中的桌面啟動器,安卓系統的桌面UI統稱為Launcher。Launcher是安卓系統中的主要程式元件之一,安卓系統中如果沒有Launcher就無法啟動安卓桌面,Launcher出錯的時候,安卓系統會出現“程序 com.and

開發-尺寸單位+Logcat的使用+Android單元測試+系統資料的讀寫

知識檢視: 《一:尺寸單位》 1.px:電腦 電視上的解析度的尺寸單位。畫素是構成數碼影像的基本單元。例如300x300解析度,即表示水平方向與垂直方向上每英寸長度上的像 素數都是300,也

c# 枚舉系統所有目錄及文件名

tco time exceptio try err ring oid cep env using Android.App; using Android.Widget; using Android.OS; using System.Runtime.InteropServic

系統關於乙太網(Ethernet)無法上網的問題解決(二)

設定完畢後發現系統已經能夠自動獲取ip了: eth0      Link encap:Ethernet  HWaddr 00:09:C0:FF:EC:48           inet addr:192.168.0.19  Bcast:192.168.0.255  Mask

系統關於乙太網(Ethernet)無法上網的問題解決(一)

最近在調系統的Ethernet,將過程記錄一下。 檢查過安卓原始碼中已經有了Ethernet的相關程式碼,可是還是無法開啟乙太網上網功能。 由於暫時無法通過修改安卓原始碼來開啟Setting中的乙太網設定(其實是我還沒找到在哪改。。。。),所以就想通過命令的方式來開啟乙太

Linux系統查看系統32還是64方法總結 in 創新實訓

-a 如果 rep 分享 查看 blog cpu 整理 ble 這篇博客是總結、歸納查看Linux系統是32位還是64位的一些方法,很多內容來自網上網友的博客。本篇只是整理、梳理這方面的知識,方便自己忘記的時候隨時查看。 方法1:getconf LONG_BIT 查看 如下

c#判斷操作系統32還是64

ping interop 64位 lin last 直接 run 遇到 roc 做一個c#項目時,遇到要獲取操作系統位數的問題,在網上找了幾個小時,都沒有找到比較完整的解決方案。話不多說,直接上可以運行的代碼(簡單、粗暴) using System.Runtime.Con

Linux系統32還是64查看方法總結

x86_64 如果 9.png 支持 ges mod lag span long 【聲明】 本文版權歸原作者所有,歡迎轉載,轉載請註明出處。 原作者:瀟湘隱者 出處:http://www.cnblogs.com/kerrycode/ 原文鏈接:https://www.cn

arm-linux-gcc編譯時出現的一些小插曲-----64系統需要32

最近由於工作的需要,重新弄起arm-linux-gcc編譯。離上一次弄這些有整整10年了。 我是在一臺64位的機器上實機安裝的 centos7 發行版,系統和交叉編譯器的安裝過程自是沒話說,問題出在使用arm-linux-gcc編譯 arm程式時, $ arm-linu

Ubuntu16.04 64系統使用32交叉編譯器的問題

在ubuntu16.04的64位系統上安裝32位交叉編譯工具鏈,建好軟連線後,發現無法使用,顯示No such file or directory。 解決方法: sudo apt-get install libc6:i386 安裝完成後,測試可用。 後來有發現其它解決

【問題】檢視當前系統32還是64

方法1 uname -i 方法2 getconf LONG_BIT 方法3 CentOS 6.X及低版本    file /sbin/init CentOS 7.X    file /lib/systemd/systemd

Java在win10系統3264環境變數設定

今天解決的一個問題終於把困擾我多年的環境變數之類的東西搞懂了。 這一切罪惡的根源就是win10的64位系統可以相容32位軟體 當我多年前安裝java的時候,我選擇了安裝32位版本的java而並非64位版本。我按照百度經驗的教程https://jingyan.baidu.c

判斷Linux系統32還是64

方法1: 執行以下命令: --------------------------- $ getconf LONG_BIT --------------------------- 如果輸出32即為32位系

什麼是64系統以及64系統32的支援和優缺點

第一講  什麼是64位系統 截至本課程編寫的時間為止,市場上有兩種受歡迎的64位微處理器體系結構:IA64 和Intel64 IA-64是由 Intel 和HP 合作開發的64位微處理機體系結構。Itanium 和Itanium2 微處理機中就是用了這種體系結構。如想了解更多關於IA-64的資訊

linux c/c++ 區分系統32還是64

方法一: #if  __WORDSIZE ==  64 #else #endif __WORDSIZE定義在#include <bits/wordsize.h>中,表示計算機系統是幾位的。 方法二: int main(int argc  ,ch

64Windows系統32應用程式連線MySql

1.首先得安裝“Connector/ODBC”,就是Mysql的ODBC驅動,這個是與應用程式相關的,而不是與作業系統相關的,也就是說,不管你的系統是x64還是x86,只要你的應用程式是x86的那麼,“Connector/ODBC”就要安裝x86的,才能正常,下面的是下載

Linux 下檢視系統32 還是64 的方法

1. 從系統檢視 1.1 uname -a 命令 [[email protected] ~]# uname -a Linux qs-dmm-rh2 2.6.18-194.el5 #1 S