diff --git a/app/build.gradle b/app/build.gradle index 0fd2f40..425b939 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.uiui.aios" minSdkVersion 24 targetSdkVersion 29 - versionCode 12 - versionName "2.1" + versionCode 13 + versionName "2.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -155,6 +155,9 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + //磁盘缓存 + implementation 'com.jakewharton:disklrucache:2.0.2' //glide implementation 'com.github.bumptech.glide:glide:4.13.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.13.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7474fcd..306f043 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" package="com.uiui.aios" android:sharedUserId="android.uid.system"> + @@ -105,6 +106,7 @@ android:excludeFromRecents="true" android:theme="@style/activity_styles" /> + + - + android:theme="@android:style/Theme.Translucent.NoTitleBar"> + android:host="com.uiui.aios" + android:scheme="tpns" /> + @@ -234,7 +239,8 @@ android:process=":xg_vip_service"> - @@ -271,13 +277,14 @@ - - + + android:authorities="${applicationId}.XG_SETTINGS_PROVIDER" + android:exported="false" /> diff --git a/app/src/main/java/com/uiui/aios/bean/UserId.java b/app/src/main/java/com/uiui/aios/bean/UserId.java new file mode 100644 index 0000000..635cb91 --- /dev/null +++ b/app/src/main/java/com/uiui/aios/bean/UserId.java @@ -0,0 +1,17 @@ +package com.uiui.aios.bean; + +import java.io.Serializable; + +public class UserId implements Serializable { + + private static final long serialVersionUID = 8035934571639651952L; + int user_id; + + public int getUser_id() { + return user_id; + } + + public void setUser_id(int user_id) { + this.user_id = user_id; + } +} diff --git a/app/src/main/java/com/uiui/aios/disklrucache/CacheHelper.java b/app/src/main/java/com/uiui/aios/disklrucache/CacheHelper.java new file mode 100644 index 0000000..1591ce9 --- /dev/null +++ b/app/src/main/java/com/uiui/aios/disklrucache/CacheHelper.java @@ -0,0 +1,463 @@ +package com.uiui.aios.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.BuildConfig; +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 = CacheHelper.class.getSimpleName(); + + private MMKV mMMKV = MMKV.defaultMMKV(); + + private static final String DIR_NAME = "diskCache"; + private static final int MAX_COUNT = 5 * 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); + mMMKV.encode(key, System.currentTimeMillis()); + + 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(); + try { + //s + edit.abort();//write REMOVE + } catch (IOException e1) { + e1.printStackTrace(); + } + } finally { + try { + if (bw != null) { + bw.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public String getAsString(String key) { + Log.e(TAG, "getAsString: " + key); + InputStream inputStream = null; + try { + //write READ + inputStream = get(key); + if (inputStream == null) { + return 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)); + } + if (BuildConfig.DEBUG) { + Log.e(TAG, "getAsString: " + sb.toString()); + } + return sb.toString(); + } catch (IOException e) { + e.printStackTrace(); + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + 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(); + } + + 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(); + } + + 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()) { + cachePath = context.getExternalCacheDir().getPath(); + } else { + cachePath = context.getCacheDir().getPath(); + } + return new File(cachePath + File.separator + uniqueName); + } + +} diff --git a/app/src/main/java/com/uiui/aios/disklrucache/Utils.java b/app/src/main/java/com/uiui/aios/disklrucache/Utils.java new file mode 100644 index 0000000..59970d7 --- /dev/null +++ b/app/src/main/java/com/uiui/aios/disklrucache/Utils.java @@ -0,0 +1,101 @@ +package com.uiui.aios.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/aios/fragment/SecondFragment.java b/app/src/main/java/com/uiui/aios/fragment/SecondFragment.java index 8583375..6294512 100644 --- a/app/src/main/java/com/uiui/aios/fragment/SecondFragment.java +++ b/app/src/main/java/com/uiui/aios/fragment/SecondFragment.java @@ -257,21 +257,22 @@ public class SecondFragment extends BaseFragment { cl_activity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - openApp(); + openApp(0); } }); cl_demand.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - openApp(); + openApp(1); } }); } - private void openApp() { + private void openApp(int position) { Intent intent = new Intent(Intent.ACTION_MAIN); /*知道要跳转应用的包命与目标Activity*/ ComponentName componentName = new ComponentName("com.uiui.city", "com.uiui.city.activity.MainActivity"); + intent.putExtra("position", position); intent.setComponent(componentName); intent.putExtra("", "");//这里Intent传值 startActivity(intent); diff --git a/app/src/main/java/com/uiui/aios/network/NetInterfaceManager.java b/app/src/main/java/com/uiui/aios/network/NetInterfaceManager.java index 4da8f12..89c561a 100644 --- a/app/src/main/java/com/uiui/aios/network/NetInterfaceManager.java +++ b/app/src/main/java/com/uiui/aios/network/NetInterfaceManager.java @@ -4,6 +4,9 @@ import android.annotation.SuppressLint; import android.content.Context; import android.util.Log; +import com.tencent.mmkv.MMKV; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; import com.uiui.aios.bean.ActivityBean; import com.uiui.aios.bean.AlarmClockData; import com.uiui.aios.bean.ArticleInfo; @@ -11,12 +14,15 @@ import com.uiui.aios.bean.BaseResponse; import com.uiui.aios.bean.DemandBean; import com.uiui.aios.bean.GoodsInfo; import com.uiui.aios.bean.NetDesktopIcon; +import com.uiui.aios.bean.UserId; +import com.uiui.aios.disklrucache.CacheHelper; import com.uiui.aios.network.api.ActivityListApi; import com.uiui.aios.network.api.AlarmClockApi; import com.uiui.aios.network.api.AppUsageRecordApi; import com.uiui.aios.network.api.ArticleListApi; import com.uiui.aios.network.api.DemandListApi; import com.uiui.aios.network.api.GetDesktopApi; +import com.uiui.aios.network.api.GetUserIDApi; import com.uiui.aios.network.api.GoodsListApi; import com.uiui.aios.network.api.HealthCodeApi; import com.uiui.aios.network.api.RunNewApp; @@ -24,6 +30,8 @@ import com.uiui.aios.network.api.SOSRecordApi; import com.uiui.aios.network.api.SendScreenshotApi; import com.uiui.aios.network.api.UpdateAlarmClockApi; import com.uiui.aios.network.api.UpdateDesktopApi; +import com.uiui.aios.network.interceptor.RepeatRequestInterceptor; +import com.uiui.aios.utils.GsonUtils; import com.uiui.aios.utils.MD5Util; import com.uiui.aios.utils.Utils; @@ -36,8 +44,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.schedulers.Schedulers; +import io.reactivex.rxjava3.subjects.BehaviorSubject; import okhttp3.Cache; import okhttp3.Headers; import okhttp3.Interceptor; @@ -53,8 +65,12 @@ public class NetInterfaceManager { @SuppressLint("StaticFieldLeak") private static NetInterfaceManager INSTANCE; private Context mContext; + private CacheHelper mCacheHelper; + private Retrofit mRetrofit; private OkHttpClient okHttpClient; + private MMKV mMMKV = MMKV.defaultMMKV(); + private final ConcurrentHashMap requestIdsMap = new ConcurrentHashMap<>(); //超时时间 private static int timeOut = 30; @@ -66,39 +82,8 @@ public class NetInterfaceManager { private NetInterfaceManager(Context context) { this.mContext = context; + this.mCacheHelper = new CacheHelper(context); if (okHttpClient == null) { - Interceptor interceptor = new Interceptor() { - @NotNull - @Override - public Response intercept(@NotNull Chain chain) throws IOException { - Request request = chain.request(); - //相同的请求 - String requestKey = MD5Util.getUpperMD5Str(request.method() + request.url().toString()); - long time = System.currentTimeMillis();//请求时间 - try { - if (requestIdsMap.size() > 0 && requestIdsMap.containsKey(requestKey)) { - Log.e("REPEAT-REQUEST", "重复请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url()); - chain.call().cancel(); - return new Response.Builder() - .protocol(Protocol.get(CUSTOM_REPEAT_REQ_PROTOCOL)) - .request(request) //multi thread - .build(); - } - requestIdsMap.put(requestKey, time); - Log.e("REPEAT-REQUEST", "注册请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url()); -// Request.Builder builder = request.newBuilder(); -// builder.addHeader("header", jsonObject.toString()); - return chain.proceed(request); - } catch (IOException e) { - throw e; - } finally { - if (requestIdsMap.containsKey(requestKey) && requestIdsMap.containsValue(time)) {//请求任务完成删除map中的数据 - requestIdsMap.remove(requestKey); - Log.e("REPEAT-REQUEST", "移除请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url()); - } - } - } - }; //如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了 OkHttpClient.Builder builder = new OkHttpClient.Builder(); @@ -106,7 +91,7 @@ public class NetInterfaceManager { builder.writeTimeout(timeOut, TimeUnit.SECONDS);// 设置写入超时时间 builder.readTimeout(timeOut, TimeUnit.SECONDS);// 设置读取数据超时时间 builder.retryOnConnectionFailure(true);// 设置进行连接失败重试 - builder.addInterceptor(interceptor); + builder.addInterceptor(new RepeatRequestInterceptor()); // 设置缓存文件路径 String cacheDirectory = mContext.getExternalCacheDir().getAbsolutePath() + "/OkHttpCache"; @@ -224,16 +209,87 @@ public class NetInterfaceManager { .observeOn(AndroidSchedulers.mainThread()); } + public interface onCompleteCallback { + void onComplete(); + } + + public Observable> getUserIDObservable() { + return mRetrofit.create(GetUserIDApi.class) + .getUserID(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public void getUserID(BehaviorSubject lifecycle, onCompleteCallback callback) { + getUserIDObservable() + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(getUserIDObserver(callback)); + } + + public void getUserID(onCompleteCallback callback) { + getUserIDObservable() + .subscribe(getUserIDObserver(callback)); + } + + public void getUserID() { + getUserIDObservable() + .subscribe(getUserIDObserver(null)); + } + + public int getUserId() { + int userId = mMMKV.decodeInt("USER_ID", -1); + if (userId == -1) { + getUserID(); + } + return userId; + } + + public Observer getUserIDObserver(onCompleteCallback callback) { + return new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getUserID", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse userIdBaseResponse) { + Log.e("getUserID", "onNext: " + userIdBaseResponse); + if (userIdBaseResponse.code == 200) { + UserId userId = userIdBaseResponse.data; + mCacheHelper.put(URLAddress.GET_USER_ID, GsonUtils.toJsonString(userId)); + mMMKV.encode("USER_ID", userId.getUser_id()); + } else { + mCacheHelper.put(URLAddress.GET_USER_ID, -1); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getUserID", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getUserID", "onComplete: "); + if (callback != null) { + callback.onComplete(); + } + } + }; + } + + public Observable>> getActivityListObservable() { return mRetrofit.create(ActivityListApi.class) - .getActivityList(Utils.getSerial(), 1, 1) + .getActivityList(Utils.getSerial(), 1, 1,getUserId()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable>> getDemandListObservable() { return mRetrofit.create(DemandListApi.class) - .getDemandList(Utils.getSerial(), 1, 1) + .getDemandList(Utils.getSerial(), 1, 1,getUserId()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } diff --git a/app/src/main/java/com/uiui/aios/network/URLAddress.java b/app/src/main/java/com/uiui/aios/network/URLAddress.java index ee26e0a..21fb25d 100644 --- a/app/src/main/java/com/uiui/aios/network/URLAddress.java +++ b/app/src/main/java/com/uiui/aios/network/URLAddress.java @@ -33,4 +33,7 @@ public class URLAddress { /*获取健康吗*/ public static final String GET_HEALTH_CODE = "getHealthCode"; + + public static final String GET_USER_ID = "getUserId"; + } diff --git a/app/src/main/java/com/uiui/aios/network/api/ActivityListApi.java b/app/src/main/java/com/uiui/aios/network/api/ActivityListApi.java index 099d26d..29ac4df 100644 --- a/app/src/main/java/com/uiui/aios/network/api/ActivityListApi.java +++ b/app/src/main/java/com/uiui/aios/network/api/ActivityListApi.java @@ -15,6 +15,7 @@ public interface ActivityListApi { Observable>> getActivityList( @Query("sn") String sn, @Query("startSize") int startSize, - @Query("pageSize") int pageSize + @Query("pageSize") int pageSize, + @Query("user_id") int user_id ); } diff --git a/app/src/main/java/com/uiui/aios/network/api/DemandListApi.java b/app/src/main/java/com/uiui/aios/network/api/DemandListApi.java index 2e2b156..c65674f 100644 --- a/app/src/main/java/com/uiui/aios/network/api/DemandListApi.java +++ b/app/src/main/java/com/uiui/aios/network/api/DemandListApi.java @@ -15,6 +15,7 @@ public interface DemandListApi { Observable>> getDemandList( @Query("sn") String sn, @Query("startSize") int startSize, - @Query("pageSize") int pageSize + @Query("pageSize") int pageSize, + @Query("user_id") int user_id ); } diff --git a/app/src/main/java/com/uiui/aios/network/api/GetUserIDApi.java b/app/src/main/java/com/uiui/aios/network/api/GetUserIDApi.java new file mode 100644 index 0000000..cf8340c --- /dev/null +++ b/app/src/main/java/com/uiui/aios/network/api/GetUserIDApi.java @@ -0,0 +1,16 @@ +package com.uiui.aios.network.api; + +import com.uiui.aios.bean.BaseResponse; +import com.uiui.aios.bean.UserId; +import com.uiui.aios.network.URLAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface GetUserIDApi { + @GET(URLAddress.GET_USER_ID) + Observable> getUserID( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiui/aios/network/interceptor/RepeatRequestInterceptor.java b/app/src/main/java/com/uiui/aios/network/interceptor/RepeatRequestInterceptor.java new file mode 100644 index 0000000..83d8973 --- /dev/null +++ b/app/src/main/java/com/uiui/aios/network/interceptor/RepeatRequestInterceptor.java @@ -0,0 +1,85 @@ +package com.uiui.aios.network.interceptor; + +import android.util.Log; + +import com.uiui.aios.BuildConfig; +import com.uiui.aios.utils.MD5Util; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; + +import okhttp3.Interceptor; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okio.Buffer; + +public class RepeatRequestInterceptor implements Interceptor { + private static final String TAG = RepeatRequestInterceptor.class.getSimpleName(); + + private final ConcurrentHashMap requestIdsMap = new ConcurrentHashMap<>(); + public static final String REPEAT_REQUEST_PROTOCOL = "OKHTTP_REPEAT_REQUEST_PROTOCOL"; + + @NotNull + @Override + public Response intercept(@NotNull Chain chain) throws IOException { + Request request = chain.request(); + + Response response = chain.proceed(chain.request()); + String content = response.body().string(); + if (BuildConfig.DEBUG) + Log.e(TAG, "请求体返回:| Response:" + content); + //相同的请求 + String requestKey = MD5Util.getUpperMD5Str(request.method() + request.url().toString() + request.body()); + long time = System.currentTimeMillis();//请求时间 + try { + if (requestIdsMap.size() > 0 && requestIdsMap.containsKey(requestKey)) { + log("重复请求:", requestKey, request); + //下面这行写了不会抛出onerror +// chain.call().cancel(); + return new Response.Builder() + .protocol(Protocol.get(REPEAT_REQUEST_PROTOCOL)) + .request(request) //multi thread + .build(); + } + requestIdsMap.put(requestKey, time); + log("注册请求:", requestKey, request); +// RepeatRequestInterceptor.Builder builder = request.newBuilder(); +// builder.addHeader("header", jsonObject.toString()); + return chain.proceed(request); + } catch (IOException e) { + Log.e(TAG, "intercept: " + e.getMessage()); + throw e; + } finally { + if (requestIdsMap.containsKey(requestKey) && requestIdsMap.containsValue(time)) {//请求任务完成删除map中的数据 + requestIdsMap.remove(requestKey); + log("移除请求:", requestKey, request); + } + } + } + + private void log(String action, String requestKey, Request request) { + if (BuildConfig.DEBUG) { + Log.e("REPEAT-REQUEST", action + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url().encodedPath() + "\t" + bodyToString(request)); + } else { + Log.e("REPEAT-REQUEST", action + requestKey + " Method @" + request.method()); + } + } + + private static String bodyToString(final Request request) { + try { + final Request copy = request.newBuilder().build(); + final Buffer buffer = new Buffer(); + copy.body().writeTo(buffer); + if (buffer.size() > 4096) { + return "-too long"; + } + return buffer.readUtf8(); + } catch (Exception e) { + return "-" + e.getMessage(); + } + } + +} diff --git a/app/src/main/java/com/uiui/aios/utils/GsonUtils.java b/app/src/main/java/com/uiui/aios/utils/GsonUtils.java new file mode 100644 index 0000000..9ea2b86 --- /dev/null +++ b/app/src/main/java/com/uiui/aios/utils/GsonUtils.java @@ -0,0 +1,24 @@ +package com.uiui.aios.utils; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + + +public class GsonUtils { + public static JsonObject getJsonObject(String jsonString) { + JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject(); + return jsonObject; + } + + // TODO: 2022/3/31 暂时没有实现 + public static T getJsonFromType(String jsonString, Class clazz) { + Gson gson = new Gson(); + T t = (T) gson.fromJson(jsonString, clazz); + return t; + } + + public static String toJsonString(Object o) { + return new Gson().toJson(o); + } +}