参考链接:

一、 基本概念和注意点

1.1  首先需要了解一点:在Android中可以动态加载,但无法像Java中那样方便动态加载jar

原因:Android的虚拟机(Dalvik VM)是不认识Java打出jar的byte code,需要通过dx工具来优化转换成Dalvik byte code才行。这一点在咱们Android项目打包的apk中可以看出:引入其他Jar的内容都被打包进了classes.dex。

所以这条路不通,请大家注意。

1.2  当前哪些API可用于动态加载

1.2.1  DexClassLoader

这个可以加载jar/apk/dex,也可以从SD卡中加载,也是本文的重点。

1.2.3  PathClassLoader

只能加载已经安装到Android系统中的apk文件。

二、 准备

本文主要参考"四、参考文章"中第一篇文章,补充细节和实践过程。

2.1  下载开源项目

将项目导入工程,工程报错的话应该是少了gen文件夹,手动添加即可。注意这个例子是从网上下载优化好的jar(已经优化成dex然后再打包成的jar)到本地文件系统,然后再从本地文件系统加载并调用的。本文则直接改成从SD卡加载。

三、实践

3.1  编写接口和实现

3.1.1  接口IDynamic

package com.dynamic;

public interface IDynamic {

public String helloWorld();

}

3.1.2  实现类DynamicTest

package com.dynamic;

public class DynamicTest implements IDynamic {

@Override

public String helloWorld() {

return "Hello World!";

}

}

3.2  打包并转成dex

3.2.1  选中工程,常规流程导出即可,如图:

注意:在实践中发现,自己新建一个Java工程然后导出jar是无法使用的,这一点大家可以根据文章一来了解相关原因,也是本文的重点之一。这里打包导出为dynamic.jar

(后期修复:打包请不要把接口文件打进来,参见文章末尾后续维护!)

3.2.2  将打包好的jar拷贝到SDK安装目录android-sdk-windows\platform-tools下,DOS进入这个目录,执行命名:

dx --dex --output=test.jar dynamic.jar

3.3  修改调用例子

修改MainActivity,如下:

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mToastButton = (Button) findViewById(R.id.toast_button);

// Before the secondary dex file can be processed by the DexClassLoader,

// it has to be first copied from asset resource to a storage location.

//        final File dexInternalStoragePath = new File(getDir("dex", Context.MODE_PRIVATE),SECONDARY_DEX_NAME);

//        if (!dexInternalStoragePath.exists()) {

//            mProgressDialog = ProgressDialog.show(this,

//                    getResources().getString(R.string.diag_title),

//                    getResources().getString(R.string.diag_message), true, false);

//            // Perform the file copying in an AsyncTask.

//            // 从网络下载需要的dex文件

//            (new PrepareDexTask()).execute(dexInternalStoragePath);

//        } else {

//            mToastButton.setEnabled(true);

//        }

mToastButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

// Internal storage where the DexClassLoader writes the optimized dex file to.

//final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);

final File optimizedDexOutputPath = new File(Environment.getExternalStorageDirectory().toString()

+ File.separator + "test.jar");

// Initialize the class loader with the secondary dex file.

//                DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),

//                        optimizedDexOutputPath.getAbsolutePath(),

//                        null,

//                        getClassLoader());

DexClassLoader cl = new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(),

Environment.getExternalStorageDirectory().toString(), null, getClassLoader());

Class libProviderClazz = null;

try {

// Load the library class from the class loader.

// 载入从网络上下载的类

//                    libProviderClazz = cl.loadClass("com.example.dex.lib.LibraryProvider");

libProviderClazz = cl.loadClass("com.dynamic.DynamicTest");

//LibraryInterface lib = (LibraryInterface) libProviderClazz.newInstance();

IDynamic lib = (IDynamic)libProviderClazz.newInstance();

// Display the toast!

//lib.showAwesomeToast(view.getContext(), "hello 世界!");

Toast.makeText(MainActivity.this, lib.helloWorld(), Toast.LENGTH_SHORT).show();

} catch (Exception exception) {

// Handle exception gracefully here.

exception.printStackTrace();

}

}

});

}

