東坡下載:內(nèi)容最豐富最安全的下載站!

首頁IT技術(shù)安卓教程 → 實(shí)現(xiàn)Android 動(dòng)態(tài)加載APK(Fragment or Activity實(shí)現(xiàn))

實(shí)現(xiàn)Android 動(dòng)態(tài)加載APK(Fragment or Activity實(shí)現(xiàn))

相關(guān)文章發(fā)表評(píng)論 來源:本站整理時(shí)間:2018/5/25 11:45:47字體大。A-A+

更多

作者:專題點(diǎn)擊:85次評(píng)論:0次標(biāo)簽: APK

首先我們需要明白,實(shí)現(xiàn)動(dòng)態(tài)加載就是要解決兩個(gè)問題:(如果使用Fragments實(shí)現(xiàn),則是一個(gè)問題)

1、Activity生命周期的管理。

2、動(dòng)態(tài)加載的apk的資源如何獲取。

第一個(gè)問題是因?yàn)樵?a target="_blank" href='http://tipsywinegypsy.com/fz/java/'>java中任何一個(gè)程序要運(yùn)行起來,必須通過類加載器將某個(gè)類加入內(nèi)存,當(dāng)我們通過一個(gè)類加載器將Activity加入內(nèi)存時(shí),其實(shí)這個(gè)Activity就是一個(gè)普通的類,它已經(jīng)沒有生命周期的概念了,在Android系統(tǒng)中,Activity的生命周期是通過ActivityManager來控制的,如果我們通過動(dòng)態(tài)加載的方式加載這個(gè)Activity,那么ActivityManager根本就不知道這個(gè)Activity的存在,所以我們必須處理好這個(gè)Activity的生命周期,至于第二個(gè)問題,在Android中,我們獲取資源都是通過Context拿到的,而動(dòng)態(tài)加載的APK是沒有Context的,所以我們不能和以前一樣那樣來拿。前面的兩篇文章推薦的方法已經(jīng)能夠很好的解決以上兩個(gè)問題,因此實(shí)現(xiàn)了APK的動(dòng)態(tài)加載。
我先來描述一下大牛博客中實(shí)現(xiàn)動(dòng)態(tài)加載的思路吧:
創(chuàng)建一個(gè)ProxyActivity,通過名字知道,它就是一個(gè)代理Activity,我們調(diào)用任何一個(gè)Activity都是通過調(diào)用ProxyActivity實(shí)現(xiàn)的,我只需要傳入動(dòng)態(tài)加載apk的路徑和需要?jiǎng)討B(tài)加載的類名,比如加載了一個(gè)Activity之后,通過反射機(jī)制讀取到Activity的所有的生命周期函數(shù)以及onActivityResult等函數(shù),并保存在一個(gè)列表中,在ProxyActivity的onCreate中通過反射調(diào)用動(dòng)態(tài)加載的Activity的onCreate,由于ProxyActivity是一個(gè)正常的Activity,它的生命周期是正常的,所以在ProxyActivity的生命周期函數(shù)中調(diào)用動(dòng)態(tài)加載Activity的生命周期函數(shù)就ok了,從而實(shí)現(xiàn)動(dòng)態(tài)加載的Activity也有生命周期了。同時(shí)盡然是代理,那么就代理徹底一點(diǎn),就干脆把動(dòng)態(tài)加載的Activity中的所有的邏輯都轉(zhuǎn)入到ProxyActivity中。那么這就要求被加載的Activity有一個(gè)ProxyActivity的引用,這個(gè)可以讓所有動(dòng)態(tài)加載的Activity繼承一個(gè)BaseActivity,這個(gè)BaseActivity中有一個(gè)setProxy方法,用來設(shè)置ProxyActivity。所以不是任何APK,都可以動(dòng)態(tài)加載的,一般只有動(dòng)態(tài)加載自己編寫的apk,動(dòng)態(tài)加載別人的apk不太現(xiàn)實(shí)。
看了上面的思路,是不是有點(diǎn)借腹生子的感覺,其實(shí)就是把動(dòng)態(tài)加載的Activity的邏輯轉(zhuǎn)移到了ProxyActivity

