Rxjava2.0 +Retrofit2.0 进行网络下载,下载后文件解压 文件内含需要更新的图片资源和文字资源json
public final class DownImpl {
private static volatile DownImpl downImpl = null;
private String mZipPath = Environment.getExternalStorageDirectory() + "/XXX/flush.zip";
private String mUnZipPath = Environment.getExternalStorageDirectory() + "/XXX";
private Observable call;
private Disposable parsingSubscribe;
public static DownImpl getInstance() {
if (downImpl == null) {
synchronized (DownImpl.class) {
if (downImpl == null) {
downImpl = new DownImpl();
}
}
}
return downImpl;
}
private interface DownService {
@Headers({"Accept:application/json"})
@Streaming
@GET
Observable downloadFileAsync(@Url String url);
}
@SuppressLint("CheckResult")
public void downloadFile(String url, final String path, final String name, final TasksDataSource.Callback2 callback) {
call = HttpBase.createService(DownService.class).downloadFileAsync(url);
call.flatMap(new Function>() {
@Override
public ObservableSource apply(ResponseBody responseBody) {
boolean writtenToDisk = writeResponseBodyToDisk(responseBody, path, name);
return Observable.just(writtenToDisk);
}
}).filter(new Predicate() {
@Override
public boolean test(Boolean aBoolean) {
if (aBoolean) {
return ZipUtil.Unzip(mZipPath, mUnZipPath);
}
return false;
}
}).onErrorReturn(new Function() {
@Override
public Boolean apply(Throwable throwable) throws Exception {
return false;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer() {
@Override
public void accept(Boolean o) {
if (o) {
callback.onSuccess("");
ParsingJsonString(callback);
} else {
callback.onFail("");
}
}
});
}
/**
* @param callback
*/
@SuppressLint("CheckResult")
private void ParsingJsonString(final TasksDataSource.Callback2 callback) {
parsingSubscribe = Observable.just(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Priseer/tabbarConfig.json").flatMap(new Function>() {
@Override
public ObservableSource apply(String s) {
BufferedSource bufferedSource = null;
try {
Source source = Okio.source(new File(s));
bufferedSource = Okio.buffer(source);
String json = bufferedSource.readUtf8();
Type type = new TypeToken() {
}.getType();
FlushDto flushDto = new Gson().fromJson(json, type);
return Observable.just(flushDto);
} catch (Exception e) {
e.printStackTrace();
return Observable.just(null);
} finally {
closeQuietly(bufferedSource);
}
}
}).onErrorReturn(new Function() {
@Override
public FlushDto apply(Throwable throwable) {
return null;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer() {
@Override
public void accept(FlushDto o) {
if (o != null) {
callback.onFinalSuccess(o);
}
}
});
}
/**
* 关闭流
*
* @param closeable
*/
public void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (RuntimeException rethrown) {
throw rethrown;
} catch (Exception ignored) {
}
}
}
/**
* @param body
* @param path
* @param name
* @return 文件写到i
*/
private boolean writeResponseBodyToDisk(ResponseBody body, String path, String name) {
try {
File outputPate = new File(path);
if (!outputPate.exists()) {
outputPate.mkdirs();
}
File output = new File(path, name);
if (output.exists()) {
output.delete();
}
BufferedSink sink = Okio.buffer(Okio.sink(output));
Buffer buffer = sink.buffer();
long total = 0;
long len;
int bufferSize = 200 * 1024; //200kb
BufferedSource source = body.source();
while ((len = source.read(buffer, bufferSize)) != -1) {
sink.emit();
total += len;
}
source.close();
sink.close();
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
解压工具类
public final class ZipUtil {
public static boolean Unzip(String zipFile, String targetDir) {
int BUFFER = 4096; //这里缓冲区我们使用4KB,
String strEntry; //保存每个zip的条目名称
try {
BufferedOutputStream dest = null; //缓冲输出流
FileInputStream fis = new FileInputStream(zipFile);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry; //每个zip条目的实例
while ((entry = zis.getNextEntry()) != null) {
try {
int count;
byte data[] = new byte[BUFFER];
strEntry = entry.getName();
File entryFile = new File(targetDir , strEntry);
File entryDir = new File(entryFile.getParent());
if (!entryDir.exists()) {
entryDir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(entryFile);
dest = new BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
zis.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
代码设置图片颜色select
// 构建颜色选择器
private ColorStateList flushColorSelector(int checkedColor, int uncheckedColor) {
return new ColorStateList(new int[][]{new int[]{android.R.attr.state_selected}, new int[]{-android.R.attr.state_selected}},
new int[]{checkedColor, uncheckedColor});
}
// 构建Drawable选择器
private StateListDrawable flushDrawableSelector(Drawable checked, Drawable unchecked) {
StateListDrawable stateList = new StateListDrawable();
int state_selected = android.R.attr.state_selected;
stateList.addState(new int[]{state_selected}, checked);
stateList.addState(new int[]{-state_selected}, unchecked);
return stateList;
}
private Drawable getDrawableFromPath(String path) {
return Drawable.createFromPath(path);
}
在下载和解压完成后
Drawable drawable = getResources().getDrawable(R.drawable.XXX);//原始图片获取适配的大小
final int minimumHeight = drawable.getMinimumHeight();
final int minimumWidth = drawable.getMinimumWidth();
StateListDrawable topSelector = flushDrawableSelector(getDrawableFromPath(check),
如果直接用topSelector.getMinimumHeight(); 获取出来的大小不准确很小 用替换之前的资源获取要建议的大小完美解决
getDrawableFromPath(unCheck));
topSelector.setBounds(0, 0, minimumWidth, minimumHeight);
mTextView.setCompoundDrawables(null, topSelector, null, null);