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, 生成的文件位于
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
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接口的实现包
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();
}
}
}