動態載入android
『壹』 如何動態載入android的so文件,如何壓縮apk尺寸
在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; }
『貳』 android 下如何動態載入觸摸屏驅動
TP驅動實現
1 修改ProjectConfig.mk
修改mediatek\config\prj\ProjectConfig.mk下的CUSTOM_KERNEL_TOUCHPANEL
其值由GT818B改為msg2133
2 增加ms2133驅動文件夾
根據TP廠家提供的驅動,我們在\mediatek\custom\common\kernel\touchpanel增加msg2133觸摸屏驅動文件夾msg2133,並做下面一些簡單修改正常使用。
(1) Msg2133介面的初始化
1) CHIP_EN片選使能引腳
mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN,GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN,GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN,GPIO_OUT_ONE);</span>
msg2133晶元使能引腳配置為GPIO模式、輸出高電平使能。
2) INT中斷引腳
mt_set_gpio_mode(GPIO_CTP_MSG2133_EINT_PIN,GPIO_CTP_MSG2133_EINT_PIN_M_EINT);
mt_set_gpio_dir(GPIO_CTP_MSG2133_EINT_PIN,GPIO_DIR_IN);
mt_set_gpio_pull_enable(GPIO_CTP_MSG2133_EINT_PIN,GPIO_PULL_ENABLE);
mt_set_gpio_pull_select(GPIO_CTP_MSG2133_EINT_PIN,GPIO_PULL_UP);</span>
配置為中斷模式、輸入、使能上下拉功能和設置為上拉。
(2) IIC地址
Msg2133的iic讀寫地址,我從數據手冊上沒有找到是如何確定這兩個地址的,驅動廠家在驅動代碼中提供,如果想要具體是怎麼確定的,可咨詢廠家。
#defineFW_ADDR_MSG21XX (0xC4>>1)
#defineFW_ADDR_MSG21XX_TP (0x4C>>1)//write,0x26
#defineFW_UPDATE_ADDR_MSG21XX (0x92>>1)//read,0x49</span>
(3) 增加TP的虛擬按鍵(virtual key)
要在TP上增加虛擬按鍵,需要在tp對應的頭文件添加下面的設置:
1) 定義TPD_HAVE_BUTTON
2) 定義TPD_BUTTON_HEIGHT、TPD_KEY_COUNT、TPD_KEYS和TPD_KEYS_DIM,分別用於定義button被識別的縱向坐標、虛擬按鍵個數、對應的功能鍵和每個功能鍵的坐標
#defineTPD_HAVE_BUTTON
#defineTPD_BUTTON_HEIGHT 800
#defineTPD_KEY_COUNT 4
#defineTPD_KEYS { KEY_BACK, KEY_SEARCH,KEY_MENU, KEY_HOMEPAGE }
#define TPD_KEYS_DIM {{200,900,10,10},{260,900,10,10},{40,900,10,10},{120,900,10,10}}</span>
其中,{200,900,10,10}對應了KEY_BACK的坐標, (200,900)是該key center的坐標,10是該鍵的寬度,10是該鍵的高度。
3) 根據顯示屏解析度修改相關的宏定義
#defineTPD_RES_X 480 // (320)
#defineTPD_RES_Y 800 //(480)</span>
把常用的實體按鍵(導航按鍵)映射到觸屏區域的快捷方式,不強制要求一定要有物理按鍵來支持用戶操作,這對開發全觸摸屏的產品非常有利。
『叄』 android 怎麼動態載入jar
核心類 1.1 DexClassLoader類 可以載入jar/apk/dex,可以從SD卡中載入為安裝的apk。 1.2 PathClassLoader類 只能載入已經安裝到Android系統中的apk文件。 一、正文 1.1 類似於eclipse的插件化實現, 首先定義好介面, 用戶實現介面功能後即可通過動態載入的方式載入jar文件, 以實現具體功能。 注意 , 這里的jar包需要經過android dx工具的處理 , 否則不能使用。
『肆』 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); }//
『伍』 如何在Android開發中動態載入的list列表數據
Android中載入list列表數據主要是通過Adapter實現,可用顯示列表的控制項如下:
Listview
GridView
ExpandListview
顯示具體的數據需要通過Adapter實現,Android目前有4種Adapter:
ArrayAdapter
SimpleAdapter
SimpleCursorAdapter
BaseAdapter ( 自定義Adapter)
具體操作步驟 ( 以自定義Adapter為例):
在xml中定義Listview布局
在代碼中通過ID找到Listview控制項
構建Adapter對象,新建一個類繼承自BaseAdapter,重寫它的四個方法,具體如下代碼
構造好適配器後設置Listview的adapter對象為新建的適配器,界面即可顯示數據
在數據變動的地方,只需要調用adapter的notifyDataSetChanged方法即可刷新界面
java">packagecom.beryl.gougou;
importandroid.content.Context;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.BaseAdapter;
importjava.util.List;
/**
*Createdbyyton16/11/14.
*/
{
privateList<String>datalist;
privateLayoutInflaterinflater;
publicMyAdapter(Contextcontext,List<String>datalist){
this.datalist=datalist;
inflater=LayoutInflater.from(context);
}
@Override
publicintgetCount(){
returndatalist.size();
}
@Override
publicObjectgetItem(intposition){
returndatalist.get(position);
}
@Override
publiclonggetItemId(intposition){
returnposition;
}
@Override
publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
//此處參考網上的view緩存機制,示例demo不多說明
returnnull;
}
}
『陸』 Android動態載入架包
先確認一下作為第三方庫引用的項目有沒有問題,然後再看打成架包是否正確,最後確認導入新項目是否正確。
『柒』 android動態載入布局更耗費資源嗎
不會的。動態載入其實是一種優化。很多時候我們都會在布局文件中加入一些不常使用的控制項,但是我們又真的很少使用它們,但是它們在進行初始化的時候,一樣會消耗我們的系統資源,因此我們應該考慮通過ViewStub來優化他,只在真正需要的時候使用它。
有時候,你的布局中會有一些比較復雜但是又很少用到的控制項。不管他是消息詳情,進度條還是未完成的提示信息,你都可以直到真正需要的時候再載入他們,以降低你的內存消耗,提升渲染效率。
『捌』 Android動態載入調用方法時方法的參數裡面帶有介面,如何獲取介面的回調
在Android中到處可見介面回調機制,尤其是UI事件處理方面,本文給大家介紹android介面回調機制,涉及到android介面回調相關知識,對本文感興趣的朋友可以參考下本篇文章
在使用介面回調的時候發現了一個經常犯的錯誤,就是回調函數裡面的實現有可能是用多線程或者是非同步任務去做的,這就會導致我們期望函數回調完畢去返回一個主函數的結果,實際發現是行不通的,因為如果回調是多線程的話你是無法和主函數同步的,也就是返回的數據是錯誤的,這是非常隱秘的一個錯誤。那有什麼好的方法去實現數據的線性傳遞呢?先介紹下回調機制原理。
回調函數
回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用為調用它所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。
開發中,介面回調是我們經常用到的。
介面回調的意思即,注冊之後並不立馬執行,而在某個時機觸發執行。
舉個例子:
A有一個問題不會,他去問B,B暫時解決不出來,B說,等我(B)解決了再告訴你(A)此時A可以繼續先做別的事情。
那麼就只有當B解決完問題後告訴A問題解決了,A才可以能解決這個問題。
代碼中比如最常用的:
一個Activity中給按鈕一個介面回調方法,只有用戶點擊了這個按鈕,告訴按鈕被點擊了,才會執行按鈕介面回調的方法
『玖』 android的動態載入和靜態載入的區別
兩者區別:
一,靜態庫的使用需要:
1
包含一個對應的頭文件告知編譯器lib文件裡面的具體內容
2
設置lib文件允許編譯器去查找已經編譯好的二進制代碼
二,動態庫的使用:
程序運行時需要載入動態庫,對動態庫有依賴性,需要手動加入動態庫
三,依賴性:
靜態鏈接表示靜態性,在編譯鏈接之後,
lib庫中需要的資源已經在可執行程序中了,
也就是靜態存在,沒有依賴性了
動態,就是實時性,在運行的時候載入需要的資源,那麼必須在運行的時候提供
需要的
動態庫,有依賴性,
運行時候沒有找到庫就不能運行了
四,區別:
簡單講,靜態庫就是直接將需要的代碼連接進可執行程序;動態庫就是在需要調用其中的函數時,根據函數映射表找到該函數然後調入堆棧執行。
做成靜態庫可執行文件本身比較大,但不必附帶動態庫
做成動態庫可執行文件本身比較小,但需要附帶動態庫
五:
首先糾正所謂「靜態連接就是把需要的庫函數放進你的exe之中」的說法。在真實世界中,有三個概念:Use
static
libary,
static
linked
DLL,
dynamic
linked
DLL.
多數人混淆了static
libary
和
static
linked
DLL的概念,當然他們有似是而非的「相似之處」,比如都用到.lib,下面具體說明。
使用靜態庫(Use
static
libary)是把.lib和其他.obj一起build在目標文件中,目標文件可以是.exe,也可以是.dll或.oxc等。一般情況下,可以根本就沒有「對應的」.dll
文件,如C
Run
Time(CRT)庫。一個例子就是,寫一個main(){},build出來並不是只有幾個位元組,當然有人會說那還有exe文件頭呢?是,即使加上文件頭的尺寸,build出的執行文件仍然「莫名的大」。實際上那多出來的部分就是CRT靜態庫。姑且可以把靜態庫.lib理解成外部程序的obj文件比較合理,它包含了函數的實現。
『拾』 android中怎麼動態的載入一個布局
由於前段時間項目需要,需要在一個頁面上載入根據不同的按鈕載入不同的布局頁面,當時想到用 tabhot 。不過美工提供的界面圖完全用不上tabhot ,所以想到了動態載入的方法來解決這一需求。在這里我整理了一下,寫了一個 DEMO 希望大家以後少走點彎路。
首先,我們先把界面的框架圖畫出來,示意圖如下: