{大半年没更新博客,一开始是忙坏了,后面没忙了发现自己不想写了,变懒惰,今天重新开始检讨自己,并且要坚持写博客这个习惯。一定要坚持下来分享自己的技术心德。}
今天我们就说讨论讨论,[动态加载:]顾名思义,就是让apk不需要升级就能更新的功能,也可以理解为”插件”,也可以叫插件式开发。
动态加载有几种比如说有加载apk的,加载dex的jar的等等,这里我们主要针对加载dex的jar这种形式。
动态图:
现在咱们说说如何实现这个功能呢。
1、其实呢就跟你项目里面集成了一个jar一个概念,只是这个jar不在项目里面了,而是在sdcard或者别的地方。这样就能完成需要升级的时候,去下载最新的jar并加载,从而达到不需要升级apk就能更新的功能。
2、这里我们主要项目为一个主体项目,一个jar项目。具体实现咱们在后面边看图边讲解。
3、jar项目打包出来的项目,需要由.class文件转成dex文件的jar,这里需要用到一个dx的工具,后面也会依次介绍,当然了网上也有下,我这里也会提供。废话不多说,咱们现在就进入高潮!!!
首先是启动类代码如下(这里呢所有触发都在点击事件里面,由于没设立服务器,我们暂时把需要动态加载的jar包放在assets文件夹里面,然后在拷贝进sdcard里面去,去加载sdcard里面的jar。拷贝成功之后就该去加载dex,并且启动里面的start方法。该方法后面会介绍干啥用):
package com.test.demo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import com.example.test.R;
/**
* create by wangyuwen at 2017/4/11.
*/
public class MainActivity extends Activity implements View.OnClickListener {
private Button btn_jar;
//sdcar里面存储dex
public static final String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dynamic_V1.jar";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_jar = (Button) findViewById(R.id.btn_jar);
btn_jar.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (view == btn_jar) {
// 加载第一个dex
File file = new File(filePath);
if (!file.exists()) {
AssetsCopySystemCard(this, "dynamic_V1.jar", filePath);
}
// 因为所有类都反射到同一个activity,所以需要把唯一的承载跳转activity的intent传进去
Intent intent = new Intent();
intent.setClassName(getPackageName(), "com.test.demo.IntentActivity");
// 加载动态dex里面的唯一通道,拿到dex里面的类对象,并且开始调用start方法
DynamicUtil.DynamicAc(this, null).ExecuteMethod("start", new Class[] { Intent.class }, new Object[] { intent });
}
}
/**
* 把Assets里面的文件拷贝到sdcard
*
* @return
*/
public static synchronized void AssetsCopySystemCard(Context context, String assets, String path) {
InputStream is = null;
FileOutputStream fos = null;
try {
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
is = context.getAssets().open(assets);
// 第二个参数是是否追加,false是覆盖,true是追加
fos = new FileOutputStream(file, false);
byte[] buffer = new byte[1024];
int byteCount = 0;
while ((byteCount = is.read(buffer)) != -1) {
// 循环从输入流读取 buffer字节
fos.write(buffer, 0, byteCount);// 将读取的输入流写入到输出流
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}