1. 程式人生 > >外掛載入帶有動態庫so的apk處理

外掛載入帶有動態庫so的apk處理

     外掛載入帶有動態庫的apk時,會報UnsatisfiedLinkError找不到動態庫的錯誤。

解決方法是在DexClassLoader中

dalvik.system.DexClassLoader.DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)

第三個引數是指定動態庫的路徑,因此我們需要把動態庫給解壓出來放到data/data/xx(package),arm手機的t卡是載入不了

因此我需要找到對應的手機cpu型別,並解壓對應的動態庫,對應的程式碼如下:

	private static boolean IsDirEquals(String srcfile,String objDir)
	{
		try{
			int index = srcfile.lastIndexOf("/");
			String dir = null;
			String firstDirName = null;
			if(index != -1)
				dir = srcfile.substring(0,index );
			
			index = srcfile.indexOf("/");
			if(index != -1)
				firstDirName = srcfile.substring(0, index);
			

			if(null != dir && dir.equalsIgnoreCase(objDir))
			{
				return true;
			}
			else if(null != firstDirName && firstDirName.equalsIgnoreCase(objDir))
			{
					return true;
			}
			}catch(Exception e){
			e.printStackTrace();
		}
		
		return false;
		
		
	}
	
	public static void UnzipSpecificFile(String zipFile, String targetDir,ArrayList<String> objDirList) {
		int BUFFER = 4096; // 這裡緩衝區我們使用4KB,
		String strEntry; // 儲存每個zip的條目名稱
		ZipInputStream zis = null;
		try {
			BufferedOutputStream dest = null; // 緩衝輸出流
			FileInputStream fis = new FileInputStream(zipFile);
			zis = new ZipInputStream(new BufferedInputStream(fis));
			ZipEntry entry; // 每個zip條目的例項
			

			
			while ((entry = zis.getNextEntry()) != null) {

				try {
					// Log.i("Unzip: ","="+ entry);
					int count;
					byte data[] = new byte[BUFFER];
					strEntry = entry.getName();
					
					boolean find = false;
					for(String dir:objDirList)
					{
						if(IsDirEquals(strEntry.toString(),dir))
						{
							find = true;
							break;
						}
					}
					
					if(false == find)
						continue;
					
					File entryFile = new File(targetDir + strEntry);
					File entryDir = new File(entryFile.getParent());
					
					if (!entryDir.exists()) {
						entryDir.mkdirs();
					}

					FileOutputStream fos = new FileOutputStream(entryFile);
					dest = new BufferedOutputStream(fos, BUFFER);
					while ((count = zis.read(data, 0, BUFFER)) != -1) {
						dest.write(data, 0, count);
					}
					dest.flush();

				} catch (Exception ex) {
					ex.printStackTrace();
				} finally {
					if (null != dest)
						dest.close();
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != zis)
					zis.close();

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	// 獲取手機CPU型別資訊
	final static public String getCpuInfo() {
		String str1 = "/proc/cpuinfo";
		String str2 = "";
		String[] cpuInfo = { "", "" }; // 1-cpu型號 //2-cpu頻率
		String[] arrayOfString;
		FileReader fr = null;
		BufferedReader localBufferedReader = null;
		try {
			fr = new FileReader(str1);
			localBufferedReader = new BufferedReader(fr, 8192);
			str2 = localBufferedReader.readLine();
			arrayOfString = str2.split("\\s+");
			for (int i = 2; i < arrayOfString.length; i++) {
				cpuInfo[0] = cpuInfo[0] + arrayOfString[i] + " ";
			}
			str2 = localBufferedReader.readLine();
			arrayOfString = str2.split("\\s+");
			cpuInfo[1] += arrayOfString[2]; // cpu頻率。
			localBufferedReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fr != null)
					fr.close();

				if (localBufferedReader != null)
					localBufferedReader.close();

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// Log.i(TAG, "cpuinfo:" + cpuInfo[0] + " " + cpuInfo[1]);
		if ((cpuInfo[0].toLowerCase().contains("armv7"))) {
			return "armeabi-v7a";
		} else if ((cpuInfo[0].toLowerCase().contains("arm"))) {
			return "armeabi";
		} else if ((cpuInfo[0].toLowerCase().contains("mips"))) {
			return "mips";
		} else {
			return "x86";
		}

	}
解壓完lib/xxx(armeabi/armeabi-v7a等)放到對應的目錄,並使用
System.loadLibrary

來載入動態庫就ok了,其中這個方法會根據之前的classLoader傳入的路徑去查詢檔案。

後面找lib庫貌似有點多餘,應該只需要找到apk的lib資料夾就可以避免列舉整個apk檔案,這個是後面需要改進的方向。


相關推薦

外掛載入帶有動態so的apk處理

     外掛載入帶有動態庫的apk時,會報UnsatisfiedLinkError找不到動態庫的錯誤。 解決方法是在DexClassLoader中 dalvik.system.DexClassLoader.DexClassLoader(String dexPath, S

配置環境的時候,PHP無法載入MySQL動態,麻煩大家幫忙看看!nocsl

不出 沒有 都沒有 小狗狗 ocs 想象 無法 配置環境 配置 黑暗降臨 夜空再一次降臨在人們的視線中 繁星點點 是那麽的美麗 當一顆流星夜空又添了一道美麗的景色 不過它消失的是那麽快 它匆匆的來又匆匆地走 沒留下一絲痕跡 但它確實來過 我常常在想 人生不就如此嗎?雖然現在

Android WebView載入Chromium動態的過程分析

        Chromium動態庫的體積比較大,有27M左右,其中程式段和資料段分別佔據25.65M和1.35M。如果按照通常方式載入Chromium動態庫,那麼當有N個正在執行的App使用WebView時,系統需要為Chromium動態庫分配的記憶體為

載入執行動態

void * dlopen(const char* filename, int flag); 開啟一個動態庫檔案,返回一個指標作為控制代碼handle.失敗返回NULL. flag: RTLD_NOW(RunTime Load Dynamic ):表示立即載入到記憶體 RT

java.lang.UnsatisfiedLinkError: Can not load XXX library ... JNA不能載入DLL動態問題

 java.lang.UnsatisfiedLinkError: Can not load XXX library ... JNA不能載入DLL動態庫問題 1, 版本問題。 版本一定要對應。 64位系統,對應64的jdk或者jre,同時對應動態庫也需要64位的。 32位也是

查詢程式載入動態的路徑

事件的起因: 最近編譯gtk版的webkit後發現,他需要指令碼Tools/Scripts/run-launcher來啟動WebKitBuild/Debug/Programs的GtkLauncher、MiniBrowser等 如果正常執行會發生出下異常 [email

osgEarth的Rex引擎原理分析(二)osg是如何根據副檔名尋找需要載入動態連結外掛

在(一)中有createLibraryNameForFile,它會根據副檔名構造需要載入的動態連結庫 osgDB/Registry.cpp ReaderWriter::ReadResult Registry::read(const ReadFunctor& re

Linux 動態載入

動態庫執行時搜尋順序 1.LD_PRELOAD   LD_PRELOAD是一個環境變數,用於動態庫載入,動態庫載入的優先順序最高;   2.-wl,-rpath   編譯目的碼時指定的動態庫搜尋路徑(指的是用-wl,-rpath),readelf -d 命令可以檢視編譯的目標檔案中rpat

沒有載入動態導致的error: symbol lookup error: undefined symbol

做了一個瀏覽器外掛,需要編譯為 abcPlugins.so , 這個.so需要呼叫另外一個業務庫 defLib.so裡面的函式。 把abcPlugins.so替換到目標板上,瀏覽器程序啟動不起來。   1. 查詢瀏覽器程序啟動過程錯誤    1

靜態連結(LIB)和動態連結(DLL),DLL的靜態載入動態載入,兩種LIB檔案。

靜態連結庫(LIB)和動態連結庫(DLL),DLL的靜態載入和動態載入,兩種LIB檔案。 一、 靜態連結庫(LIB,也簡稱“靜態庫”)與動態連結庫(DLL,也簡稱“動態庫”)的區別 靜態連結庫與動態連結庫都是共享程式碼的方式,如果採用靜態連結庫,則無論你願不願意,lib 中的指令都全部被直接包含在最

C++載入動態的形式來實現封裝

目錄結構 └── test ├── CMakeLists.txt ├── base.h //設定介面 ├── drive.cpp //具體實現 └── main.cpp

啟動優化之動態延遲載入

程式啟動過程中載入過多動態庫會導致啟動變慢,尤其是剛開機時啟動程式,載入過多的dll會佔用IO,這時候系統IO通常是非常繁忙的,會拖慢啟動速度。         動態庫載入包括靜態載入和動態載入, 靜態載入就是使

Linux動態載入函式dlopen原始碼梳理(二)

中大概梳理了整個流程,還有_dl_map_object_from_fd(),以及link_map結構沒有進行分析,在這裡對這兩部分進行分析 由於_dl_map_object_from_fd()比較長,整個函式的程式碼就放到最後作為附錄,前面部分來一點點進行梳理。 一、

Windows開發之動態載入

前段時間寫程式碼,主程序要載入很多dll,剛開始寫的dll動態載入,好麻煩的說。老大說寫成靜態載入,理解錯了意思,改成了靜態庫,真的傻。好長時間沒寫動態庫,忘得差不多了,筆記裡也是簡單記了下。最後改成了個dll靜態載入,現在來總結一下吧。 動態庫,在Windows下為dll檔案,Linux下是so,這裡先不

【Unity】Unity資源池的動態載入釋放和記憶體優化處理

需求環境         在上一級的【解決方案】文章中,我們設計出了動態載入資源的業務流程,而這一節,我們就通過一些簡單的程式碼,來實現出業務流程中的效果。        吸取之前文章的經驗,如

OSX10.9 QT5.3.1 關於載入動態(Cannot load library.....)

在LINUX 、WINDOWS程式正常,但在MAC下卻不能載入。如下圖 在生成的APP檔案,右鍵‘顯示包內容’  位定到  fnd_main.app/Contents/MacOS,把生成的動態庫 *.dblib複製進去。 ASSERT: "uint(i) <

深入理解LINUX下動態連結器/載入器ld-linux.so.2

最近在Linux 環境下開發,搞了好幾天 Compiler 和 linker,覺得有必要來寫一篇關於Linux環境下 ld.so的文章了,google上搜索了很多相關介紹性的文件,發現國內百度上卻很少有相關類文件,覺得有必要來梳理一下: ld-linux.so.2 是

linux中動態的編譯和載入的查詢順序

Glibc安裝的庫中有一個名為ld-Linux.so.X其中X為一個數字(版本), 在不同的平臺上可以通過ldd檢視 $ldd /bin/cat linux-vdso.so.1 =>  (0x00007fff9176f000) libc.so.6 => /lib

CodeBlocks載入動態動態

CodeBlocks新建一個Dynamic Link Library工程,工程名稱叫做:dll,程式碼已由嚮導自己生成好了 這裡函式就不寫了 編譯該工程,Ctrl+F9,完畢,關閉工程 再新建一個Project,名稱為cbp,選擇Console application,完