From 0b69c9294a3576c711f693294ca0e6aac8095e1d Mon Sep 17 00:00:00 2001
From: fanhuitong <981964879@qq.com>
Date: Wed, 20 Jul 2022 15:22:37 +0800
Subject: [PATCH] =?UTF-8?q?version:3.2=20fix:=E4=BF=AE=E5=A4=8D=E5=85=A8?=
=?UTF-8?q?=E5=B1=80=E6=9B=B4=E6=96=B0=EF=BC=8C=E6=9B=B4=E6=8D=A2=E8=85=BE?=
=?UTF-8?q?=E8=AE=AF=E6=8E=A8=E9=80=81=20update:=E6=8E=A5=E5=8F=A3?=
=?UTF-8?q?=E7=BC=93=E5=AD=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/build.gradle | 15 +-
app/src/main/AndroidManifest.xml | 2 +-
.../uiui/appstore/activity/MainActivity.java | 4 +-
.../uiui/appstore/base/BaseApplication.java | 6 +
.../com/uiui/appstore/base/BasePresenter.java | 7 +
.../java/com/uiui/appstore/base/BaseView.java | 4 +
.../java/com/uiui/appstore/bean/BatchID.java | 28 ++
.../appstore/disklrucache/CacheHelper.java | 473 ++++++++++++++++++
.../com/uiui/appstore/disklrucache/Utils.java | 101 ++++
.../com/uiui/appstore/gson/GsonUtils.java | 144 ++++++
.../appstore/gson/IntegerDefault0Adapter.java | 35 ++
.../gson/NullStringToEmptyAdapterFactory.java | 45 ++
.../uiui/appstore/manager/ConnectManager.java | 134 +++++
.../uiui/appstore/manager/ConnectMode.java | 12 +
.../appstore/network/NetInterfaceManager.java | 210 ++++++--
.../appstore/network/api/GetBatchApi.java | 17 +
.../interceptor/RepeatRequestInterceptor.java | 108 ++++
.../uiui/appstore/receiver/BootReceiver.java | 4 +-
.../appstore/service/InitJpushServer.java | 100 ----
.../appstore/service/main/MainSContact.java | 15 +
.../appstore/service/main/MainSPresenter.java | 49 ++
.../appstore/service/main/MainService.java | 167 +++++++
.../uiui/appstore/tpush/MessageReceiver.java | 33 ++
.../java/com/uiui/appstore/utils/MD5Util.java | 112 +++++
.../com/uiui/appstore/utils/TimeUtils.java | 17 +
25 files changed, 1703 insertions(+), 139 deletions(-)
create mode 100644 app/src/main/java/com/uiui/appstore/base/BasePresenter.java
create mode 100644 app/src/main/java/com/uiui/appstore/base/BaseView.java
create mode 100644 app/src/main/java/com/uiui/appstore/bean/BatchID.java
create mode 100644 app/src/main/java/com/uiui/appstore/disklrucache/CacheHelper.java
create mode 100644 app/src/main/java/com/uiui/appstore/disklrucache/Utils.java
create mode 100644 app/src/main/java/com/uiui/appstore/gson/GsonUtils.java
create mode 100644 app/src/main/java/com/uiui/appstore/gson/IntegerDefault0Adapter.java
create mode 100644 app/src/main/java/com/uiui/appstore/gson/NullStringToEmptyAdapterFactory.java
create mode 100644 app/src/main/java/com/uiui/appstore/manager/ConnectManager.java
create mode 100644 app/src/main/java/com/uiui/appstore/manager/ConnectMode.java
create mode 100644 app/src/main/java/com/uiui/appstore/network/api/GetBatchApi.java
create mode 100644 app/src/main/java/com/uiui/appstore/network/interceptor/RepeatRequestInterceptor.java
delete mode 100644 app/src/main/java/com/uiui/appstore/service/InitJpushServer.java
create mode 100644 app/src/main/java/com/uiui/appstore/service/main/MainSContact.java
create mode 100644 app/src/main/java/com/uiui/appstore/service/main/MainSPresenter.java
create mode 100644 app/src/main/java/com/uiui/appstore/service/main/MainService.java
create mode 100644 app/src/main/java/com/uiui/appstore/utils/MD5Util.java
diff --git a/app/build.gradle b/app/build.gradle
index dac2a05..cd5d76c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -45,8 +45,8 @@ android {
productFlavors {
beta {
flavorDimensions "default"
- versionCode 22
- versionName "3.1"
+ versionCode 23
+ versionName "3.2"
}
official {
@@ -175,6 +175,8 @@ dependencies {
//glide
implementation 'com.github.bumptech.glide:glide:4.13.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
+ //磁盘缓存
+ implementation 'com.jakewharton:disklrucache:2.0.2'
//aria
implementation 'com.arialyy.aria:core:3.8.15'
annotationProcessor 'com.arialyy.aria:compiler:3.8.15'
@@ -190,12 +192,19 @@ dependencies {
//RxJava
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
-
+ //生命周期管理
+ implementation 'com.trello.rxlifecycle4:rxlifecycle:4.0.2'
+ implementation 'com.trello.rxlifecycle4:rxlifecycle-android:4.0.2'
+ implementation 'com.trello.rxlifecycle4:rxlifecycle-components:4.0.2'
+ implementation 'com.trello.rxlifecycle4:rxlifecycle-components-preference:4.0.2'
+ implementation 'com.trello.rxlifecycle4:rxlifecycle-android-lifecycle:4.0.2'
//google
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.google.zxing:core:3.5.0'
//fastjson
implementation 'com.alibaba:fastjson:1.2.83'
+ //MMKV
+ implementation 'com.tencent:mmkv-static:1.2.13'
//腾讯移动推送 TPNS
implementation 'com.tencent.tpns:tpns:1.3.2.0-release'
// //极光推送
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aba7557..51c06db 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -102,7 +102,7 @@
diff --git a/app/src/main/java/com/uiui/appstore/activity/MainActivity.java b/app/src/main/java/com/uiui/appstore/activity/MainActivity.java
index 583a072..4370338 100644
--- a/app/src/main/java/com/uiui/appstore/activity/MainActivity.java
+++ b/app/src/main/java/com/uiui/appstore/activity/MainActivity.java
@@ -29,7 +29,7 @@ import com.uiui.appstore.fragment.FeaturedFragment;
import com.uiui.appstore.fragment.ManageFragment;
import com.uiui.appstore.network.NetInterfaceManager;
import com.uiui.appstore.service.GuardService;
-import com.uiui.appstore.service.InitJpushServer;
+import com.uiui.appstore.service.main.MainService;
import com.uiui.appstore.service.MyDownloadService;
import com.uiui.appstore.service.StepService;
import com.uiui.appstore.utils.SPUtils;
@@ -66,7 +66,7 @@ public class MainActivity extends BaseActivity {
private void starService() {
startService(new Intent(this, GuardService.class));
startService(new Intent(this, StepService.class));
- startService(new Intent(this, InitJpushServer.class));
+ startService(new Intent(this, MainService.class));
startService(new Intent(this, MyDownloadService.class));
}
diff --git a/app/src/main/java/com/uiui/appstore/base/BaseApplication.java b/app/src/main/java/com/uiui/appstore/base/BaseApplication.java
index 0234512..2824e77 100644
--- a/app/src/main/java/com/uiui/appstore/base/BaseApplication.java
+++ b/app/src/main/java/com/uiui/appstore/base/BaseApplication.java
@@ -23,7 +23,9 @@ import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.tencent.android.tpush.XGIOperateCallback;
import com.tencent.android.tpush.XGPushConfig;
import com.tencent.android.tpush.XGPushManager;
+import com.tencent.mmkv.MMKV;
import com.uiui.appstore.R;
+import com.uiui.appstore.manager.ConnectManager;
import com.uiui.appstore.network.NetInterfaceManager;
import com.uiui.appstore.receiver.AppManagerReceiver;
import com.uiui.appstore.utils.JGYUtils;
@@ -75,9 +77,13 @@ public class BaseApplication extends Application {
public void onCreate() {
super.onCreate();
app = this;
+ String rootDir = MMKV.initialize(this);
+ Log.i(TAG, "mmkv root: " + rootDir);
+
tPushInit();
ToastUtil.init(this);
JGYUtils.init(this);
+ ConnectManager.init(this);
Aria.init(this);
Aria.get(this).getDownloadConfig().setMaxTaskNum(1);
Aria.get(this).getDownloadConfig().setConvertSpeed(true);
diff --git a/app/src/main/java/com/uiui/appstore/base/BasePresenter.java b/app/src/main/java/com/uiui/appstore/base/BasePresenter.java
new file mode 100644
index 0000000..54921c8
--- /dev/null
+++ b/app/src/main/java/com/uiui/appstore/base/BasePresenter.java
@@ -0,0 +1,7 @@
+package com.uiui.appstore.base;
+
+public interface BasePresenter {
+ void attachView(V view);
+
+ void detachView();
+}
diff --git a/app/src/main/java/com/uiui/appstore/base/BaseView.java b/app/src/main/java/com/uiui/appstore/base/BaseView.java
new file mode 100644
index 0000000..3238992
--- /dev/null
+++ b/app/src/main/java/com/uiui/appstore/base/BaseView.java
@@ -0,0 +1,4 @@
+package com.uiui.appstore.base;
+
+public interface BaseView {
+}
diff --git a/app/src/main/java/com/uiui/appstore/bean/BatchID.java b/app/src/main/java/com/uiui/appstore/bean/BatchID.java
new file mode 100644
index 0000000..2e7ac9b
--- /dev/null
+++ b/app/src/main/java/com/uiui/appstore/bean/BatchID.java
@@ -0,0 +1,28 @@
+package com.uiui.appstore.bean;
+
+import androidx.annotation.NonNull;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonParser;
+
+import java.io.Serializable;
+
+public class BatchID implements Serializable {
+ private static final long serialVersionUID = -2320968190625923242L;
+
+ String batch_id;
+
+ public String getBatch_id() {
+ return batch_id;
+ }
+
+ public void setBatch_id(String batch_id) {
+ this.batch_id = batch_id;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString();
+ }
+}
diff --git a/app/src/main/java/com/uiui/appstore/disklrucache/CacheHelper.java b/app/src/main/java/com/uiui/appstore/disklrucache/CacheHelper.java
new file mode 100644
index 0000000..0b83d99
--- /dev/null
+++ b/app/src/main/java/com/uiui/appstore/disklrucache/CacheHelper.java
@@ -0,0 +1,473 @@
+package com.uiui.appstore.disklrucache;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.Environment;
+import android.util.Log;
+
+import com.jakewharton.disklrucache.DiskLruCache;
+import com.tencent.mmkv.MMKV;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Serializable;
+
+/**
+ * 磁盘缓存帮助类
+ */
+public class CacheHelper {
+ private static final String TAG = "DiskLruCacheHelper";
+
+ private MMKV mMMKV = MMKV.defaultMMKV();
+
+ private static final String DIR_NAME = "diskCache";
+ private static final int MAX_COUNT = 1024 * 1024 * 1024;
+ private static final int DEFAULT_APP_VERSION = 1;
+
+ private DiskLruCache mDiskLruCache;
+
+ public CacheHelper(Context context) {
+ mDiskLruCache = generateCache(context, DIR_NAME, MAX_COUNT);
+ }
+
+ public CacheHelper(Context context, String dirName) {
+ mDiskLruCache = generateCache(context, dirName, MAX_COUNT);
+ }
+
+ public CacheHelper(Context context, String dirName, int maxCount) {
+ mDiskLruCache = generateCache(context, dirName, maxCount);
+ }
+
+ //custom cache dir
+ public CacheHelper(File dir) {
+ mDiskLruCache = generateCache(null, dir, MAX_COUNT);
+ }
+
+ public CacheHelper(Context context, File dir) {
+ mDiskLruCache = generateCache(context, dir, MAX_COUNT);
+ }
+
+ public CacheHelper(Context context, File dir, int maxCount) {
+ mDiskLruCache = generateCache(context, dir, maxCount);
+ }
+
+ private DiskLruCache generateCache(Context context, File dir, int maxCount) {
+ if (!dir.exists() || !dir.isDirectory()) {
+ throw new IllegalArgumentException(
+ dir + " is not a directory or does not exists. ");
+ }
+
+ int appVersion = context == null ? DEFAULT_APP_VERSION : Utils.getAppVersion(context);
+
+ DiskLruCache diskLruCache = null;
+ try {
+ diskLruCache = DiskLruCache.open(
+ dir,
+ appVersion,
+ DEFAULT_APP_VERSION,
+ maxCount);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return diskLruCache;
+ }
+
+ private DiskLruCache generateCache(Context context, String dirName, int maxCount) {
+ DiskLruCache diskLruCache = null;
+ try {
+ diskLruCache = DiskLruCache.open(
+ getDiskCacheDir(context, dirName),
+ Utils.getAppVersion(context),
+ DEFAULT_APP_VERSION,
+ maxCount);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return diskLruCache;
+ }
+
+ // =======================================
+ // ============== String 数据 读写 =============
+ // =======================================
+
+ public void put(String key, String value) {
+ Log.e(TAG, "put: key = " + key + " value = " + value);
+ mMMKV.encode(key, System.currentTimeMillis());
+ mMMKV.encode(key + "_mmkv", value);
+
+ DiskLruCache.Editor edit = null;
+ BufferedWriter bw = null;
+ try {
+ edit = editor(key);
+ if (edit == null) {
+ return;
+ }
+ OutputStream os = edit.newOutputStream(0);
+ bw = new BufferedWriter(new OutputStreamWriter(os));
+ bw.write(value);
+ edit.commit();//write CLEAN
+ } catch (IOException e) {
+ e.printStackTrace();
+ Log.e(TAG, "put: " + e.getMessage());
+ try {
+ //s
+ edit.abort();//write REMOVE
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ Log.e(TAG, "put: " + e1.getMessage());
+ }
+ } finally {
+ try {
+ if (bw != null) {
+ bw.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ Log.e(TAG, "put: " + e.getMessage());
+ }
+ }
+ }
+
+ public String getAsString(String key) {
+ Log.e(TAG, "getAsString: " + key);
+ InputStream inputStream = null;
+ try {
+ //write READ
+ inputStream = get(key);
+ if (inputStream == null) {
+ return mMMKV.decodeString(key + "_mmkv", null);
+ }
+ StringBuilder sb = new StringBuilder();
+ int len = 0;
+ byte[] buf = new byte[128];
+ while ((len = inputStream.read(buf)) != -1) {
+ sb.append(new String(buf, 0, len));
+ }
+ return sb.toString();
+ } catch (IOException e) {
+ e.printStackTrace();
+ Log.e(TAG, "getAsString: " + e.getMessage());
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ Log.e(TAG, "getAsString: " + e1.getMessage());
+ }
+ }
+ }
+ return null;
+ }
+
+
+ public void put(String key, JSONObject jsonObject) {
+ put(key, jsonObject.toString());
+ }
+
+ public JSONObject getAsJson(String key) {
+ String val = getAsString(key);
+ try {
+ if (val != null) {
+ return new JSONObject(val);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ // =======================================
+ // ============ JSONArray 数据 读写 =============
+ // =======================================
+
+ public void put(String key, JSONArray jsonArray) {
+ put(key, jsonArray.toString());
+ }
+
+ public JSONArray getAsJSONArray(String key) {
+ String JSONString = getAsString(key);
+ try {
+ JSONArray obj = new JSONArray(JSONString);
+ return obj;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ // =======================================
+ // ============== byte 数据 读写 =============
+ // =======================================
+
+ /**
+ * 保存 byte数据 到 缓存中
+ *
+ * @param key 保存的key
+ * @param value 保存的数据
+ */
+ public void put(String key, byte[] value) {
+ OutputStream out = null;
+ DiskLruCache.Editor editor = null;
+ try {
+ editor = editor(key);
+ if (editor == null) {
+ return;
+ }
+ out = editor.newOutputStream(0);
+ out.write(value);
+ out.flush();
+ editor.commit();//write CLEAN
+ } catch (Exception e) {
+ e.printStackTrace();
+ try {
+ editor.abort();//write REMOVE
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+
+ public byte[] getAsBytes(String key) {
+ byte[] res = null;
+ InputStream is = get(key);
+ if (is == null) {
+ return null;
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ byte[] buf = new byte[256];
+ int len = 0;
+ while ((len = is.read(buf)) != -1) {
+ baos.write(buf, 0, len);
+ }
+ res = baos.toByteArray();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return res;
+ }
+
+
+ // =======================================
+ // ============== 序列化 数据 读写 =============
+ // =======================================
+ public void put(String key, Serializable value) {
+ DiskLruCache.Editor editor = editor(key);
+ ObjectOutputStream oos = null;
+ if (editor == null) {
+ return;
+ }
+ try {
+ OutputStream os = editor.newOutputStream(0);
+ oos = new ObjectOutputStream(os);
+ oos.writeObject(value);
+ oos.flush();
+ editor.commit();
+ } catch (IOException e) {
+ e.printStackTrace();
+ try {
+ editor.abort();
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ } finally {
+ try {
+ if (oos != null) {
+ oos.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public T getAsSerializable(String key) {
+ T t = null;
+ InputStream is = get(key);
+ ObjectInputStream ois = null;
+ if (is == null) {
+ return null;
+ }
+ try {
+ ois = new ObjectInputStream(is);
+ t = (T) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (ois != null) {
+ ois.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return t;
+ }
+
+ // =======================================
+ // ============== bitmap 数据 读写 =============
+ // =======================================
+ public void put(String key, Bitmap bitmap) {
+ put(key, Utils.bitmap2Bytes(bitmap));
+ }
+
+ public Bitmap getAsBitmap(String key) {
+ byte[] bytes = getAsBytes(key);
+ if (bytes == null) {
+ return null;
+ }
+ return Utils.bytes2Bitmap(bytes);
+ }
+
+ // =======================================
+ // ============= drawable 数据 读写 =============
+ // =======================================
+ public void put(String key, Drawable value) {
+ put(key, Utils.drawable2Bitmap(value));
+ }
+
+ public Drawable getAsDrawable(String key) {
+ byte[] bytes = getAsBytes(key);
+ if (bytes == null) {
+ return null;
+ }
+ return Utils.bitmap2Drawable(Utils.bytes2Bitmap(bytes));
+ }
+
+ // =======================================
+ // ============= other methods =============
+ // =======================================
+ public boolean remove(String key) {
+ try {
+ key = Utils.hashKeyForDisk(key);
+ return mDiskLruCache.remove(key);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public void close() throws IOException {
+ mDiskLruCache.close();
+ }
+
+ public void delete() throws IOException {
+ mDiskLruCache.delete();
+ mMMKV.clearAll();
+ }
+
+ public void flush() throws IOException {
+ mDiskLruCache.flush();
+ }
+
+ public boolean isClosed() {
+ return mDiskLruCache.isClosed();
+ }
+
+ public long size() {
+ return mDiskLruCache.size();
+ }
+
+ public void setMaxSize(long maxSize) {
+ mDiskLruCache.setMaxSize(maxSize);
+ }
+
+ public File getDirectory() {
+ return mDiskLruCache.getDirectory();
+ }
+
+ public long getMaxSize() {
+ return mDiskLruCache.getMaxSize();
+ }
+
+
+ // =======================================
+ // ===遇到文件比较大的,可以直接通过流读写 =====
+ // =======================================
+ //basic editor
+ public DiskLruCache.Editor editor(String key) {
+ try {
+ key = Utils.hashKeyForDisk(key);
+ //wirte DIRTY
+ DiskLruCache.Editor edit = mDiskLruCache.edit(key);
+ //edit maybe null :the entry is editing
+ if (edit == null) {
+ Log.w(TAG, "the entry spcified key:" + key + " is editing by other . ");
+ }
+ return edit;
+ } catch (IOException e) {
+ e.printStackTrace();
+ Log.e(TAG, "editor: " + e.getMessage());
+ }
+
+ return null;
+ }
+
+
+ //basic get
+ public InputStream get(String key) {
+ try {
+ DiskLruCache.Snapshot snapshot = mDiskLruCache.get(Utils.hashKeyForDisk(key));
+ if (snapshot == null) //not find entry , or entry.readable = false
+ {
+ Log.e(TAG, "not find entry , or entry.readable = false");
+ return null;
+ }
+ //write READ
+ return snapshot.getInputStream(0);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ }
+
+
+ // =======================================
+ // ============== 序列化 数据 读写 =============
+ // =======================================
+
+ private File getDiskCacheDir(Context context, String uniqueName) {
+ String cachePath;
+ if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
+ || !Environment.isExternalStorageRemovable()) {
+ if (context.getExternalCacheDir() != null) {
+ cachePath = context.getExternalCacheDir().getPath();
+ } else if (context.getExternalFilesDir("cache") != null) {
+ cachePath = context.getExternalFilesDir("cache").getPath();
+ } else {
+ cachePath = context.getCacheDir().getPath();
+ }
+ } else {
+ cachePath = context.getCacheDir().getPath();
+ }
+ return new File(cachePath + File.separator + uniqueName);
+ }
+
+}
diff --git a/app/src/main/java/com/uiui/appstore/disklrucache/Utils.java b/app/src/main/java/com/uiui/appstore/disklrucache/Utils.java
new file mode 100644
index 0000000..da0171b
--- /dev/null
+++ b/app/src/main/java/com/uiui/appstore/disklrucache/Utils.java
@@ -0,0 +1,101 @@
+package com.uiui.appstore.disklrucache;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+
+import java.io.ByteArrayOutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class Utils {
+ public static int getAppVersion(Context context) {
+ try {
+ PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return info.versionCode;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return 1;
+ }
+
+
+ public static String hashKeyForDisk(String key) {
+ String cacheKey;
+ try {
+ final MessageDigest mDigest = MessageDigest.getInstance("MD5");
+ mDigest.update(key.getBytes());
+ cacheKey = bytesToHexString(mDigest.digest());
+ } catch (NoSuchAlgorithmException e) {
+ cacheKey = String.valueOf(key.hashCode());
+ }
+ return cacheKey;
+ }
+
+ public static String bytesToHexString(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < bytes.length; i++) {
+ String hex = Integer.toHexString(0xFF & bytes[i]);
+ if (hex.length() == 1) {
+ sb.append('0');
+ }
+ sb.append(hex);
+ }
+ return sb.toString();
+ }
+
+ public static byte[] bitmap2Bytes(Bitmap bm) {
+ if (bm == null) {
+ return null;
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
+ return baos.toByteArray();
+ }
+
+ public static Bitmap bytes2Bitmap(byte[] bytes) {
+ return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
+ }
+
+
+ /**
+ * Drawable → Bitmap
+ */
+ public static Bitmap drawable2Bitmap(Drawable drawable) {
+ if (drawable == null) {
+ return null;
+ }
+ // 取 drawable 的长宽
+ int w = drawable.getIntrinsicWidth();
+ int h = drawable.getIntrinsicHeight();
+ // 取 drawable 的颜色格式
+ Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
+ // 建立对应 bitmap
+ Bitmap bitmap = Bitmap.createBitmap(w, h, config);
+ // 建立对应 bitmap 的画布
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, w, h);
+ // 把 drawable 内容画到画布中
+ drawable.draw(canvas);
+ return bitmap;
+ }
+
+ /*
+ * Bitmap → Drawable
+ */
+ @SuppressWarnings("deprecation")
+ public static Drawable bitmap2Drawable(Bitmap bm) {
+ if (bm == null) {
+ return null;
+ }
+ BitmapDrawable bd = new BitmapDrawable(bm);
+ bd.setTargetDensity(bm.getDensity());
+ return new BitmapDrawable(bm);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/uiui/appstore/gson/GsonUtils.java b/app/src/main/java/com/uiui/appstore/gson/GsonUtils.java
new file mode 100644
index 0000000..f4fc637
--- /dev/null
+++ b/app/src/main/java/com/uiui/appstore/gson/GsonUtils.java
@@ -0,0 +1,144 @@
+package com.uiui.appstore.gson;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+
+public class GsonUtils {
+ //https://blog.csdn.net/zte1055889498/article/details/122400299
+
+ public static JsonObject getJsonObject(String jsonString) {
+ JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
+ return jsonObject;
+ }
+
+ private static final Gson gson;
+
+ static {
+ GsonBuilder builder = new GsonBuilder();
+ builder.registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory());
+ builder.registerTypeAdapter(Integer.class, new IntegerDefault0Adapter());
+ builder.registerTypeAdapter(int.class, new IntegerDefault0Adapter());
+ builder.disableHtmlEscaping();
+ builder.enableComplexMapKeySerialization();
+ // builder.excludeFieldsWithoutExposeAnnotation();
+ builder.setDateFormat("yyyy-MM-dd HH:mm:ss");
+ gson = builder.create();
+ }
+
+ public static Type makeJavaType(Type rawType, Type... typeArguments) {
+ return TypeToken.getParameterized(rawType, typeArguments).getType();
+ }
+
+ public static String toString(Object value) {
+ if (Objects.isNull(value)) {
+ return null;
+ }
+ if (value instanceof String) {
+ return (String) value;
+ }
+ return toJSONString(value);
+ }
+
+ public static String toJSONString(Object value) {
+ return gson.toJson(value);
+ }
+
+ public static String toPrettyString(Object value) {
+ return gson.newBuilder().setPrettyPrinting().create().toJson(value);
+ }
+
+ public static JsonElement fromJavaObject(Object value) {
+ JsonElement result = null;
+ if (Objects.nonNull(value) && (value instanceof String)) {
+ result = parseObject((String) value);
+ } else {
+ result = gson.toJsonTree(value);
+ }
+ return result;
+ }
+
+ public static JsonElement parseObject(String content) {
+ return JsonParser.parseString(content);
+ }
+
+ public static JsonElement getJsonElement(JsonObject node, String name) {
+ return node.get(name);
+ }
+
+ public static JsonElement getJsonElement(JsonArray node, int index) {
+ return node.get(index);
+ }
+
+ public static T toJavaObject(JsonElement node, Class clazz) {
+ return gson.fromJson(node, clazz);
+ }
+
+ public static T toJavaObject(JsonElement node, Type type) {
+ return gson.fromJson(node, type);
+ }
+
+ public static T toJavaObject(JsonElement node, TypeToken> typeToken) {
+ return toJavaObject(node, typeToken.getType());
+ }
+
+ public static List toJavaList(JsonElement node, Class clazz) {
+ return toJavaObject(node, makeJavaType(List.class, clazz));
+ }
+
+ public static List