真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android動(dòng)態(tài)加載,android動(dòng)態(tài)加載so庫(kù)

android的動(dòng)態(tài)加載和靜態(tài)加載的區(qū)別

兩者區(qū)別:

站在用戶的角度思考問題,與客戶深入溝通,找到新賓網(wǎng)站設(shè)計(jì)與新賓網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國(guó)際域名空間、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋新賓地區(qū)。

一,靜態(tài)庫(kù)的使用需要:

1

包含一個(gè)對(duì)應(yīng)的頭文件告知編譯器lib文件里面的具體內(nèi)容

2

設(shè)置lib文件允許編譯器去查找已經(jīng)編譯好的二進(jìn)制代碼

二,動(dòng)態(tài)庫(kù)的使用:

程序運(yùn)行時(shí)需要加載動(dòng)態(tài)庫(kù),對(duì)動(dòng)態(tài)庫(kù)有依賴性,需要手動(dòng)加入動(dòng)態(tài)庫(kù)

三,依賴性:

靜態(tài)鏈接表示靜態(tài)性,在編譯鏈接之后,

lib庫(kù)中需要的資源已經(jīng)在可執(zhí)行程序中了,

也就是靜態(tài)存在,沒有依賴性了

動(dòng)態(tài),就是實(shí)時(shí)性,在運(yùn)行的時(shí)候載入需要的資源,那么必須在運(yùn)行的時(shí)候提供

需要的

動(dòng)態(tài)庫(kù),有依賴性,

運(yùn)行時(shí)候沒有找到庫(kù)就不能運(yùn)行了

四,區(qū)別:

簡(jiǎn)單講,靜態(tài)庫(kù)就是直接將需要的代碼連接進(jìn)可執(zhí)行程序;動(dòng)態(tài)庫(kù)就是在需要調(diào)用其中的函數(shù)時(shí),根據(jù)函數(shù)映射表找到該函數(shù)然后調(diào)入堆棧執(zhí)行。

做成靜態(tài)庫(kù)可執(zhí)行文件本身比較大,但不必附帶動(dòng)態(tài)庫(kù)

做成動(dòng)態(tài)庫(kù)可執(zhí)行文件本身比較小,但需要附帶動(dòng)態(tài)庫(kù)

五:

首先糾正所謂“靜態(tài)連接就是把需要的庫(kù)函數(shù)放進(jìn)你的exe之中”的說法。在真實(shí)世界中,有三個(gè)概念:Use

static

libary,

static

linked

DLL,

dynamic

linked

DLL.

多數(shù)人混淆了static

libary

static

linked

DLL的概念,當(dāng)然他們有似是而非的“相似之處”,比如都用到.lib,下面具體說明。

使用靜態(tài)庫(kù)(Use

static

libary)是把.lib和其他.obj一起build在目標(biāo)文件中,目標(biāo)文件可以是.exe,也可以是.dll或.oxc等。一般情況下,可以根本就沒有“對(duì)應(yīng)的”.dll

文件,如C

Run

Time(CRT)庫(kù)。一個(gè)例子就是,寫一個(gè)main(){},build出來并不是只有幾個(gè)字節(jié),當(dāng)然有人會(huì)說那還有exe文件頭呢?是,即使加上文件頭的尺寸,build出的執(zhí)行文件仍然“莫名的大”。實(shí)際上那多出來的部分就是CRT靜態(tài)庫(kù)。姑且可以把靜態(tài)庫(kù).lib理解成外部程序的obj文件比較合理,它包含了函數(shù)的實(shí)現(xiàn)。

android和標(biāo)準(zhǔn)linux 動(dòng)態(tài)加載差異和分析

之前的分析android和標(biāo)準(zhǔn)linux在編譯器的差別,那么是標(biāo)準(zhǔn)編譯器編譯的bin文件是否可以在andorid上運(yùn)行的。

下面一個(gè)android bin為例,通過readelf -l命令,

再看標(biāo)準(zhǔn)的linux加載器

通過INTERP 段的區(qū)別,android使用linker程序,而標(biāo)準(zhǔn)Linux使用的是ld-linux.so這個(gè)so,內(nèi)核分析它的.interp段,也就是linker或者ld-linux.so,將動(dòng)態(tài)連接器映射到進(jìn)程的地址空間,然后將控制權(quán)交給動(dòng)態(tài)鏈接。

將arm-linux-gnueabi下的ld-linux.so.3和libc.so.6 copy到android平臺(tái)的/lib下

root@sp9820e_2h10:/lib # ls

ld-linux.so.3

libc.so.6

運(yùn)行helloworld,添加/lib到LD_LIBRARY_PATH,運(yùn)行成功

Android動(dòng)態(tài)加載dex技術(shù)初步了解

此處需要注意DexClassLoader的四個(gè)參數(shù):

參數(shù)1 dexPath:待加載的dex文件路徑,如果是外存路徑,一定要加上讀外存文件的權(quán)限(uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/ ),否則會(huì)報(bào)與上面一樣的錯(cuò)誤,這點(diǎn)參考文章2中說這個(gè)權(quán)限可有可無是錯(cuò)誤的。(更正下:Android4.4 KitKat及以后的版本需要此權(quán)限,之前的版本不需要權(quán)限)

Android怎樣動(dòng)態(tài)加載代碼技術(shù)

在開發(fā)Android App的過程當(dāng)中,可能希望實(shí)現(xiàn)插件式軟件架構(gòu),將一部分代碼以另外一個(gè)APK的形式單獨(dú)發(fā)布,而在主程序中加載并執(zhí)行這個(gè)APK中的代碼。

實(shí)現(xiàn)這個(gè)任務(wù)的一般方法是:

復(fù)制代碼

// 加載類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);

// 通過反射技術(shù),調(diào)用cls中的方法,下面是一個(gè)示例,實(shí)際代碼因情況而定

Object obj = cls.newInstance();

Method method = cls.getDeclaredMethod("someMethod");

method.invoke(obj);

復(fù)制代碼

但是,這個(gè)方法在Android 4.1及之后的系統(tǒng)中存在一些問題:對(duì)于收費(fèi)應(yīng)用,Google Play會(huì)將其安裝在一個(gè)加密目錄之下(具體就是/data/app-asec),而不是一個(gè)普通目錄之下(具體就是/data/app);安裝在加密目錄中的應(yīng)用,我們是無法使用上述方法來加載并執(zhí)行代碼的;而實(shí)際情況是,我們經(jīng)常就是依靠插件應(yīng)用來收費(fèi)的。

解決上述問題的一個(gè)方案是:將插件的二進(jìn)制代碼拷貝到SD卡中,主程序從SD卡中加載并執(zhí)行其代碼。

實(shí)現(xiàn)這個(gè)任務(wù)的具體方法是:

復(fù)制代碼

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可能會(huì)拒絕加載

String cacheDir = mainContext.getApplicationInfo().dataDir;

ClassLoader parentLoader = pluginContext.getClassLoader();

DexClassLoader loader = new DexClassLoader(path, cacheDir, null, parentLoader);

return loader.loadClass(entryCls);

}

// 獲取程序版本號(hào)

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;

}

// 獲取插件二進(jìn)制代碼的存儲(chǔ)位置,注意做好版本控制;路徑必須是以.dex結(jié)束,否則加載會(huì)出問題

private String generatePluginDexPath(Context context, String pkg) {

int version = getVersionCode(context, pkg);

String path = getMyAppPath() + ".classes/" + pkg + version + ".dex";

return path;

}

// 主程序在SD卡上的數(shù)據(jù)目錄

private String getMyAppPath() {

return Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyApp/";

}

// 拷貝插件的二進(jìn)制代碼到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();

}

}

復(fù)制代碼

插件工程這邊也需要做相應(yīng)的修改:

1.編譯插件工程;

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

3.重新編譯插件工程;

4.發(fā)布插件APK。

android 怎么動(dòng)態(tài)的加載類

android 如何動(dòng)態(tài)的加載類----app插件技術(shù)

轉(zhuǎn)自:

?

前言:

?

? ? ? 在目前的軟硬件環(huán)境下,Native App與Web App在用戶體驗(yàn)上有著明顯的優(yōu)勢(shì),但在實(shí)際項(xiàng)目中有些會(huì)因?yàn)闃I(yè)務(wù)的頻繁變更而頻繁的升級(jí)客戶端,造成較差的用戶體驗(yàn),而這也恰恰是Web App的優(yōu)勢(shì)?,F(xiàn)如今很多項(xiàng)目要求需要采用類似于微信或Q游這樣的插件化開發(fā)模式越來越多,本文就是闡述android的動(dòng)態(tài)加載技術(shù)來滿足插件化開發(fā)模式的文章。

