Android 动态加载DEX

1). 新建项目并创建Dynamic接口
/**
 * 接口
 * Created by mazaiting on 2018/6/26.
 */

public interface Dynamic {
  String say();
}
2). 创建接口的实现类DynamicImpl
/**
 * 动态实现类
 * Created by mazaiting on 2018/6/26.
 */

public class DynamicImpl implements Dynamic {
  @Override
  public String say() {
    return "mazaiting";
  }
}
3). 编译

Build -> Make Project, 生成的文件位于


图1.png
4). Gradle任务创建

在app/build.gradle文件中追加

// 删除dynamic.jar包任务
task clearJar(type: Delete) {
    delete('libs/dynamic.jar')
}

// 打包任务
task makeJar(type: org.gradle.api.tasks.bundling.Jar) {
    // 指定生成jar名称
    baseName 'dynamic'
    // 打包文件的位置
    from('build\\intermediates\\classes\\debug\\com\\mazaiting\\dynamicjar\\')
    // 打包到jar后的目录结构
    into('com/mazaiting/dynamicjar/')
    // 去掉不需要打包的目录和文件
    exclude('text/','Dynamic.class','R.class','BuildConfig.class')
    // 去掉R$开头的文件
    exclude { it.name.startsWith('R$') }
}

makeJar.dependsOn(clearJar, build)
5). 在Terminal控制台运行
# 查看所有任务
gradlew tasks --all
# 执行任务
gradlew makeJar
6). 生成jar
图2.png
7). dex打包

将打包好的jar文件拷贝到android的安装目录中的\sdk\build-tools\26.0.1\目录下,使用dx --dex --output=dynamic_temp.jar dynamic.jar进行压缩
这条命令首先将dynamic.jar编译成dynamic.dex文件,然后再将dynamic.dex文件压缩成dynamic_temp.jar,当然也可以压缩成.zip格式或者直接编译成.apk文件都可以。

8). 将生成的dynamic_dex.jar文件导入Android工程的assets文件夹下,并删除Dynamic接口的实现包
图3.png
9). 使用
public class MainActivity extends AppCompatActivity {
  /**缓存文件夹*/
  private File mCacheDir;
  /**目标文件*/
  private String mInternalPath;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    copyFile();
    setContentView(R.layout.activity_main);
  }
  
  /**
   * 拷贝文件
   */
  private void copyFile() {
    // 获取缓存路径
    mCacheDir = FileUtil.getCacheDir(getApplicationContext());
    // 获取dex文件存储路径
    mInternalPath = mCacheDir.getAbsolutePath() + File.separator + "dynamic.jar";
    File file = new File(mInternalPath);
    // 判断文件是否存在
    if (!file.exists()) {
      try {
        // 创建新文件
        file.createNewFile();
        // 拷贝文件
        FileUtil.copyFiles(this, "dynamic_dex.jar", file);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  /**
   * 动态加载按钮,布局文件只有一个按钮
   */
  public void loadDex(View view) {
    loadDex();
  }
  
  /**
   * 动态加载
   */
  private void loadDex() {
    // 新建DexClassLoader
    // 第一个参数:dex压缩文件的路径
    // 第二个参数:dex解压缩后的文件路径
    // 第三个参数:C/C++依赖的本地库文件
    // 第四个参数:上一级的类加载器
    DexClassLoader dexClassLoader = new DexClassLoader(
            mInternalPath, mCacheDir.getAbsolutePath(), null, getClassLoader());
    try {
      // 加载的类名为jar文件中的完整类名
      Class clazz = dexClassLoader.loadClass("com.mazaiting.dynamicjar.impl.DynamicImpl");
      Dynamic dynamic = (Dynamic) clazz.newInstance();
      if (null != dynamic) {
        Toast.makeText(this, dynamic.say(), Toast.LENGTH_SHORT).show();
      }
    } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
      e.printStackTrace();
    }
  }
}
10). 运行项目
图4.png
代码下载
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,131评论 19 139
  • Dalvik 虚拟机和标准的java虚拟机加载机制的区别: Dalvik虚拟机如同其他Java虚拟机一样,在运行程...
    脏仙人阅读 10,705评论 1 10
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 180,258评论 25 708
  • 今天跟大家分享的是微商,如何利用新浪微博来加好友。 微博的高级搜索可以,精确的搜索关键词,时间,地区条件好,去搜索...
    平胸小公主阅读 556评论 0 0
  • 新小说第一章框架基本搭好,尚需时日润色打磨,方能成型。 第一部长篇,简单随意,如落花流水,畅快淋漓。 这部长篇,多...
    老麦Michael阅读 278评论 0 0

友情链接更多精彩内容