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

android動態載入

發布時間: 2022-11-25 23:44:37

Ⅰ android中怎麼動態的載入一個布局

由於前段時間項目需要,需要在一個頁面上載入根據不同的按鈕載入不同的布局頁面,當時想到用 tabhot 。不過美工提供的界面圖完全用不上tabhot ,所以想到了動態載入的方法來解決這一需求。在這里我整理了一下,寫了一個 DEMO 希望大家以後少走點彎路。

首先,我們先把界面的框架圖畫出來,示意圖如下:

Ⅱ android 怎麼動態的載入類

android 如何動態的載入類----app插件技術

轉自:http://blog.csdn.net/mingli198611/article/details/8858076
?
前言:
?
? ? ? 在目前的軟硬體環境下,Native App與Web App在用戶體驗上有著明顯的優勢,但在實際項目中有些會因為業務的頻繁變更而頻繁的升級客戶端,造成較差的用戶體驗,而這也恰恰是Web App的優勢。現如今很多項目要求需要採用類似於微信或Q游這樣的插件化開發模式越來越多,本文就是闡述android的動態載入技術來滿足插件化開發模式的文章。
?
1.基本概念
1.1??在Android中可以動態載入,但無法像java中那樣方便動態載入jar。
Android的虛擬機(DalvikVM)是不認識Java打出jar的byte code,需要通過dx工具來優化轉換成Dalvikbyte code才行。這一點在咱們Android項目打包的apk中可以看出:引入其他Jar的內容都被打包進了classes.dex。即android要載入的java類必須dex格式的代碼文件.
1.2??在Android中可以載入基於NDK的so庫。
NDK的執行效率很高,加密性很好,但同時開發入門難度大,一般用於加解密、數學運算等場合。so的載入很簡單,如果APK發布時已經攜帶了so文件,只需要在載入時調用System.loadLibrary(libName)方法即可。由於軟體的安裝目錄中存放so的目錄是沒有寫許可權的,開發者不能更改該目錄的內容,所以如果要動態載入存放在其他地方的so文件,用System.load(pathName)方法即可。
1.3??在Android中支持動態載入dex文件的兩種方式:
DexClassLoader:這個可以載入jar/apk/dex,也可以從SD卡中載入,也是本文的重點
PathClassLoader:只能載入已經安裝到Android系統中的apk文件。也就是 /data/app 目錄下的 apk 文件。其它位置的文件載入的時候都會出現 ClassNotFoundException.因為 PathClassLoader 會去讀取 /data/dalvik-cache 目錄下的經過 Dalvik 優化過的 dex 文件,這個目錄的 dex 文件是在安裝 apk 包的時候由 Dalvik 生成的。
?
2.注意
2.1 採用不用安裝的插件開發模式,只能夠使用?DexClassLoader進行載入.不過動態載入是有一些限制的,比如插件(子apk)包中的Activity、Service類是不能動態載入的,因為缺少聲明;即使你在Manifest文件中進行了聲明,系統默認也是到安裝apk所在的路徑中去尋找類,所以你會遇到一個ClassNotFound的異常。插件里你可以用主apk中先前放入的layout、strings等資源。但是插件中自帶的界面只能用純代碼進行編寫,插件中是不能載入插件(子apk)中的xml作為layout等資源使用的。所以在開發上一些特效會比較困難些,建議預先植入主apk中。
2.2?大家可以看看DexClassLoader的API文檔,裡面不提倡從SD卡載入,不安全
3.如何製作插件
3.1 把工程導出為jar包
3.2 執行SDK安裝目錄android-sdk-windows\platform-tools下的dx命令,把jar包轉換為dex格式

dx?--dex?--output=dex名 jar包名

4.如何做到啟動未安裝的apk中的activity?