Android动态替换dex,Android DexClassLoader动态加载与插件化开发相关推荐

  1. 动态加载、插件化、热部署、热修复(更新)知识汇总

    开发中经常能听到动态加载,插件化,热部署等词,动态加载到底是何方神物,它能实现什么功能,实现原理又如何?动态加载和插件化.热部署又有着什么样的联系呢?下面我们一起来学习吧. 1. 基本知识 1.1 动 ...

  2. Android插件化开发之动态加载的类型

    https://segmentfault.com/a/1190000005113493 基本信息 Author:kaedea GitHub:android-dynamical-loading 现在网络 ...

  3. Android插件化开发之动态加载基础之ClassLoader工作机制

    类加载器ClassLoader 早期使用过Eclipse等Java编写的软件的同学可能比较熟悉,Eclipse可以加载许多第三方的插件(或者叫扩展),这就是动态加载.这些插件大多是一些Jar包,而使用 ...

  4. Android插件化开发之动态加载技术系列索引

    动态加载介绍 在Android开发中采用动态加载技术,可以达到不安装新的APK就升级APP功能的目的,可以用来到达快速发版的目的,也可以用来修复一些紧急BUG. 现在使用得比较广泛的动态加载技术的核心 ...

  5. Android插件化开发之动态加载三个关键问题详解

    本文摘选自任玉刚著<Android开发艺术探索>,介绍了Android插件化技术的原理和三个关键问题,并给出了作者自己发起的开源插件化框架. 动态加载技术(也叫插件化技术)在技术驱动型的公 ...

  6. Android插件化开发基础之App如何动态加载类

    在 Java 里面,我们可以把一些类放到 .jar 文件里面,然后用 ClassLoader 动态加载.例如: URLClassLoader ucl = URLClassLoader.newInsta ...

  7. Android插件化开发之动态加载技术简单易懂的介绍方式

    转载地方:https://segmentfault.com/a/1190000004062866 基本信息 Author:kaedea GitHub:android-dynamical-loading ...

  8. Android动态加载APK插件类

    前言 插件化开发目前是非常热门的Android技术,它主要通过将不同的业务对象封装到插件中,这样不同的业务可以独立开发和调试,提高项目的开发效率.APK文件就是常见的插件文件格式,它包含了Androi ...

  9. Android插件化开发之动态加载本地皮肤包进行换肤

    Android插件化开发之动态加载本地皮肤包进行换肤 前言: 本文主要讲解如何用开源换肤框架 android-skin-loader-lib来实现加载本地皮肤包文件进行换肤,具体可自行参考框架原理进行 ...

最新文章

  1. Python 核心设计理念27个问题及解答
  2. mysql 自动补齐 表名,列名 方法, 重启mysql方法
  3. vue.js bootstrap 下拉列表_陕西省百度下拉总代理
  4. 学python买什么书-书单狗 篇一:小白学Python,到底要看多少书?
  5. My Calendar I
  6. 【NLP】统计自然语言处理(第2版)思维导图
  7. vba正则表达式入门
  8. 把所有数据库厂商拉在一起,会发生什么?
  9. 梅科尔工作室-OpenEuler培训第二讲笔记
  10. android 根据宽度调整字体大小,android 字体大小 根据分辨率 自动调整
  11. Worthington 分子生物学解读
  12. 地球人口承载力估计【小学奥数7653】
  13. 《控制论导论》读书:变异度-度量变异度
  14. TFT-LCD LVGL与硬件交互
  15. JavaScript-2:初体验JS
  16. android 局部tab页,安卓TabLayout+ViewPager实现切页
  17. 信息系统项目管理知识--项目立项管理
  18. XEChat-plugins安装教程------idea插件(游戏)
  19. 计算机存储和进制转换
  20. Junction.exe 命令应用详解

热门文章

  1. jsp的session介绍 (转)
  2. Concurrency 学习 (Mac iphone)
  3. 如何解决企业邮件对国外的通信问题
  4. BCH未来发展的支柱是什么
  5. Mesos各种存储处理方式
  6. CSS之 background-color: rgba(255,0,0,opacity number)
  7. Spring Boot干货系列:(六)静态资源和拦截器处理 | 掘金技术征文
  8. C#windows向窗体传递泛型类
  9. 利用单臂路由实现VLAN间路由
  10. RBL, UBL, Uboot的关系