當前位置:首頁 » 安卓系統 » androidapk動態載入

androidapk動態載入

發布時間: 2023-09-23 11:58:23

1. Android APK安裝流程(4)--APK載入

上面 主要分析到APK的過程,這里我們開始分析APK的載入過程。直接看之前流程進行到下一步的 processPendingInstall() 方法:

installPackagesLI() 可以支持單包和多包載入,載入主要分為4個階段:

執行完2-2的 scanPackageTrackLI() 之後Pms的兩大核心數據結構都已經准備好了,一個是代表掃描結果的final ArrayMap<String, PackageParser.Package> mPackages = new ArrayMap<>();中的PackageParser.Package,另外一個是mSettings.mPackages的PackageSetting 數據結構,這兩個結構PackageParser.Package代表掃描結果,為靜態數據,掃描完成後就不會發生變化。PackageSetting用於存儲安裝應用的動態數據,如許可權授予情況等。PackageParser.Package由於是靜態數據,掃描apk就可以獲取。PackageSetting生成之後會被記錄到文件中,以後每次系統啟動都會重新載入。

2. 如何動態載入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;

}

3. Android怎樣動態載入代碼技術

在開發Android App的過程當中,可能希望實現插件式軟體架構,將一部分代碼以另外一個APK的形式單獨發布,而在主程序中載入並執行這個APK中的代碼。 實現這個任務的一般方法是:// 載入類clsContext pluginContext = mainContext.createPackageContext(PLUGIN_PKG, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);ClassLoader loader = pluginContext.getClassLoader();Class<?> cls = loader.loadClass(CLASS_NAME);// 通過反射技術,調用cls中的方法,下面是一個示例,實際代碼因情況而定Object obj = cls.newInstance();Method method = cls.getDeclaredMethod("someMethod");method.invoke(obj); 但是,這個方法在Android 4.1及之後的系統中存在一些問題:對於收費應用,Google Play會將其安裝在一個加密目錄之下(具體就是/data/app-asec),而不是一個普通目錄之下(具體就是/data/app);安裝在加密目錄中的應用,我們是無法使用上述方法來載入並執行代碼的;而實際情況是,我們經常就是依靠插件應用來收費的。 解決上述問題的一個方案是:將插件的二進制代碼拷貝到SD卡中,主程序從SD卡中載入並執行其代碼。 實現這個任務的具體方法是:Class<?> cls = null;try { // 嘗試第一種方法 cls = loadClass1(mainContext, pkg, entryCls);} catch (Exception e) { // 嘗試第二種方法 cls = loadClass2(mainContext, pkg, entryCls);}// 示例代碼Object obj = cls.newInstance();Method method = cls.getDeclaredMethod("someMethod");method.invoke(obj);// 第一種載入方法private Class<?> loadClass1(Context mainContext, String pkg, String entryCls) throws Exception { Context pluginContext = mainContext.createPackageContext(pkg, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); ClassLoader loader = pluginContext.getClassLoader(); return loader.loadClass(entryCls); }//

熱點內容
php環境部署 發布:2025-01-26 15:28:09 瀏覽:17
python實現svm 發布:2025-01-26 15:24:25 瀏覽:381
易語言寫ip全局代理伺服器 發布:2025-01-26 15:04:01 瀏覽:668
gm命令在哪個文件夾 發布:2025-01-26 15:03:12 瀏覽:307
javadate類 發布:2025-01-26 14:58:54 瀏覽:352
領航s1配置怎麼樣 發布:2025-01-26 09:58:10 瀏覽:763
公司區域網搭建伺服器搭建 發布:2025-01-26 09:16:56 瀏覽:433
android裁剪圓形圖片 發布:2025-01-26 09:05:56 瀏覽:411
小貸源碼 發布:2025-01-26 08:20:58 瀏覽:536
更換電腦名登錄伺服器 發布:2025-01-26 07:56:52 瀏覽:240