尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38565345

近期由于项目太大了。导致编译通只是(Android对一个应用中的方法个数貌似有限制),所以一直琢磨着是否能将某些模块的APK不用安装,动态载入,通过在网上查找资料和网友的帮助,最终实现了APK的动态载入。网络上介绍APK动态载入的文章许多,可是我觉得写得很好的就是这位大牛的,我基本上就是使用他的这样的方案,然后增加了自己的元素。这位大牛是通过Activity实现的。我稍作改动。通过Fragment实现动态载入,我个人觉得使用Fragmnet更加简单。由于使用Fragment实现不须要考虑Fragment的生命周期。

文章地址:http://blog.csdn.net/singwhatiwanna/article/details/22597587
          http://blog.csdn.net/singwhatiwanna/article/details/23387079
一定要读了这两篇文章之后再来读我这篇,由于我是借鉴了这篇文章的思想的。

首先我们须要明确。实现动态载入就是要解决两个问题:(假设使用Fragments实现,则是一个问题)

1、Activity生命周期的管理。

2、动态载入的apk的资源怎样获取。

第一个问题是由于在java中不论什么一个程序要执行起来,必须通过类载入器将某个类增加内存,当我们通过一个类载入器将Activity增加内存时,事实上这个Activity就是一个普通的类。它已经没有生命周期的概念了,在Android系统中,Activity的生命周期是通过ActivityManager来控制的,假设我们通过动态载入的方式载入这个Activity,那么ActivityManager根本就不知道这个Activity的存在。所以我们必须处理好这个Activity的生命周期。至于第二个问题,在Android中。我们获取资源都是通过Context拿到的。而动态载入的APK是没有Context的。所以我们不能和曾经一样那样来拿。

前面的两篇文章推荐的方法已经能够很好的解决以上两个问题,因此实现了APK的动态载入。
我先来描写叙述一下大牛博客中实现动态载入的思路吧:
创建一个ProxyActivity,通过名字知道。它就是一个代理Activity,我们调用不论什么一个Activity都是通过调用ProxyActivity实现的,我仅仅须要传入动态载入apk的路径和须要动态载入的类名,比方载入了一个Activity之后。通过反射机制读取到Activity的全部的生命周期函数以及onActivityResult等函数,并保存在一个列表中。在ProxyActivity的onCreate中通过反射调用动态载入的Activity的onCreate,由于ProxyActivity是一个正常的Activity,它的生命周期是正常的,所以在ProxyActivity的生命周期函数中调用动态载入Activity的生命周期函数就ok了,从而实现动态载入的Activity也有生命周期了。

同一时候尽然是代理。那么就代理彻底一点。就干脆把动态载入的Activity中的全部的逻辑都转入到ProxyActivity中。

那么这就要求被载入的Activity有一个ProxyActivity的引用,这个能够让全部动态载入的Activity继承一个BaseActivity,这个BaseActivity中有一个setProxy方法。用来设置ProxyActivity。所以不是不论什么APK。都能够动态载入的。一般仅仅有动态载入自己编写的apk,动态载入别人的apk不太现实。

看了上面的思路,是不是有点借腹生子的感觉,事实上就是把动态载入的Activity的逻辑转移到了ProxyActivity

解决资源訪问的问题方法就是造ProxyActivity中重载者两个函数
public abstract AssetManager getAssets();
public abstract Resources getResources();
至于为什么能解决资源的问题,我还是推荐几篇文章大家去学习一下吧:
本人的另外一篇文章:http://blog.csdn.net/yuanzeyao/article/details/12955459
解说Android资源载入机制的一篇文章:http://blog.csdn.net/singwhatiwanna/article/details/24532419
 
好了,上面就是通过Activity实现的动态载入apk,以下看看我是怎么通过Fragment来实现动态载入的,假设熟悉Fragment的同学们应该知道。Fragment就相当于一个有生命周期的View,它的生命周期被所在的Activity的生命周期管理。即使我们通过类载入器把一个Fragment增加到内存,它和曾经我们使用的Fragment没有什么两样。仅仅要我们将这个Fragment增加到ProxyActivity,ProxyActivity就会自己主动的管理好这个Fragment的生命周期。

所以我们就不须要操心Fragment的生命周期,以下就来看看代码实现吧:

1、BaseFragment.java

public class BaseFragment extends Fragment implements IConstant
{private static final String TAG = "BaseFragment";protected String mDexPath;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);Bundle bundle=this.getArguments();//动态载入apk的路径mDexPath=bundle.getString(DEX_PATH);}//在Fragment中启动另外一个Fragmentprotected void replaceFragmentByProxy(String name){if(mDexPath==null)return;//PROXY_VIEW_ACTION 是ProxyActivity的actionIntent intent=new Intent(PROXY_VIEW_ACTION);//传递apk路径intent.putExtra(DEX_PATH, mDexPath);//是启动Fragment还是启动Fragment,这里启动的是Fragmentintent.putExtra(START_TYPE, TYPE_FRAGMENT);//须要载入的fragment的类名intent.putExtra(CLASS_NAME, name);this.startActivity(intent);}
}