解決資源訪問的問題方法就是造ProxyActivity中重載者兩個(gè)函數(shù)
 public abstract AssetManager getAssets();
 public abstract Resources getResources();
 至于為什么能解決資源的問題,我還是推薦幾篇文章大家去學(xué)習(xí)一下吧:
 本人的另外一篇文章:http://blog.csdn.net/yuanzeyao/article/details/12955459
 講解Android資源加載機(jī)制的一篇文章:http://blog.csdn.net/singwhatiwanna/article/details/24532419
 
好了,上面就是通過Activity實(shí)現(xiàn)的動(dòng)態(tài)加載apk,下面看看我是怎么通過Fragment來實(shí)現(xiàn)動(dòng)態(tài)加載的,如果熟悉Fragment的同學(xué)們應(yīng)該知道,F(xiàn)ragment就相當(dāng)于一個(gè)有生命周期的View,它的生命周期被所在的Activity的生命周期管理,即使我們通過類加載器把一個(gè)Fragment加入到內(nèi)存,它和以前我們使用的Fragment沒有什么兩樣,只要我們將這個(gè)Fragment加入到ProxyActivity,ProxyActivity就會(huì)自動(dòng)的管理好這個(gè)Fragment的生命周期。所以我們就不需要擔(dān)心Fragment的生命周期,下面就來看看代碼實(shí)現(xiàn)吧:

1、BaseFragment.java

[java] view plain copy

public class BaseFragment extends Fragment implements IConstant  

{  

private static final String TAG = "BaseFragment";  

protected String mDexPath;  

@Override  

public void onCreate(Bundle savedInstanceState)  

{  

super.onCreate(savedInstanceState);  

Bundle bundle=this.getArguments();  

//動(dòng)態(tài)加載apk的路徑  

mDexPath=bundle.getString(DEX_PATH);  

}  

//在Fragment中啟動(dòng)另外一個(gè)Fragment  

protected void replaceFragmentByProxy(String name)  

{  

if(mDexPath==null)  

return;  

//PROXY_VIEW_ACTION 是ProxyActivity的action  

Intent intent=new Intent(PROXY_VIEW_ACTION);  

//傳遞apk路徑  

intent.putExtra(DEX_PATH, mDexPath);  

//是啟動(dòng)Fragment還是啟動(dòng)Fragment,這里啟動(dòng)的是Fragment  

intent.putExtra(START_TYPE, TYPE_FRAGMENT);  

//需要加載的fragment的類名  

intent.putExtra(CLASS_NAME, name);  

this.startActivity(intent);  

}  

}  


所有需要?jiǎng)討B(tài)加載的Fragment都需要繼承這個(gè)BaseFragment,每次啟動(dòng)一個(gè)Fragment,只需要傳遞apk的路徑即可。
下面是我寫的一個(gè)MyFragment,用來使用BitmapFun加載網(wǎng)絡(luò)圖片的,這里僅僅是加載并顯示圖片,沒有考慮其他的,如果想深入了解BitmapFun的使用,請(qǐng)看我的另外一篇文章:
http://blog.csdn.net/yuanzeyao/article/details/38355719

[java] view plain copy

public class MyFragment extends BaseFragment  

{  

private static final String TAG = "MyFragment";  

private static final String IMAGE_CACHE_DIR = "thumbs";  

private ImageFetcher mImageFetcher;  

private GridView mGridView;  

private Context context;  

private Button btn;  

@Override  

public void onCreate(Bundle savedInstanceState)  

{  

super.onCreate(savedInstanceState);  

ImageCacheParams cacheParams = new ImageCacheParams(getActivity(), IMAGE_CACHE_DIR);  

cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 25% of app memory  

// The ImageFetcher takes care of loading images into our ImageView children asynchronously  

mImageFetcher = new ImageFetcher(getActivity(), 200);  

mImageFetcher.setLoadingImage(R.drawable.empty_photo);  

mImageFetcher.addImageCache(getActivity().getSupportFragmentManager(), cacheParams);  

}  

@Override  

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  

{  

//這里其實(shí)可以直接使用R.layout.fragment  

Resources mResources=this.getActivity().getResources();  

return inflater.inflate(mResources.getIdentifier("fragment", "layout", "com.dl.client"), container,false);  

}  

@Override  

public void onViewCreated(View view, Bundle savedInstanceState)  

{  

super.onViewCreated(view, savedInstanceState);  

mGridView=(GridView) view.findViewById(R.id.gridView);  

btn=(Button)view.findViewById(R.id.btn_fragment);  

btn.setOnClickListener(new View.OnClickListener()  

{  

@Override  

public void onClick(View arg0)  

{  

//在Fragment中動(dòng)態(tài)加載另外一個(gè)Fragment  

replaceFragmentByProxy("com.dl.client.TempFragment");  

}  

});  

context=this.getActivity();  

mGridView.setAdapter(new BaseAdapter()  

{  

@Override  

public View getView(int position, View contentView, ViewGroup arg2)  

{  

ImageView mImg;  

if(contentView==null)  

{  

contentView=LayoutInflater.from(context).inflate(R.layout.item,null);  

}  

mImg=(ImageView)contentView.findViewById(R.id.img_11);  

//mImg.setImageResource(R.drawable.empty_photo);  

mImageFetcher.loadImage(Images.imageThumbUrls[position], mImg);  

return contentView;  

}  

@Override  

public long getItemId(int arg0)  

{  

return 0;  

}  

@Override  

public Object getItem(int arg0)  

{  

return Images.imageThumbUrls[arg0];  

}  

@Override  

public int getCount()  

{  

return Images.imageThumbUrls.length;  

}  

});  

}  

}  


下面看看這個(gè)應(yīng)用的效果吧:

最后需要注意的一點(diǎn)就是動(dòng)態(tài)加載的apk不能和宿主應(yīng)用包含相同的jar包,不然會(huì)報(bào)錯(cuò)的。。。

  • apk提取工具合集
  • 專業(yè)的音頻提取器
  • 手機(jī)網(wǎng)名生成器軟件
  • RE管理器版本大全
apk提取工具合集
(6)apk提取工具合集

我們經(jīng)常會(huì)發(fā)現(xiàn)安裝在手機(jī)上的apk文件不知道哪里去了,想刪也不會(huì)刪,或者想提取出來發(fā)送給別人也不知道位置,小編也經(jīng)常會(huì)有這樣的困難,所以找了幾款蠻好用的apk提取工具,可以將手機(jī)上所有的apk文件都提取出來,編輯刪除或者發(fā)送都可以隨意操作。

...更多>>
  • 簡(jiǎn)備app1.0(1107) 安卓最新版

    11-19 / 1.9M

    推薦理由:非常簡(jiǎn)單易用的手機(jī)apk提取軟件,簡(jiǎn)備app的功能簡(jiǎn)單實(shí)用,可以提取,備份和分享手機(jī)上的應(yīng)用,簡(jiǎn)單小巧,支
  • Apk備份提取工具下載6.13去廣告版【

    09-19 / 681KB

    推薦理由:Apk備份提取工具是一款能幫你提取手機(jī)圖標(biāo)的手機(jī)軟件,在無需root權(quán)限的前提下,就能將手機(jī)系統(tǒng)級(jí)的應(yīng)用提取
  • APK提取器(APK Extractor )4.0.7 中

    06-26 / 1.5M

    推薦理由:apk管理器是現(xiàn)在手機(jī)上很流行的一款不錯(cuò)的備份以及軟件管理的工具,這款工具是不需要你的手機(jī)進(jìn)行root的,就
  • 手機(jī)軟件管理軟件(APK提取器)3.5 安

    06-04 / 190KB

    推薦理由:現(xiàn)在有很多的朋友都是喜歡在自己的手機(jī)上下載各種各樣的軟件的,那么現(xiàn)在小編就給你的手機(jī)上介紹一款不錯(cuò)的
  • APK包名簽名提取1.5 免費(fèi)版

    07-11 / 3.9M

    推薦理由:APK應(yīng)用提取是一款無需root就可以使用的工具,很小巧。它可以掃描出手機(jī)里所有的程序,一鍵復(fù)制就可以提取A
  • 軟件版本自定義app1.1 安卓最新版

    02-05 / 36KB

    推薦理由:一些安卓的應(yīng)用軟件經(jīng)常會(huì)更新,每次打開都提示要升級(jí),很煩人,應(yīng)用版本自定義app是由網(wǎng)友自己制作的一款X
專業(yè)的音頻提取器
(6)專業(yè)的音頻提取器

專業(yè)的音頻提取器,讓您從各種格式視頻中提取各種格式的音頻,從視頻中提取音頻保存為MP3等格式,其操作極其簡(jiǎn)單,且轉(zhuǎn)換后的音頻文件可以保存到您的手機(jī)中。軟件支持所有視頻格式,在里面直接播放也可以。

...更多>>
手機(jī)網(wǎng)名生成器軟件
(9)手機(jī)網(wǎng)名生成器軟件

每個(gè)人都想要擁有獨(dú)一無二的網(wǎng)名,那么特殊的、個(gè)性化的網(wǎng)名如何制作呢?東坡小編為你收集整理了幾款手機(jī)網(wǎng)名生成器軟件,都擁有體積小、操作簡(jiǎn)單,花樣多等特點(diǎn),軟件中多種網(wǎng)名樣式可供選擇,只需要輸入網(wǎng)名就能制作一款個(gè)性化的名字了,在微信、QQ中輕松秀一把。

...更多>>
RE管理器版本大全
(7)RE管理器版本大全

喜歡搗鼓手機(jī)的軟件對(duì)re管理器應(yīng)該不會(huì)陌生,它的全稱Root Explorer,是一款可以幫助用戶獲得手機(jī)最高權(quán)限的文件管理工具,root后就能對(duì)權(quán)限文件進(jìn)行操作,支持新建文件夾,編輯文件和安裝等功能,還有zip、ara文件解壓的功能。

...更多>>
  • RE管理器Root Explorer4.2 修改版

    01-19 / 4.2M

    推薦理由:RE管理器RootExplorer,最強(qiáng)大的ROOT權(quán)限文件管理利器,軟件支持簡(jiǎn)體中文,并且具備普通文件管理器所有功能
  • RE管理器免root版4.1.3 去廣告安卓

    05-24 / 3.8M

    推薦理由:RE管理器app是由SpeedSoftware研發(fā)的一款手機(jī)文件管理軟件,可以把用戶的所有文件圖片縮略圖,APK二進(jìn)制XML
  • RE管理器漢化版apk4.3.0 安卓免費(fèi)版

    03-21 / 2.8M

    推薦理由:RE文件管理器是一款實(shí)用的文件管理器,功能全面。使用該軟件能夠快速找到音樂、圖片、安裝包、文檔、壓縮包
  • re管理器舊版4.0.2去廣告版安卓中文

    09-10 / 3.0M

    推薦理由:安卓手機(jī)上的文件管理神器——re管理器,它有著非常高的權(quán)限管理功能,不過手機(jī)用戶需要獲取root權(quán)限,小編
  • qq悄悄話破解re管理器下載1.0安卓最

    06-18 / 1.3M

    推薦理由:QQ悄悄話是騰訊qq推出的一個(gè)匿名發(fā)送信息的功能,自從有了這個(gè)功能,感覺整個(gè)人都不好了,要是以后聊天都變
  • RE管理器3.3.4 漢化版

    03-29 / 2.4M

    推薦理由:R.E.管理器是由Speed Software開發(fā)的一款A(yù)ndroid平臺(tái)高權(quán)限文件管理器,獲取ROOT權(quán)限后可對(duì)系統(tǒng)文件進(jìn)行操作

擴(kuò)展知識(shí)

相關(guān)評(píng)論

閱讀本文后您有什么感想? 已有 人給出評(píng)價(jià)!

  • 2791 喜歡喜歡
  • 2101 頂
  • 800 難過難過
  • 1219 囧
  • 4049 圍觀圍觀
  • 5602 無聊無聊
熱門評(píng)論
最新評(píng)論
發(fā)表評(píng)論 查看所有評(píng)論(0)
昵稱:
表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)