?

1.基本概念

1.1??在Android中可以動(dòng)態(tài)加載,但無法像Java中那樣方便動(dòng)態(tài)加載jar。

Android的虛擬機(jī)(DalvikVM)是不認(rèn)識(shí)Java打出jar的byte code,需要通過dx工具來優(yōu)化轉(zhuǎn)換成Dalvikbyte code才行。這一點(diǎn)在咱們Android項(xiàng)目打包的apk中可以看出:引入其他Jar的內(nèi)容都被打包進(jìn)了classes.dex。即android要加載的java類必須dex格式的代碼文件.

1.2??在Android中可以加載基于NDK的so庫(kù)。

NDK的執(zhí)行效率很高,加密性很好,但同時(shí)開發(fā)入門難度大,一般用于加解密、數(shù)學(xué)運(yùn)算等場(chǎng)合。so的加載很簡(jiǎn)單,如果APK發(fā)布時(shí)已經(jīng)攜帶了so文件,只需要在加載時(shí)調(diào)用System.loadLibrary(libName)方法即可。由于軟件的安裝目錄中存放so的目錄是沒有寫權(quán)限的,開發(fā)者不能更改該目錄的內(nèi)容,所以如果要?jiǎng)討B(tài)加載存放在其他地方的so文件,用System.load(pathName)方法即可。

1.3??在Android中支持動(dòng)態(tài)加載dex文件的兩種方式:

DexClassLoader:這個(gè)可以加載jar/apk/dex,也可以從SD卡中加載,也是本文的重點(diǎn)

PathClassLoader:只能加載已經(jīng)安裝到Android系統(tǒng)中的apk文件。也就是 /data/app 目錄下的 apk 文件。其它位置的文件加載的時(shí)候都會(huì)出現(xiàn) ClassNotFoundException.因?yàn)?PathClassLoader 會(huì)去讀取 /data/dalvik-cache 目錄下的經(jīng)過 Dalvik 優(yōu)化過的 dex 文件,這個(gè)目錄的 dex 文件是在安裝 apk 包的時(shí)候由 Dalvik 生成的。

?

2.注意

2.1 采用不用安裝的插件開發(fā)模式,只能夠使用?DexClassLoader進(jìn)行加載.不過動(dòng)態(tài)加載是有一些限制的,比如插件(子apk)包中的Activity、Service類是不能動(dòng)態(tài)加載的,因?yàn)槿鄙俾暶?;即使你在Manifest文件中進(jìn)行了聲明,系統(tǒng)默認(rèn)也是到安裝apk所在的路徑中去尋找類,所以你會(huì)遇到一個(gè)ClassNotFound的異常。插件里你可以用主apk中先前放入的layout、strings等資源。但是插件中自帶的界面只能用純代碼進(jìn)行編寫,插件中是不能加載插件(子apk)中的xml作為layout等資源使用的。所以在開發(fā)上一些特效會(huì)比較困難些,建議預(yù)先植入主apk中。

2.2?大家可以看看DexClassLoader的API文檔,里面不提倡從SD卡加載,不安全

3.如何制作插件

3.1 把工程導(dǎo)出為jar包

3.2 執(zhí)行SDK安裝目錄android-sdk-windows\platform-tools下的dx命令,把jar包轉(zhuǎn)換為dex格式

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

4.如何做到啟動(dòng)未安裝的apk中的activity?

采用反射機(jī)制,把主apk中的activity的context傳遞到插件的activity中,然后采用反射進(jìn)行回調(diào)插件activity的方法。不足之出就是,插件中的activity并不是真正的activity,它只是運(yùn)行在主activity中。比如:點(diǎn)擊返回直接退出當(dāng)前activity而不是回到主activity。實(shí)例如下:

?

這是調(diào)用的Activity:

?

[java]?view plaincopy ? ?

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動(dòng)態(tài)加載,android動(dòng)態(tài)加載so庫(kù)
瀏覽路徑:http://weahome.cn/article/hoehid.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部