* Create by KunMinX at 2022/6/14
*/
public class NoteRequester extends MviDispatcher
* Create by KunMinX at 2022/8/24
*/
public class WeatherRequester extends MviDispatcher
* author: Blankj
* blog : http://blankj.com
* time : 2016/09/23
* desc : AdaptScreenUtils
*
*/
public final class AdaptScreenUtils {
private static boolean isInitMiui = false;
private static Field mTmpMetricsField;
public static Resources adaptWidth(Resources resources, int designWidth) {
DisplayMetrics dm = getDisplayMetrics(resources);
float newXdpi = dm.xdpi = (dm.widthPixels * 72f) / designWidth;
setAppDmXdpi(newXdpi);
return resources;
}
public static Resources adaptHeight(Resources resources, int designHeight) {
DisplayMetrics dm = getDisplayMetrics(resources);
float newXdpi = dm.xdpi = (dm.heightPixels * 72f) / designHeight;
setAppDmXdpi(newXdpi);
return resources;
}
private static void setAppDmXdpi(final float xdpi) {
Utils.getApp().getResources().getDisplayMetrics().xdpi = xdpi;
}
private static DisplayMetrics getDisplayMetrics(Resources resources) {
DisplayMetrics miuiDisplayMetrics = getMiuiTmpMetrics(resources);
if (miuiDisplayMetrics == null) {
return resources.getDisplayMetrics();
}
return miuiDisplayMetrics;
}
private static DisplayMetrics getMiuiTmpMetrics(Resources resources) {
if (!isInitMiui) {
DisplayMetrics ret = null;
String simpleName = resources.getClass().getSimpleName();
if ("MiuiResources".equals(simpleName) || "XResources".equals(simpleName)) {
try {
//noinspection JavaReflectionMemberAccess
mTmpMetricsField = Resources.class.getDeclaredField("mTmpMetrics");
mTmpMetricsField.setAccessible(true);
ret = (DisplayMetrics) mTmpMetricsField.get(resources);
} catch (Exception e) {
Log.e("AdaptScreenUtils", "no field of mTmpMetrics in resources.");
}
}
isInitMiui = true;
return ret;
}
if (mTmpMetricsField == null) {
return null;
}
try {
return (DisplayMetrics) mTmpMetricsField.get(resources);
} catch (Exception e) {
return null;
}
}
}
================================================
FILE: architecture/src/main/java/com/kunminx/architecture/utils/TimeUtils.java
================================================
package com.kunminx.architecture.utils;
import android.annotation.SuppressLint;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Objects;
/**
* Create by KunMinX at 2022/6/30
*/
public class TimeUtils {
public final static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public final static String YY_MM_DD = "yy-MM-dd";
public final static String HH_MM_SS = "HH:mm:ss";
public static String getCurrentTime(String time_format) {
@SuppressLint("SimpleDateFormat")
SimpleDateFormat formatter = new SimpleDateFormat(time_format);
Date curDate = new Date(System.currentTimeMillis());
return formatter.format(curDate);
}
public static String getTime(long time, String format) {
@SuppressLint("SimpleDateFormat")
SimpleDateFormat formatter = new SimpleDateFormat(format);
Date curDate = new Date(time);
return formatter.format(curDate);
}
public static long getStringToDate(String dateString, String pattern) {
@SuppressLint("SimpleDateFormat")
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
Date date = null;
try {
date = (Date) dateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
return Objects.requireNonNull(date).getTime();
}
}
================================================
FILE: architecture/src/main/java/com/kunminx/architecture/utils/ToastUtils.java
================================================
package com.kunminx.architecture.utils;
import android.widget.Toast;
/**
* Create by KunMinX at 2021/8/19
*/
public class ToastUtils {
public static void showLongToast(String text) {
Toast.makeText(Utils.getApp().getApplicationContext(), text, Toast.LENGTH_LONG).show();
}
public static void showShortToast(String text) {
Toast.makeText(Utils.getApp().getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
================================================
FILE: architecture/src/main/java/com/kunminx/architecture/utils/Utils.java
================================================
package com.kunminx.architecture.utils;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import androidx.core.content.FileProvider;
import java.lang.reflect.InvocationTargetException;
/**
*
* blog : http://blankj.com
* time : 16/12/08
* desc : utils about initialization
*
*/
public final class Utils {
@SuppressLint("StaticFieldLeak")
private static Application sApplication;
private Utils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
public static void init(final Context context) {
if (context == null) {
init(getApplicationByReflect());
return;
}
init((Application) context.getApplicationContext());
}
public static void init(final Application app) {
if (sApplication == null) {
if (app == null) {
sApplication = getApplicationByReflect();
} else {
sApplication = app;
}
} else {
if (app != null && app.getClass() != sApplication.getClass()) {
sApplication = app;
}
}
}
public static Application getApp() {
if (sApplication != null) {
return sApplication;
}
Application app = getApplicationByReflect();
init(app);
return app;
}
private static Application getApplicationByReflect() {
try {
@SuppressLint("PrivateApi")
Class> activityThread = Class.forName("android.app.ActivityThread");
Object thread = activityThread.getMethod("currentActivityThread").invoke(null);
Object app = activityThread.getMethod("getApplication").invoke(thread);
if (app == null) {
throw new NullPointerException("u should init first");
}
return (Application) app;
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException | InvocationTargetException e) {
e.printStackTrace();
}
throw new NullPointerException("u should init first");
}
public static final class FileProvider4UtilCode extends FileProvider {
@Override
public boolean onCreate() {
Utils.init(getContext());
return true;
}
}
}
================================================
FILE: architecture/src/main/res/values/attrs.xml
================================================
* author:
* ___ ___ ___ ___
* _____ / /\ /__/\ /__/| / /\
* / /::\ / /::\ \ \:\ | |:| / /:/
* / /:/\:\ ___ ___ / /:/\:\ \ \:\ | |:| /__/::\
* / /:/~/::\ /__/\ / /\ / /:/~/::\ _____\__\:\ __| |:| \__\/\:\
* /__/:/ /:/\:| \ \:\ / /:/ /__/:/ /:/\:\ /__/::::::::\ /__/\_|:|____ \ \:\
* \ \:\/:/~/:/ \ \:\ /:/ \ \:\/:/__\/ \ \:\~~\~~\/ \ \:\/:::::/ \__\:\
* \ \::/ /:/ \ \:\/:/ \ \::/ \ \:\ ~~~ \ \::/~~~~ / /:/
* \ \:\/:/ \ \::/ \ \:\ \ \:\ \ \:\ /__/:/
* \ \::/ \__\/ \ \:\ \ \:\ \ \:\ \__\/
* \__\/ \__\/ \__\/ \__\/
* blog : http://blankj.com
* time : 16/12/08
* desc : utils about initialization
*
*/
public final class AppUtils {
@SuppressLint("StaticFieldLeak")
private static Application sApplication;
private AppUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
public static Application getApp() {
if (sApplication != null) {
return sApplication;
}
sApplication = getApplicationByReflect();
return sApplication;
}
private static Application getApplicationByReflect() {
try {
@SuppressLint("PrivateApi")
Class> activityThread = Class.forName("android.app.ActivityThread");
Object thread = activityThread.getMethod("currentActivityThread").invoke(null);
Object app = activityThread.getMethod("getApplication").invoke(thread);
if (app == null) {
throw new NullPointerException("u should init first");
}
return (Application) app;
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException | InvocationTargetException e) {
e.printStackTrace();
}
throw new NullPointerException("u should init first");
}
}
================================================
FILE: keyvalue-dispatch/src/main/java/com/kunminx/architecture/utils/SPUtils.java
================================================
package com.kunminx.architecture.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
*
* author: Blankj
* blog : http://blankj.com
* time : 2016/08/02
* desc : utils about shared preference
*
*/
@SuppressLint("ApplySharedPref")
public final class SPUtils {
private static final Map
{@code false}: no
*/
public boolean contains(@NonNull final String key) {
return sp.contains(key);
}
/**
* Remove the preference in sp.
*
* @param key The key of sp.
*/
public void remove(@NonNull final String key) {
remove(key, false);
}
/**
* Remove the preference in sp.
*
* @param key The key of sp.
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void remove(@NonNull final String key, final boolean isCommit) {
if (isCommit) {
sp.edit().remove(key).commit();
} else {
sp.edit().remove(key).apply();
}
}
/**
* Remove all preferences in sp.
*/
public void clear() {
clear(false);
}
/**
* Remove all preferences in sp.
*
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void clear(final boolean isCommit) {
if (isCommit) {
sp.edit().clear().commit();
} else {
sp.edit().clear().apply();
}
}
}
================================================
FILE: keyvalue-dispatch/src/test/java/com/kunminx/architecture/ExampleUnitTest.java
================================================
package com.kunminx.architecture;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see Testing documentation
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: mvi-dispatch/.gitignore
================================================
/build
================================================
FILE: mvi-dispatch/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
group = 'com.github.KunMinX'
ext {
PUBLISH_GROUP_ID = 'com.kunminx.arch'
PUBLISH_ARTIFACT_ID = 'mvi-dispatch'
PUBLISH_VERSION = appVersionName
VERSION_CODE = appVersionCode
ARTIFACT_DESCRIPTION = 'Jetpack Single Source of Truth Library for android'
POM_URL='https://github.com/KunMinX/Jetpack-MVI-Best-Practice'
POM_SCM_URL='https://github.com/KunMinX/Jetpack-MVI-Best-Practice/tree/master'
POM_SCM_CONNECTION='scm:git:github.com/KunMinX/Jetpack-MVI-Best-Practice.git'
POM_SCM_DEV_CONNECTION='scm:git:ssh://github.com/KunMinX/Jetpack-MVI-Best-Practice.git'
POM_DEVELOPER_ID='KunMinX'
POM_DEVELOPER_NAME='KunMinX'
POM_DEVELOPER_URL='https://github.com/KunMinX'
POM_DEVELOPER_EMAIL='kunminx@gmail.com'
LICENSE_NAME='The Apache Software License, Version 2.0'
LICENSE_URL='http://www.apache.org/licenses/LICENSE-2.0.txt'
uploadJavadocs = false
uploadSources = false
}
apply from: "${rootProject.projectDir}/publish-mavencentral.gradle"
android {
compileSdkVersion appTargetSdk
defaultConfig {
minSdkVersion appMinSdk
targetSdkVersion appTargetSdk
versionCode appVersionCode
versionName appVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
================================================
FILE: mvi-dispatch/consumer-rules.pro
================================================
================================================
FILE: mvi-dispatch/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: mvi-dispatch/src/androidTest/java/com/kunminx/dispatch/ExampleInstrumentedTest.java
================================================
package com.kunminx.dispatch;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see Testing documentation
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.kunminx.dispatch.test", appContext.getPackageName());
}
}
================================================
FILE: mvi-dispatch/src/main/AndroidManifest.xml
================================================