導航:首頁 > 文件處理 > androidso壓縮

androidso壓縮

發布時間:2023-08-21 11:22:30

① 如何動態載入android的so文件,如何壓縮apk尺寸

您好,很高興為您解答。

一、 工具集介紹 (項目地址: https://github.com/liyuming1978/NativeLibCompression)
安卓壓縮工具集提供了一個極為簡潔的方法,能夠比安卓原有的Zip提供更高壓縮比的存儲應用內的so文件 (後期版本還可以支持壓縮動態載入的jar包,以及游戲資源文件),同時提供了應用內網路更新下載壓縮文件的方法,使得應用可以將部分so存儲到雲端,減小應用的尺寸。

壓縮原理: 壓縮工具會把所有的so使用LZMA演算法壓縮到assert目錄,應用在第一次啟動的時候,會解壓到應用的私有目錄下

二、 工具集組成
工具集為一個安裝程序,建議安裝在默認路徑下,安裝在program files下在win7可能有讀寫許可權的問題導致一些異常

安裝後,你可以看見4個目錄,此目錄內都含有源碼
安裝後的四個目錄如下

其中 ApkLibComrepss 為java命令行程序的源碼,在此目錄的bin子目錄中,你可以找到ApkCompress.jar ,使用這個文件可以把一個普通的apk文件轉換為壓縮的apk文件
CompressDemo為一個樣例代碼,你可以參考這個代碼知道如何整合壓縮的SDK。
DecRawso是壓縮的SDK,你的開發工程需要引用這個SDK,並進行一些源碼上的修改,才能整合壓縮的功能
RawsoCreator為windows下的轉換工具, 這個工具一般無需使用, 僅僅在調試和二次開發壓縮SDK的時候使用。
三、 如何整合壓縮SDK
打開CompressDemo,我們以這個工程為例子講解如何整合壓縮SDK
1. 首先需要引入DecRawso工程

2. 然後需要在你的工程內最初始的地方調用DecRawso.NewInstance。在此demo工程內,是在MainActivity.java的OnCreate內調用了此方法, 此方法是創建了一個解壓的唯一實例。注意:此方法是非同步的,所以你可以傳入一個handler接受非同步解碼完成的消息,如果同時傳入參數showProgress=true,SDK內會產生一個進度對話框以阻塞主進程。不推薦使用DecRawso.NewInstance(mContext,null,false);的方式,此方式不接受任何消息,且無進度對話框,解壓會在後台自動完成,並且在應用第一次load so的時候阻塞直到後台解壓完成。所以如果阻塞時間過長,可能會導致應用無響應。
3. 修改load so文件的方法:所有的System.loadlibrary(***)改為 System.load(DecRawso.GetInstance().GetPath(「***"));
新版本, 這步可以省略了,sdk會修改system的libaray載入路徑,一般情況下,系統升級不會出問題 (非正規代碼,小概率會隨android升級修改新的代碼),如果方便的話,還是採用System.load(DecRawso.GetInstance().GetPath(「***"))

經過這幾個簡單的步驟,壓縮的SDK已經整合到工程內了。

四、 如何壓縮發布APK
使用ApkCompress.jar壓縮發布APK。 此工具為命令行工具。一般的此命令使用方式為:在命令行運行ComPressApk.jar-a C:/my/test.apk -k c:/key *** ### alias -x86http://www.test.com (也可以運行 java –jarComPressApk.jar )
-a 後面跟apk路徑名, 可以不是全路徑
-k 後面是簽名文件[key storepasskeypass alias name] ,key可以不是全路徑名 (name 如果不寫, 默認就是CERT)
-x86 表示需要存儲x86庫文件在雲端, 後面跟以http://開頭的鏈接,最後實際的存儲位置應該為 http://www.test.com/cloudrawso_x86
命令執行完以後, 會生成test_CompressAlign.apk. 這個apk就是壓縮後的apk
五、 開發模式和壓縮模式
為了方便開發,在實現開發的過程中(修改了源碼支持壓縮後),也可以不壓縮so,apk也可以正常運行,壓縮的SDK內部會自動判斷是否有壓縮包, 如果沒有壓縮包,則載入的路徑恢復成android默認的路徑。所以最方便的開發是,先整合代碼,在開發過程中和原來一樣開發(不壓縮),在發布的時候才壓縮apk
六、 X86和ARM庫混合調用
在實現開發過程中,可能會有某些第三方庫確實沒有x86版本,通常情況下ISV並不在x86目錄下放置arm的第三方庫,那麼在實際運行過程中會導致缺庫現象的發生。在缺庫的情況下,壓縮的SDK會在x86設備上自動解壓arm的壓縮包,避免缺庫現象的發生。(只有真正載入了缺失的庫才是缺庫,庫文件不一致並不一定就是缺庫)
但是顯然這樣會導致運行的低效率,如果在第三方so和x86的庫完全沒有相互引用的情況下(也就是說這些庫都是java層使用JNI調用的,在native層沒有相互調用),可以拷貝arm的第三方庫到x86目錄下,這樣就不會出現缺庫的情況。當然這種情況會導致arm庫多餘的拷貝,在以前的zip壓縮情況下,會使得壓縮包變大,但是在新的LZMA壓縮情況下,庫大小完全不會增大,因為LZMA壓縮由於字典比較大,能夠盡可能的壓縮關聯的幾個文件,如果文件完全相同,LZMA的壓縮會和單個文件基本一致。

如若滿意,請點擊右側【採納答案】,如若還有問題,請點擊【追問】

希望我的回答對您有所幫助,望採納!

~ O(∩_∩)O~

② androidstudio怎麼將寫好的so文件工程打包成jar包

Android Studio的so庫導入和Eclipse的方式有些不同。在Android Studio中,要在工程的src/main下面新建一個jniLibs文件夾,然後將所用到的第三方so庫復制進來,然後找到Project下的build.gradle文件,在其中添加以下幾行代碼:

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

task nativeLibsToJar(type: Zip, description: "create a jar archive of the native libs") {
destinationDir file("$projectDir/libs")
baseName "Native_Libs2"
extension "jar"
from fileTree(dir: "libs", include: "**/*.so")
into "lib"
}

然後重新Gradle一下代碼,第三方so庫就加了進來。

參考http://www.cnblogs.com/devpan/p/5536238.html

③ 如何動態載入android的so文件,如何壓縮apk尺寸,androidapk

在Android中調用動態庫文件(*.so)都是通過jni的方式,而且往往在apk或jar包中調用so文件時,都要將對應so文件打包進apk或jar包,工程目錄下圖:

以上方式的存在的問題:
1、缺少靈活性比較類似靜態載入了(不是靜態載入),能載入的so文件綁定死了;
2、但so文件很多或很大時,會導致對應的apk和jar包很大;
3、不能動態的對so文件更新;

Android中載入so文件的提供的API:
void System.load(String pathName);

說明:
1、pathName:文件名+文件路勁;
2、該方法調用成功後so文件中的導出函數都將插入的系統提供的一個映射表(類型Map);

看到以上對System.load(String pathName);的函數說明可定有人會想到將so文件放到一個指定的目錄然後再通過參數pathName直接引用該目錄的路勁和對應的so文件問題不就解決了嗎?
這里有個問題被忽略了,那就是System.load只能載入兩個目錄路勁下的so文件:
1、/system/lib ;
2、安裝包的路勁,即:/data/data/<packagename>/…
而且這兩個路勁又是有許可權保護的不能直接訪問;

問題解決方法:
先從網路下載so文件到手機目錄(如:/test/device/test.so) –> 將test.so載入到內存(ByteArrayOutputStream) –> 然後保存到對用安裝包目錄;
具體代碼如下:

try {
String localPath = Environment.getExternalStorageDirectory() + path;
Log.v(TAG, "LazyBandingLib localPath:" + localPath);

String[] tokens = mPatterns.split(path);
if (null == tokens || tokens.length <= 0
|| tokens[tokens.length - 1] == "") {
Log.v(TAG, "非法的文件路徑!");
return -3;
}
// 開辟一個輸入流
File inFile = new File(localPath);
// 判斷需載入的文件是否存在
if (!inFile.exists()) {
// 下載遠程驅動文件
Log.v(TAG, inFile.getAbsolutePath() + " is not fond!");
return 1;
}
FileInputStream fis = new FileInputStream(inFile);

File dir = context.getDir("libs", Context.MODE_PRIVATE);
// 獲取驅動文件輸出流
File soFile = new File(dir, tokens[tokens.length - 1]);
if (!soFile.exists()) {
Log.v(TAG, "### " + soFile.getAbsolutePath() + " is not exists");
FileOutputStream fos = new FileOutputStream(soFile);
Log.v(TAG, "FileOutputStream:" + fos.toString() + ",tokens:"
+ tokens[tokens.length - 1]);

// 位元組數組輸出流,寫入到內存中(ram)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
// 從內存到寫入到具體文件
fos.write(baos.toByteArray());
// 關閉文件流
baos.close();
fos.close();
}
fis.close();
Log.v(TAG, "### System.load start");
// 載入外設驅動
System.load(soFile.getAbsolutePath());
Log.v(TAG, "### System.load End");

return 0;

} catch (Exception e) {
Log.v(TAG, "Exception " + e.getMessage());
e.printStackTrace();
return -1;

}

閱讀全文

與androidso壓縮相關的資料

熱點內容
程序員為什麼素質低 瀏覽:891
可愛的程序員小姐姐 瀏覽:143
伺服器上網站的地址 瀏覽:796
蘋果平板如何找到app資源庫 瀏覽:319
阿里雲可以雲伺服器地址 瀏覽:247
熊貓繪畫app如何導入圖片 瀏覽:553
如何自己編輯手機app 瀏覽:922
程序員那麼可愛帶的項鏈 瀏覽:530
安卓系統導航mic什麼意思 瀏覽:190
編譯sdk如何輸出bin文件 瀏覽:673
如何用html5開發app 瀏覽:139
怎麼隱藏蘋果的app 瀏覽:324
上海捷豹空氣壓縮機 瀏覽:455
51單片機換行 瀏覽:735
哪裡可以快速學看建築圖紙app 瀏覽:500
內部排序的演算法比較 瀏覽:179
伺服器如何定期執行指令 瀏覽:931
python下載python腳本 瀏覽:297
台達plc遠程編程 瀏覽:263
雲計算的後台伺服器 瀏覽:589