採用反射機制,把主apk中的activity的context傳遞到插件的activity中,然後採用反射進行回調插件activity的方法。不足之出就是,插件中的activity並不是真正的activity,它只是運行在主activity中。比如:點擊返回直接退出當前activity而不是回到主activity。實例如下:
?
這是調用的Activity:
?
[java]?view plain ? ?
package?com.beyondsoft.activity;??
??
import?java.lang.reflect.Constructor;??
import?java.lang.reflect.InvocationTargetException;??
import?java.lang.reflect.Method;??
??
import?dalvik.system.DexClassLoader;??
import?android.app.Activity;??
import?android.content.pm.PackageInfo;??
import?android.os.Bundle;??
import?android.util.Log;??
??
public?class?PlugActivity?extends?Activity?{??
??
????private?Class?mActivityClass;??
????private?Object?mActivityInstance;??
????Class?localClass;??
????private?Object?instance;??
??
????@Override??
????protected?void?onCreate(Bundle?savedInstanceState)?{??
????????super.onCreate(savedInstanceState);??
??
????????Bundle?paramBundle?=?new?Bundle();??
????????paramBundle.putBoolean("KEY_START_FROM_OTHER_ACTIVITY",?true);??
????????paramBundle.putString("str",?"PlugActivity");??
????????String?dexpath?=?"/sdcard/FragmentProject.apk";??
????????String?dexoutputpath?=?"/mnt/sdcard/";??
????????LoadAPK(paramBundle,?dexpath,?dexoutputpath);??
????}??
??
????@Override??
????protected?void?onStart()?{??
????????super.onStart();??
????????Method?start;??
????????try?{??
????????????start?=?localClass.getMethod("onStart");??
????????????????start.invoke(instance);??
????????}?catch?(Exception?e)?{??
????????????//?TODO?Auto-generated?catch?block??
????????????e.printStackTrace();??
????????}??
????}??
??
????@Override??
????protected?void?onResume()?{??
????????//?TODO?Auto-generated?method?stub??
????????super.onResume();??
????????Method?resume;??
????????try?{??
????????????resume?=?localClass.getMethod("onResume");??
????????????resume.invoke(instance);??
????????}?catch?(Exception?e)?{??
????????????//?TODO?Auto-generated?catch?block??
????????????e.printStackTrace();??
????????}??
????}??
??
????@Override??
????protected?void?onPause()?{??
????????super.onPause();??
????????Method?pause;??
????????try?{??
????????????pause?=?localClass.getMethod("onPause");??
????????????pause.invoke(instance);??
????????}?catch?(Exception?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
??
????@Override??
????protected?void?onStop()?{??
????????super.onStop();??
????????try?{??
????????????Method?stop?=?localClass.getMethod("onStop");??
????????????stop.invoke(instance);??
????????}?catch?(Exception?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
??
????@Override??
????protected?void?onDestroy()?{??
????????//?TODO?Auto-generated?method?stub??
????????super.onDestroy();??
????????try?{??
????????????Method?des?=?localClass.getMethod("onDestroy");??
????????????des.invoke(instance);??
????????}?catch?(Exception?e)?{??
????????????//?TODO?Auto-generated?catch?block??
????????????e.printStackTrace();??
????????}??
????}??

Ⅲ 如何在Android開發中動態載入的list列表數據

Android中載入list列表數據主要是通過Adapter實現,可用顯示列表的控制項如下:

  1. Listview

  2. GridView

  3. ExpandListview

顯示具體的數據需要通過Adapter實現,Android目前有4種Adapter:

  1. ArrayAdapter

  2. SimpleAdapter

  3. SimpleCursorAdapter

  4. BaseAdapter ( 自定義Adapter)

具體操作步驟 ( 以自定義Adapter為例):

  1. 在xml中定義Listview布局

  2. 在代碼中通過ID找到Listview控制項

  3. 構建Adapter對象,新建一個類繼承自BaseAdapter,重寫它的四個方法,具體如下代碼

  4. 構造好適配器後設置Listview的adapter對象為新建的適配器,界面即可顯示數據

  5. 在數據變動的地方,只需要調用adapter的notifyDataSetChanged方法即可刷新界面


  6. 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 怎麼動態載入jar

核心類 1.1 DexClassLoader類 可以載入jar/apk/dex,可以從SD卡中載入為安裝的apk。 1.2 PathClassLoader類 只能載入已經安裝到Android系統中的apk文件。 一、正文 1.1 類似於eclipse的插件化實現, 首先定義好介面, 用戶實現介面功能後即可通過動態載入的方式載入jar文件, 以實現具體功能。 注意 , 這里的jar包需要經過android dx工具的處理 , 否則不能使用。

Ⅳ Android動態載入資源

Fruit[] data = {"apple", "banana", "orange"};

int[] bitmaps= {R.drawable.apple, R.drawable.banana, R.drawable.orange};
for ( int i= 0; i < data.size; i ++ ){

Fruit temp= new Fruit(fruit, bitmaps[i]);

fruitList.add(temp);
}

Ⅵ 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的動態載入和靜態載入的區別

兩者區別:
一,靜態庫的使用需要:
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開發中動態載入的list列表數據

動態獲取的話,一般都是結合服務端通知客戶端數據更新,然後組成成一個list,通知你的界面進行重繪更新。

Ⅸ Android怎樣動態載入代碼技術

在開發Android App的過程當中,可能希望實現插件式軟體架構,將一部分代碼以另外一個APK的形式單獨發布,而在主程序中載入並執行這個APK中的代碼。

實現這個任務的一般方法是:

復制代碼
// 載入類cls
Context 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);
}

// 第二種載入方法
private Class<?> loadClass2(Context mainContext, String pkg, String entryCls) throws Exception {
Context pluginContext = mainContext.createPackageContext(pkg, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
String path = generatePluginDexPath(mainContext, pkg);
ensureFileExist(pluginContext, pkg, path);
// cacheDir必須是主程序的私有目錄,否則DexClassLoader可能會拒絕載入
String cacheDir = mainContext.getApplicationInfo().dataDir;
ClassLoader parentLoader = pluginContext.getClassLoader();
DexClassLoader loader = new DexClassLoader(path, cacheDir, null, parentLoader);
return loader.loadClass(entryCls);
}

// 獲取程序版本號
private int getVersionCode(Context context, String pkg) {
PackageInfo info = null;
int versionCode = 0;
try {
info = context.getPackageManager().getPackageInfo(pkg, PackageManager.GET_ACTIVITIES);
versionCode = info.versionCode;
} catch (Exception e) {}
return versionCode;
}

// 獲取插件二進制代碼的存儲位置,注意做好版本控制;路徑必須是以.dex結束,否則載入會出問題
private String generatePluginDexPath(Context context, String pkg) {
int version = getVersionCode(context, pkg);
String path = getMyAppPath() + ".classes/" + pkg + version + ".dex";
return path;
}

// 主程序在SD卡上的數據目錄
private String getMyAppPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyApp/";
}
// 拷貝插件的二進制代碼到SD卡
private void ensureFileExist(Context pluginContext, String pkg, String path) throws Exception {
File file = new File(path);
if(file.exists()) return;
file.getParentFile().mkdirs();
Resources res = pluginContext.getResources();
int id = res.getIdentifier("classes", "raw", pkg);
InputStream in = res.openRawResource(id);
FileOutputStream out = new FileOutputStream(file);
try {
byte[] buffer = new byte[1024 * 1024];
int n = 0;
while((n = in.read(buffer)) > 0) {
out.write(buffer, 0, n);
} out.flush();
} catch (IOException e) {
in.close();
out.close();
}
}
復制代碼

插件工程這邊也需要做相應的修改:

1.編譯插件工程;

2.將bin目錄之下的classes.dex拷貝到/res/raw目錄之下;

3.重新編譯插件工程;

4.發布插件APK。

Ⅹ Android動態載入dex技術初步了解

此處需要注意DexClassLoader的四個參數:
參數1 dexPath:待載入的dex文件路徑,如果是外存路徑,一定要加上讀外存文件的許可權(<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> ),否則會報與上面一樣的錯誤,這點參考文章2中說這個許可權可有可無是錯誤的。(更正下:Android4.4 KitKat及以後的版本需要此許可權,之前的版本不需要許可權)

熱點內容
通達信自定義板塊在哪個文件夾 發布:2024-05-06 09:56:37 瀏覽:103
在linux搭建mqtt伺服器搭建 發布:2024-05-06 09:52:00 瀏覽:558
windowspython23 發布:2024-05-06 09:27:50 瀏覽:746
編程ug開初 發布:2024-05-06 09:27:48 瀏覽:560
小白源碼論壇 發布:2024-05-06 09:24:56 瀏覽:139
android進程重啟 發布:2024-05-06 09:15:09 瀏覽:96
ie瀏覽器設置默認ftp 發布:2024-05-06 09:14:03 瀏覽:885
邁騰尊貴中控配置怎麼使用 發布:2024-05-06 09:13:28 瀏覽:656
奧迪存儲卡格式不正確請格式化存儲卡 發布:2024-05-06 09:01:31 瀏覽:34
個人信用資料庫 發布:2024-05-06 09:00:34 瀏覽:417