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, 生成的文件位于


3110861-5d2c0322e892e3fc.png
图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
3110861-762df26a2e103d2f.png
图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接口的实现包
3110861-13faf8ee64c6f005.png
图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). 运行项目
3110861-dc59e4fa6c75012a.png
图4.png
代码下载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值