「Update」
1、修复皮肤包下载存储,使用md5存储; 2、修复重复加载皮肤包导致View设置了图片被还原的bug;
This commit is contained in:
@@ -58,4 +58,4 @@ MOGO_TELEMATIC_VERSION=1.4.7.42
|
||||
# v2x
|
||||
MOGO_V2X_VERSION=1.4.7.42
|
||||
# SKIN
|
||||
MOGO_SKIN_VERSION=1.4.7.49.3-debug
|
||||
MOGO_SKIN_VERSION=1.4.7.49.4-debug
|
||||
|
||||
@@ -11,21 +11,17 @@ public class Skin {
|
||||
* 文件校验md5值
|
||||
*/
|
||||
public String md5 = "";
|
||||
|
||||
/**
|
||||
* 下载地址
|
||||
*/
|
||||
public String url = "xxxx";
|
||||
public String url = "";
|
||||
|
||||
/**
|
||||
* 皮肤名
|
||||
*/
|
||||
public String name = "";
|
||||
|
||||
/**
|
||||
* 下载完成后缓存地址
|
||||
*/
|
||||
public String path = "";
|
||||
|
||||
public File file;
|
||||
|
||||
public Skin(String md5, String name, String url) {
|
||||
@@ -36,10 +32,33 @@ public class Skin {
|
||||
|
||||
public File getSkinFile(File theme) {
|
||||
if (null == file) {
|
||||
file = new File(theme, name);
|
||||
file = new File(theme, getSkinFileName());
|
||||
}
|
||||
path = file.getAbsolutePath();
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 下载完成后缓存地址
|
||||
*/
|
||||
public String getPathLocal() {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 获取皮肤包文件名称
|
||||
*/
|
||||
public String getSkinFileName() {
|
||||
return name + "_" + md5 + ".zip";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Skin{" +
|
||||
"md5='" + md5 + '\'' +
|
||||
", url='" + url + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", file=" + file +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,40 +81,52 @@ public class SkinManager extends Observable {
|
||||
//还原默认皮肤包
|
||||
SkinPreference.getInstance().setSkin("");
|
||||
SkinResources.getInstance().reset();
|
||||
|
||||
//应用皮肤包
|
||||
setChanged();
|
||||
//通知观察者
|
||||
notifyObservers();
|
||||
}
|
||||
// 加载指定目录下的皮肤
|
||||
else {
|
||||
try {
|
||||
//反射创建AssetManager 与 Resource
|
||||
AssetManager assetManager = AssetManager.class.newInstance();
|
||||
// 资源路径设置 目录或压缩包
|
||||
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
|
||||
addAssetPath.setAccessible(true);
|
||||
int result = (int) addAssetPath.invoke(assetManager, skinPath);
|
||||
if (result == 0) {
|
||||
Log.e(TAG, "加载皮肤APK失败:" + skinPath);
|
||||
// 判断是否已经加载同样皮肤,如果已经加载则不再重复加载,防止因为重复加载导致ImageView之类的设置了src、background的控件被重制
|
||||
if (!SkinPreference.getInstance().getSkin().equals(skinPath)) {
|
||||
try {
|
||||
//反射创建AssetManager 与 Resource
|
||||
AssetManager assetManager = AssetManager.class.newInstance();
|
||||
// 资源路径设置 目录或压缩包
|
||||
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
|
||||
addAssetPath.setAccessible(true);
|
||||
int result = (int) addAssetPath.invoke(assetManager, skinPath);
|
||||
if (result == 0) {
|
||||
Log.e(TAG, "加载皮肤APK失败:" + skinPath);
|
||||
}
|
||||
|
||||
// 获取当前Resources
|
||||
Resources resources = application.getResources();
|
||||
//根据当前的设备显示器信息 与 配置(横竖屏、语言等) 创建Resources
|
||||
Resources skinResource = new Resources(assetManager, resources.getDisplayMetrics(), resources.getConfiguration());
|
||||
// 获取外部Apk(皮肤包) 包名
|
||||
PackageManager mPm = application.getPackageManager();
|
||||
PackageInfo info = mPm.getPackageArchiveInfo(skinPath, PackageManager.GET_ACTIVITIES);
|
||||
String packageName = info.packageName;
|
||||
|
||||
SkinResources.getInstance().applySkin(skinResource, packageName);
|
||||
|
||||
//保存当前使用的皮肤包
|
||||
SkinPreference.getInstance().setSkin(skinPath);
|
||||
|
||||
//应用皮肤包
|
||||
setChanged();
|
||||
//通知观察者
|
||||
notifyObservers();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 获取当前Resources
|
||||
Resources resources = application.getResources();
|
||||
//根据当前的设备显示器信息 与 配置(横竖屏、语言等) 创建Resources
|
||||
Resources skinResource = new Resources(assetManager, resources.getDisplayMetrics(), resources.getConfiguration());
|
||||
// 获取外部Apk(皮肤包) 包名
|
||||
PackageManager mPm = application.getPackageManager();
|
||||
PackageInfo info = mPm.getPackageArchiveInfo(skinPath, PackageManager.GET_ACTIVITIES);
|
||||
String packageName = info.packageName;
|
||||
SkinResources.getInstance().applySkin(skinResource, packageName);
|
||||
|
||||
//保存当前使用的皮肤包
|
||||
SkinPreference.getInstance().setSkin(skinPath);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
Log.e(TAG, "皮肤已存在,开始换肤……");
|
||||
}
|
||||
}
|
||||
//应用皮肤包
|
||||
setChanged();
|
||||
//通知观察者
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public void updateSkin(Activity activity) {
|
||||
@@ -135,70 +147,71 @@ public class SkinManager extends Observable {
|
||||
File skinFile = skin.getSkinFile(theme);
|
||||
// 判断是否存在
|
||||
if (skinFile.exists()) {
|
||||
Log.e("SkinActivity", "皮肤已存在,开始换肤……");
|
||||
SkinManager.getInstance().loadSkin(skin.path);
|
||||
Log.e(TAG, "皮肤已存在,开始换肤……skin=" + skin);
|
||||
SkinManager.getInstance().loadSkin(skin.getPathLocal());
|
||||
return;
|
||||
}
|
||||
Log.e("SkinActivity", "皮肤不存在,开始下载……");
|
||||
Log.e(TAG, "皮肤不存在,开始下载……skin=" + skin);
|
||||
DownloadManager manager = getDownloadManager(skin, theme);
|
||||
// 启动文件下载
|
||||
manager.startDownload();
|
||||
|
||||
}
|
||||
|
||||
private static DownloadManager getDownloadManager(Skin skin, File theme) {
|
||||
private static DownloadManager getDownloadManager(Skin skin, File themeDirectory) {
|
||||
DownloadManager.DownloadListener downloadListener = new DownloadManager.DownloadListener() {
|
||||
@Override
|
||||
public void onProgressUpdate(int progress) {
|
||||
// 更新UI或日志
|
||||
Log.d("DownloadManager", "onProgressUpdate progress = " + progress);
|
||||
Log.d(TAG, "DownloadManager onProgressUpdate progress = " + progress);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadSuccess() {
|
||||
// 下载成功后的处理
|
||||
Log.d("DownloadManager", "onDownloadSuccess");
|
||||
File skinFile = skin.getSkinFile(theme);
|
||||
Log.d(TAG, "DownloadManager onDownloadSuccess");
|
||||
File skinFile = skin.getSkinFile(themeDirectory);
|
||||
try {
|
||||
//下载成功,将皮肤包信息insert已下载数据库
|
||||
Log.e("SkinActivity", "皮肤包下载完成开始校验");
|
||||
Log.e(TAG, "DownloadManager 皮肤包下载完成开始校验");
|
||||
//皮肤包的md5校验 防止下载文件损坏(但是会减慢速度。从数据库查询已下载皮肤表数据库中保留md5字段)
|
||||
if (TextUtils.equals(SkinUtils.getSkinMD5(skinFile), skin.md5)) {
|
||||
Log.d("SkinActivity", "校验成功,修改文件名。");
|
||||
Log.d(TAG, "DownloadManager 校验成功,修改文件名。");
|
||||
// 校验文件签名没问题后删除其他主题
|
||||
deleteFilesExcept(theme, skin.file.getName());
|
||||
deleteFilesExcept(themeDirectory, skin.getSkinFileName());
|
||||
} else {
|
||||
Log.e("SkinActivity", "皮肤文件校验出错,本地文件MD5 与云端文件MD5 不一致。");
|
||||
Log.e(TAG, "DownloadManager 皮肤文件校验出错,本地文件MD5 与云端文件MD5 不一致。");
|
||||
Toast.makeText(mApplication, "皮肤文件校验出错,本地文件MD5 与云端文件MD5 不一致。", Toast.LENGTH_SHORT).show();
|
||||
// TODO 删除本地皮肤文件,并重新下载(这个操作比较危险,需要严格保证配置文件中的md5与实际皮肤包一致,否则将是灾难)
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SkinManager.getInstance().loadSkin(skin.path);
|
||||
SkinManager.getInstance().loadSkin(skin.getPathLocal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFailed(Exception e) {
|
||||
// 下载失败后的处理
|
||||
Log.e("DownloadManager", "onDownloadFailed");
|
||||
Log.e(TAG, "DownloadManager onDownloadFailed");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAlreadyDownloading(String url) {
|
||||
// 处理重复下载的情况
|
||||
Log.w("DownloadManager", "onAlreadyDownloading url=" + url);
|
||||
Log.w(TAG, "DownloadManager onAlreadyDownloading url=" + url);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
return new DownloadManager(skin.url, theme, downloadListener);
|
||||
return new DownloadManager(skin.url, skin.getSkinFileName(), themeDirectory, downloadListener);
|
||||
}
|
||||
|
||||
public static void deleteFilesExcept(File directory, String fileNameToKeep) {
|
||||
if (directory == null || !directory.exists() || !directory.isDirectory()) {
|
||||
throw new IllegalArgumentException("Provided path is not a valid directory: " + directory);
|
||||
Log.e(TAG, "Provided path is not a valid directory: " + directory);
|
||||
}
|
||||
|
||||
// 获取目录下的所有文件和子目录
|
||||
@@ -208,9 +221,9 @@ public class SkinManager extends Observable {
|
||||
// 如果文件名不等于要保留的文件名,并且不是目录,则删除
|
||||
if (!file.getName().equals(fileNameToKeep) && !file.isDirectory()) {
|
||||
if (file.delete()) {
|
||||
System.out.println("Deleted: " + file.getAbsolutePath());
|
||||
Log.d(TAG, "Deleted file=" + file.getAbsolutePath());
|
||||
} else {
|
||||
System.err.println("Failed to delete: " + file.getAbsolutePath());
|
||||
Log.e(TAG, "Failed to delete file=" + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mogo.skin.net;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -22,16 +23,19 @@ public class DownloadManager {
|
||||
|
||||
public interface DownloadListener {
|
||||
void onProgressUpdate(int progress);
|
||||
|
||||
void onDownloadSuccess();
|
||||
|
||||
void onDownloadFailed(Exception e);
|
||||
|
||||
void onAlreadyDownloading(String url);
|
||||
}
|
||||
|
||||
public DownloadManager(String url, File directory, DownloadListener listener) {
|
||||
public DownloadManager(String url, String skinFileName, File directory, DownloadListener listener) {
|
||||
this.downloadUrl = url;
|
||||
this.outputDir = directory;
|
||||
this.listener = listener;
|
||||
this.outputFile = new File(outputDir, getFileNameFromUrl(url));
|
||||
this.outputFile = new File(outputDir, skinFileName);
|
||||
|
||||
// 确保输出目录存在
|
||||
if (!outputDir.exists()) {
|
||||
|
||||
Reference in New Issue
Block a user