全部须要动态载入的Fragment都须要继承这个BaseFragment,每次启动一个Fragment,仅仅须要传递apk的路径就可以。
以下是我写的一个MyFragment,用来使用BitmapFun载入网络图片的,这里仅仅是载入并显示图片。没有考虑其它的。假设想深入了解BitmapFun的使用,请看我的另外一篇文章:
http://blog.csdn.net/yuanzeyao/article/details/38355719

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;@Overridepublic 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 asynchronouslymImageFetcher = new ImageFetcher(getActivity(), 200);mImageFetcher.setLoadingImage(R.drawable.empty_photo);mImageFetcher.addImageCache(getActivity().getSupportFragmentManager(), cacheParams);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){//这里事实上能够直接使用R.layout.fragmentResources mResources=this.getActivity().getResources();return inflater.inflate(mResources.getIdentifier("fragment", "layout", "com.dl.client"), container,false);}@Overridepublic 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(){@Overridepublic void onClick(View arg0){//在Fragment中动态载入另外一个FragmentreplaceFragmentByProxy("com.dl.client.TempFragment");}});context=this.getActivity();mGridView.setAdapter(new BaseAdapter(){@Overridepublic 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;}@Overridepublic long getItemId(int arg0){return 0;}@Overridepublic Object getItem(int arg0){return Images.imageThumbUrls[arg0];}@Overridepublic int getCount(){return Images.imageThumbUrls.length;}});}
}

以下看看这个应用的效果吧:

最后须要注意的一点就是动态载入的apk不能和宿主应用包括同样的jar包,不然会报错的。。

转载于:https://www.cnblogs.com/zfyouxi/p/5260799.html

实现Android 动态载入APK(Fragment or Activity实现)相关推荐

  1. 深入浅出Android动态载入jar包技术

    在实际项目中.因为某些业务频繁变更而导致频繁升级client的弊病会造成较差的用户体验,而这也恰是Web App的优势,于是便衍生了一种思路.将核心的易于变更的业务封装在jar包里然后通过网络下载下来 ...

  2. android 动态生成fragment,Android动态加载fragment(fragment复用)

    [实例简介] Android动态加载fragment(fragment复用) [实例截图] [核心代码] fm_reuse └── fm_reuse ├── AndroidManifest.xml ├ ...

  3. Android动态加载进阶 代理Activity模式

    基本信息 作者:kaedea 项目:android-dynamical-loading 技术背景 简单模式中,使用ClassLoader加载外部的Dex或Apk文件,可以加载一些本地APP不存在的类, ...

  4. Android开发之旅-Fragment和Activity之间onCreateOptionsMenu的联系

    Fragment和Activity一样,可以重写onCreateOptionsMenu方法来设定自己的菜单,其实这两个地方使用onCreateOptionsMenu的目的和效果都是完全一样的,但是由于 ...

  5. android 动态调用apk,通过反射动态加载未安装apk

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 不知道哪里出了问题,折腾了好几天了 logcat显示 I load plugin class com.plugin.PluginMain W dalvik ...

  6. android t跳转到fragment,Android 使用EventBus进行Fragment和Activity通信

    本文介绍EventBus的基本使用,以及用于Fragment和Activity之间通信. github地址: https://github.com/greenrobot/EventBus 版本是 Ev ...

  7. Android开发之在Fragment和Activity页面拍照需要注意的地方

    先贴出Google官方文档:Google官方拍照文档 感觉讲的不是很细,有不少坑. 先看需要配置权限和provider <!--拍照存储权限--><uses-permissionan ...

  8. Android动态加载技术

    基本信息 Author:kaedea GitHub:android-dynamical-loading 我们很早开始就在Android项目中采用了动态加载技术,主要目的是为了达到让用户不用重新安装AP ...

  9. Android动态加载入门 简单加载模式

    基本信息 作者:kaedea 项目:android-dynamical-loading 初步了解Android动态加载 Java程序中,JVM虚拟机是通过类加载器ClassLoader加载.jar文件 ...

最新文章

  1. intent.putExtra()方法参数详解
  2. java日记(2)------定时任务quartz浅析
  3. PHP laravel 加模块,php – 如何在Laravel 5中构建模块化应用程序?
  4. 存在于实数域的微观粒子5-可分类性
  5. override覆盖
  6. 既生Flash,又何生EEPROM?
  7. LMSn没有运行在RT (real time) 模式Oracle 19c RAC?
  8. oracle 中某张表备份,张表系统流程(java程序备份及恢复SQL2000中数据库中的某张表)...
  9. 【java】swing编写窗体
  10. 客户和服务器之间响应的序列,Redis的请求/响应协议和往返时间详解
  11. ubuntu20.04 推荐翻译软件
  12. 质数/素数 - 合数
  13. 支持向量机(一)你确定不看吗
  14. 深度学习实战案例:新闻文本分类
  15. DSPE-PEG-cRGD,磷脂-聚乙二醇-环肽RGD,靶向穿膜肽RGD环肽供应
  16. 【论文阅读】Causality matters in medical imaging
  17. 《研磨设计模式》 与 《设计模式之禅》对比
  18. 区块链 | 区块链与物联网双剑合璧 这对CP如何改写未来?
  19. 解决studio 3T时间到期方法
  20. 各种数学平均数之间的关系

热门文章

  1. 第二届360杯全国大学生信息安全技术大赛部分解题思路(加密解密题)
  2. 深入入门正则表达式(java) - 1 - 入门基础
  3. 动态生成ContextMenuStrip
  4. DevExpress小结(简略)
  5. 这周的工作任务,编写sql存储过程
  6. [导入]8.3赛车频道活动
  7. 手机忽然就安装不了东西,就是下载好apk打开后按不了安装。怎么处理?
  8. 将房子卖了五百万,存在银行,靠利息能过日子吗?
  9. 为什么工厂招人越来越不容易?是招工难还是待遇低?
  10. 穷人怎么慢慢打破阶层?做到这2点,活出最真实的样子,别表演!