public class DeviceUtils {
private static Activity activity;
public DeviceUtils(Activity activity) {
this.activity=activity;
}
public static int getVersionCode() {
int versionCode = 0;
try {
//获取软件版本号,对应AndroidManifest.xml下android:versionCode
versionCode = activity.getPackageManager().
getPackageInfo(activity.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return versionCode;
}
/**
* 获取版本号名称
*
* @param
* @return
*/
public static String getVerName() {
String verName = "";
try {
verName = activity.getPackageManager().
getPackageInfo(activity.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return verName;
}
/**
* Return the version name of device's system.
*
* @return the version name of device's system
*/
public static String getSDKVersionName() {
return Build.VERSION.RELEASE;
}
/**
* Return version code of device's system.
*
* @return version code of device's system
*/
public static int getSDKVersionCode() {
return Build.VERSION.SDK_INT;
}
/**
* Return the android id of device.
*
* @return the android id of device
*/
@SuppressLint("HardwareIds")
public static String getAndroidID() {
String id = Settings.Secure.getString(
activity.getContentResolver(),
Settings.Secure.ANDROID_ID
);
if ("9774d56d682e549c".equals(id)) return "";
return id == null ? "" : id;
}
/**
* Return the manufacturer of the product/hardware.
* e.g. Xiaomi
*
* @return the manufacturer of the product/hardware
*/
public static String getManufacturer() {
return Build.MANUFACTURER;
}
/**
* Return the model of device.
* e.g. MI2SC
*
* @return the model of device
*/
public static String getModel() {
String model = Build.MODEL;
if (model != null) {
model = model.trim().replaceAll("\\s*", "");
} else {
model = "";
}
return model;
}
/**
* Return an ordered list of ABIs supported by this device. The most preferred ABI is the first
* element in the list.
*
* @return an ordered list of ABIs supported by this device
*/
public static String[] getABIs() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return Build.SUPPORTED_ABIS;
} else {
if (!TextUtils.isEmpty(Build.CPU_ABI2)) {
return new String[]{Build.CPU_ABI, Build.CPU_ABI2};
}
return new String[]{Build.CPU_ABI};
}
}
private static final String KEY_UDID = "KEY_UDID";
private volatile static String udid;
/**
* Return the unique device id.
* {1}{UUID(macAddress)}
* {2}{UUID(androidId )}
* {9}{UUID(random )}
*
* @return the unique device id
*/
public static String getUniqueDeviceId() {
return getUniqueDeviceId("", true);
}
/**
* Return the unique device id.
* android 10 deprecated {prefix}{1}{UUID(macAddress)}
* {prefix}{2}{UUID(androidId )}
* {prefix}{9}{UUID(random )}
*
* @param prefix The prefix of the unique device id.
* @return the unique device id
*/
public static String getUniqueDeviceId(String prefix) {
return getUniqueDeviceId(prefix, true);
}
/**
* Return the unique device id.
* {1}{UUID(macAddress)}
* {2}{UUID(androidId )}
* {9}{UUID(random )}
*
* @param useCache True to use cache, false otherwise.
* @return the unique device id
*/
public static String getUniqueDeviceId(boolean useCache) {
return getUniqueDeviceId("", useCache);
}
/**
* Return the unique device id.
* android 10 deprecated {prefix}{1}{UUID(macAddress)}
* {prefix}{2}{UUID(androidId )}
* {prefix}{9}{UUID(random )}
*
* @param prefix The prefix of the unique device id.
* @param useCache True to use cache, false otherwise.
* @return the unique device id
*/
public static String getUniqueDeviceId(String prefix, boolean useCache) {
if (!useCache) {
return getUniqueDeviceIdReal(prefix);
}
if (udid == null) {
synchronized (DeviceUtils.class) {
if (udid == null) {
UtilsBridge utilsBridge=new UtilsBridge(activity);
final String id = utilsBridge.getSpUtils4Utils().getString(KEY_UDID, null);
if (id != null) {
udid = id;
return udid;
}
return getUniqueDeviceIdReal(prefix);
}
}
}
return udid;
}
private static String getUniqueDeviceIdReal(String prefix) {
try {
final String androidId = getAndroidID();
if (!TextUtils.isEmpty(androidId)) {
return saveUdid(prefix + 2, androidId);
}
} catch (Exception ignore) {/**/}
return saveUdid(prefix + 9, "");
}
private static String saveUdid(String prefix, String id) {
udid = getUdid(prefix, id);
UtilsBridge utilsBridge=new UtilsBridge(activity);
utilsBridge.getSpUtils4Utils().put(KEY_UDID, udid);
return udid;
}
private static String getUdid(String prefix, String id) {
if (id.equals("")) {
return prefix + UUID.randomUUID().toString().replace("-", "");
}
return prefix + UUID.nameUUIDFromBytes(id.getBytes()).toString().replace("-", "");
}
}
public class AdaptScreenUtils {
private static List<Field> sMetricsFields;
private AdaptScreenUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
private static void applyDisplayMetrics(@NonNull final Resources resources, final float newXdpi) {
resources.getDisplayMetrics().xdpi = newXdpi;
Utils.getApp().getResources().getDisplayMetrics().xdpi = newXdpi;
applyOtherDisplayMetrics(resources, newXdpi);
}
static Runnable getPreLoadRunnable() {
return new Runnable() {
@Override
public void run() {
preLoad();
}
};
}
private static void preLoad() {
applyDisplayMetrics(Resources.getSystem(), Resources.getSystem().getDisplayMetrics().xdpi);
}
private static void applyOtherDisplayMetrics(final Resources resources, final float newXdpi) {
if (sMetricsFields == null) {
sMetricsFields = new ArrayList<>();
Class resCls = resources.getClass();
Field[] declaredFields = resCls.getDeclaredFields();
while (declaredFields != null && declaredFields.length > 0) {
for (Field field : declaredFields) {
if (field.getType().isAssignableFrom(DisplayMetrics.class)) {
field.setAccessible(true);
DisplayMetrics tmpDm = getMetricsFromField(resources, field);
if (tmpDm != null) {
sMetricsFields.add(field);
tmpDm.xdpi = newXdpi;
}
}
}
resCls = resCls.getSuperclass();
if (resCls != null) {
declaredFields = resCls.getDeclaredFields();
} else {
break;
}
}
} else {
applyMetricsFields(resources, newXdpi);
}
}
private static void applyMetricsFields(final Resources resources, final float newXdpi) {
for (Field metricsField : sMetricsFields) {
try {
DisplayMetrics dm = (DisplayMetrics) metricsField.get(resources);
if (dm != null) dm.xdpi = newXdpi;
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static DisplayMetrics getMetricsFromField(final Resources resources, final Field field) {
try {
return (DisplayMetrics) field.get(resources);
} catch (Exception ignore) {
return null;
}
}
}
@SuppressLint("ApplySharedPref")
public class SPUtils {
Activity activity;
public SPUtils(Activity activity) {
this. activity=activity;
}
private static final Map<String, SPUtils> SP_UTILS_MAP = new HashMap<>();
private SharedPreferences sp;
public static SPUtils getInstance(String spName) {
return getInstance(spName, Context.MODE_PRIVATE);
}
public static SPUtils getInstance(String spName, final int mode) {
if (isSpace(spName)) spName = "spUtils";
SPUtils spUtils = SP_UTILS_MAP.get(spName);
if (spUtils == null) {
synchronized (SPUtils.class) {
spUtils = SP_UTILS_MAP.get(spName);
if (spUtils == null) {
spUtils = new SPUtils(spName, mode);
SP_UTILS_MAP.put(spName, spUtils);
}
}
}
return spUtils;
}
private SPUtils(final String spName, final int mode) {
sp = Utils.getApp().getSharedPreferences(spName, mode);
}
/**
* Put the string value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
*/
public void put(@NonNull final String key, final String value) {
put(key, value, false);
}
/**
* Put the string value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void put(@NonNull final String key, final String value, final boolean isCommit) {
if (isCommit) {
sp.edit().putString(key, value).commit();
} else {
sp.edit().putString(key, value).apply();
}
}
/**
* Return the string value in sp.
*
* @param key The key of sp.
* @return the string value if sp exists or {@code ""} otherwise
*/
public String getString(@NonNull final String key) {
return getString(key, "");
}
/**
* Return the string value in sp.
*
* @param key The key of sp.
* @param defaultValue The default value if the sp doesn't exist.
* @return the string value if sp exists or {@code defaultValue} otherwise
*/
public String getString(@NonNull final String key, final String defaultValue) {
return sp.getString(key, defaultValue);
}
/**
* Put the int value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
*/
public void put(@NonNull final String key, final int value) {
put(key, value, false);
}
/**
* Put the int value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void put(@NonNull final String key, final int value, final boolean isCommit) {
if (isCommit) {
sp.edit().putInt(key, value).commit();
} else {
sp.edit().putInt(key, value).apply();
}
}
/**
* Return the int value in sp.
*
* @param key The key of sp.
* @return the int value if sp exists or {@code -1} otherwise
*/
public int getInt(@NonNull final String key) {
return getInt(key, -1);
}
/**
* Return the int value in sp.
*
* @param key The key of sp.
* @param defaultValue The default value if the sp doesn't exist.
* @return the int value if sp exists or {@code defaultValue} otherwise
*/
public int getInt(@NonNull final String key, final int defaultValue) {
return sp.getInt(key, defaultValue);
}
/**
* Put the long value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
*/
public void put(@NonNull final String key, final long value) {
put(key, value, false);
}
/**
* Put the long value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void put(@NonNull final String key, final long value, final boolean isCommit) {
if (isCommit) {
sp.edit().putLong(key, value).commit();
} else {
sp.edit().putLong(key, value).apply();
}
}
/**
* Return the long value in sp.
*
* @param key The key of sp.
* @return the long value if sp exists or {@code -1} otherwise
*/
public long getLong(@NonNull final String key) {
return getLong(key, -1L);
}
/**
* Return the long value in sp.
*
* @param key The key of sp.
* @param defaultValue The default value if the sp doesn't exist.
* @return the long value if sp exists or {@code defaultValue} otherwise
*/
public long getLong(@NonNull final String key, final long defaultValue) {
return sp.getLong(key, defaultValue);
}
/**
* Put the float value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
*/
public void put(@NonNull final String key, final float value) {
put(key, value, false);
}
/**
* Put the float value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void put(@NonNull final String key, final float value, final boolean isCommit) {
if (isCommit) {
sp.edit().putFloat(key, value).commit();
} else {
sp.edit().putFloat(key, value).apply();
}
}
/**
* Return the float value in sp.
*
* @param key The key of sp.
* @return the float value if sp exists or {@code -1f} otherwise
*/
public float getFloat(@NonNull final String key) {
return getFloat(key, -1f);
}
/**
* Return the float value in sp.
*
* @param key The key of sp.
* @param defaultValue The default value if the sp doesn't exist.
* @return the float value if sp exists or {@code defaultValue} otherwise
*/
public float getFloat(@NonNull final String key, final float defaultValue) {
return sp.getFloat(key, defaultValue);
}
/**
* Put the boolean value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
*/
public void put(@NonNull final String key, final boolean value) {
put(key, value, false);
}
/**
* Put the boolean value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void put(@NonNull final String key, final boolean value, final boolean isCommit) {
if (isCommit) {
sp.edit().putBoolean(key, value).commit();
} else {
sp.edit().putBoolean(key, value).apply();
}
}
/**
* Return the boolean value in sp.
*
* @param key The key of sp.
* @return the boolean value if sp exists or {@code false} otherwise
*/
public boolean getBoolean(@NonNull final String key) {
return getBoolean(key, false);
}
/**
* Return the boolean value in sp.
*
* @param key The key of sp.
* @param defaultValue The default value if the sp doesn't exist.
* @return the boolean value if sp exists or {@code defaultValue} otherwise
*/
public boolean getBoolean(@NonNull final String key, final boolean defaultValue) {
return sp.getBoolean(key, defaultValue);
}
/**
* Put the set of string value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
*/
public void put(@NonNull final String key, final Set<String> value) {
put(key, value, false);
}
/**
* Put the set of string value in sp.
*
* @param key The key of sp.
* @param value The value of sp.
* @param isCommit True to use {@link SharedPreferences.Editor#commit()},
* false to use {@link SharedPreferences.Editor#apply()}
*/
public void put(@NonNull final String key,
final Set<String> value,
final boolean isCommit) {
if (isCommit) {
sp.edit().putStringSet(key, value).commit();
} else {
sp.edit().putStringSet(key, value).apply();
}
}
/**
* Return the set of string value in sp.
*
* @param key The key of sp.
* @return the set of string value if sp exists
* or {@code Collections.emptySet()} otherwise
*/
public Set<String> getStringSet(@NonNull final String key) {
return getStringSet(key, Collections.<String>emptySet());
}
/**
* Return the set of string value in sp.
*
* @param key The key of sp.
* @param defaultValue The default value if the sp doesn't exist.
* @return the set of string value if sp exists or {@code defaultValue} otherwise
*/
public Set<String> getStringSet(@NonNull final String key,
final Set<String> defaultValue) {
return sp.getStringSet(key, defaultValue);
}
/**
* Return all values in sp.
*
* @return all values in sp
*/
public Map<String, ?> getAll() {
return sp.getAll();
}
/**
* Return whether the sp contains the preference.
*
* @param key The key of sp.
* @return {@code true}: yes
{@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();
}
}
private static boolean isSpace(final String s) {
if (s == null) return true;
for (int i = 0, len = s.length(); i < len; ++i) {
if (!Character.isWhitespace(s.charAt(i))) {
return false;
}
}
return true;
}
}
public class ThreadUtils {
private static final Map<Integer, Map<Integer, ExecutorService>> TYPE_PRIORITY_POOLS = new HashMap<>();
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final byte TYPE_SINGLE = -1;
private static final byte TYPE_CACHED = -2;
private static final byte TYPE_IO = -4;
private static final byte TYPE_CPU = -8;
public static ExecutorService getCachedPool() {
return getPoolByTypeAndPriority(TYPE_CACHED);
}
private static ExecutorService getPoolByTypeAndPriority(final int type) {
return getPoolByTypeAndPriority(type, Thread.NORM_PRIORITY);
}
private static ExecutorService getPoolByTypeAndPriority(final int type, final int priority) {
synchronized (TYPE_PRIORITY_POOLS) {
ExecutorService pool;
Map<Integer, ExecutorService> priorityPools = TYPE_PRIORITY_POOLS.get(type);
if (priorityPools == null) {
priorityPools = new ConcurrentHashMap<>();
pool = ThreadPoolExecutor4Util.createPool(type, priority);
priorityPools.put(priority, pool);
TYPE_PRIORITY_POOLS.put(type, priorityPools);
} else {
pool = priorityPools.get(priority);
if (pool == null) {
pool = ThreadPoolExecutor4Util.createPool(type, priority);
priorityPools.put(priority, pool);
}
}
return pool;
}
}
static final class ThreadPoolExecutor4Util extends ThreadPoolExecutor {
private static ExecutorService createPool(final int type, final int priority) {
switch (type) {
case TYPE_SINGLE:
return new ThreadPoolExecutor4Util(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue4Util(),
new UtilsThreadFactory("single", priority)
);
case TYPE_CACHED:
return new ThreadPoolExecutor4Util(0, 128,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue4Util(true),
new UtilsThreadFactory("cached", priority)
);
case TYPE_IO:
return new ThreadPoolExecutor4Util(2 * CPU_COUNT + 1, 2 * CPU_COUNT + 1,
30, TimeUnit.SECONDS,
new LinkedBlockingQueue4Util(),
new UtilsThreadFactory("io", priority)
);
case TYPE_CPU:
return new ThreadPoolExecutor4Util(CPU_COUNT + 1, 2 * CPU_COUNT + 1,
30, TimeUnit.SECONDS,
new LinkedBlockingQueue4Util(true),
new UtilsThreadFactory("cpu", priority)
);
default:
return new ThreadPoolExecutor4Util(type, type,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue4Util(),
new UtilsThreadFactory("fixed(" + type + ")", priority)
);
}
}
private final AtomicInteger mSubmittedCount = new AtomicInteger();
private LinkedBlockingQueue4Util mWorkQueue;
ThreadPoolExecutor4Util(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
LinkedBlockingQueue4Util workQueue,
ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize,
keepAliveTime, unit,
workQueue,
threadFactory
);
workQueue.mPool = this;
mWorkQueue = workQueue;
}
private int getSubmittedCount() {
return mSubmittedCount.get();
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
mSubmittedCount.decrementAndGet();
super.afterExecute(r, t);
}
@Override
public void execute(@NonNull Runnable command) {
if (this.isShutdown()) return;
mSubmittedCount.incrementAndGet();
try {
super.execute(command);
} catch (RejectedExecutionException ignore) {
Log.e("ThreadUtils", "This will not happen!");
mWorkQueue.offer(command);
} catch (Throwable t) {
mSubmittedCount.decrementAndGet();
}
}
}
private static final class LinkedBlockingQueue4Util extends LinkedBlockingQueue<Runnable> {
private volatile ThreadPoolExecutor4Util mPool;
private int mCapacity = Integer.MAX_VALUE;
LinkedBlockingQueue4Util() {
super();
}
LinkedBlockingQueue4Util(boolean isAddSubThreadFirstThenAddQueue) {
super();
if (isAddSubThreadFirstThenAddQueue) {
mCapacity = 0;
}
}
LinkedBlockingQueue4Util(int capacity) {
super();
mCapacity = capacity;
}
@Override
public boolean offer(@NonNull Runnable runnable) {
if (mCapacity <= size() &&
mPool != null && mPool.getPoolSize() < mPool.getMaximumPoolSize()) {
// create a non-core thread
return false;
}
return super.offer(runnable);
}
}
static final class UtilsThreadFactory extends AtomicLong
implements ThreadFactory {
private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
private static final long serialVersionUID = -9209200509960368598L;
private final String namePrefix;
private final int priority;
private final boolean isDaemon;
UtilsThreadFactory(String prefix, int priority) {
this(prefix, priority, false);
}
UtilsThreadFactory(String prefix, int priority, boolean isDaemon) {
namePrefix = prefix + "-pool-" +
POOL_NUMBER.getAndIncrement() +
"-thread-";
this.priority = priority;
this.isDaemon = isDaemon;
}
@Override
public Thread newThread(@NonNull Runnable r) {
Thread t = new Thread(r, namePrefix + getAndIncrement()) {
@Override
public void run() {
try {
super.run();
} catch (Throwable t) {
Log.e("ThreadUtils", "Request threw uncaught throwable", t);
}
}
};
t.setDaemon(isDaemon);
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(e);
}
});
t.setPriority(priority);
return t;
}
}
}
public class Utils {
@SuppressLint("StaticFieldLeak")
private static Application sApp;
private Utils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* Init utils.
* Init it in the class of UtilsFileProvider.
*
* @param app application
*/
public static void init(final Application app) {
if (app == null) {
Log.e("Utils", "app is null.");
return;
}
if (sApp == null) {
sApp = app;
UtilsBridge.init(sApp);
UtilsBridge.preLoad();
return;
}
if (sApp.equals(app)) return;
UtilsBridge.unInit(sApp);
sApp = app;
UtilsBridge.init(sApp);
}
/**
* Return the Application object.
* Main process get app by UtilsFileProvider,
* and other process get app by reflect.
*
* @return the Application object
*/
public static Application getApp() {
if (sApp != null) return sApp;
init(UtilsBridge.getApplicationByReflect());
if (sApp == null) throw new NullPointerException("reflect failed.");
return sApp;
}
///
// interface
///
public interface OnAppStatusChangedListener {
void onForeground(Activity activity);
void onBackground(Activity activity);
}
public static class ActivityLifecycleCallbacks {
public void onActivityCreated(@NonNull Activity activity) {/**/}
public void onActivityStarted(@NonNull Activity activity) {/**/}
public void onActivityResumed(@NonNull Activity activity) {/**/}
public void onActivityPaused(@NonNull Activity activity) {/**/}
public void onActivityStopped(@NonNull Activity activity) {/**/}
public void onActivityDestroyed(@NonNull Activity activity) {/**/}
public void onLifecycleChanged(@NonNull Activity activity, Lifecycle.Event event) {/**/}
}
public interface Consumer<T> {
void accept(T t);
}
public interface Supplier<T> {
T get();
}
public interface Func1<Ret, Par> {
Ret call(Par param);
}
}
class UtilsActivityLifecycleImpl implements Application.ActivityLifecycleCallbacks {
static final UtilsActivityLifecycleImpl INSTANCE = new UtilsActivityLifecycleImpl();
private final LinkedList<Activity> mActivityList = new LinkedList<>();
void init(Application app) {
app.registerActivityLifecycleCallbacks(this);
}
void unInit(Application app) {
mActivityList.clear();
app.unregisterActivityLifecycleCallbacks(this);
}
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
@Override
public void onActivityPostStopped(@NonNull Activity activity) {/**/}
@Override
public void onActivityPreSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {/**/}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {/**/}
@Override
public void onActivityPostSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {/**/}
@Override
public void onActivityPreDestroyed(@NonNull Activity activity) {/**/}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
Application getApplicationByReflect() {
try {
Class activityThreadClass = Class.forName("android.app.ActivityThread");
Object thread = getActivityThread();
if (thread == null) return null;
Object app = activityThreadClass.getMethod("getApplication").invoke(thread);
if (app == null) return null;
return (Application) app;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Object getActivityThread() {
Object activityThread = getActivityThreadInActivityThreadStaticField();
if (activityThread != null) return activityThread;
return getActivityThreadInActivityThreadStaticMethod();
}
private Object getActivityThreadInActivityThreadStaticField() {
try {
Class activityThreadClass = Class.forName("android.app.ActivityThread");
Field sCurrentActivityThreadField = activityThreadClass.getDeclaredField("sCurrentActivityThread");
sCurrentActivityThreadField.setAccessible(true);
return sCurrentActivityThreadField.get(null);
} catch (Exception e) {
Log.e("UtilsActivityLifecycle", "getActivityThreadInActivityThreadStaticField: " + e.getMessage());
return null;
}
}
private Object getActivityThreadInActivityThreadStaticMethod() {
try {
Class activityThreadClass = Class.forName("android.app.ActivityThread");
return activityThreadClass.getMethod("currentActivityThread").invoke(null);
} catch (Exception e) {
Log.e("UtilsActivityLifecycle", "getActivityThreadInActivityThreadStaticMethod: " + e.getMessage());
return null;
}
}
}
public class UtilsBridge {
private static Activity activity;
public UtilsBridge(Activity activity) {
this. activity=activity;
}
static void init(Application app) {
UtilsActivityLifecycleImpl.INSTANCE.init(app);
}
static void unInit(Application app) {
UtilsActivityLifecycleImpl.INSTANCE.unInit(app);
}
static void preLoad() {
preLoad(AdaptScreenUtils.getPreLoadRunnable());
}
private static void preLoad(final Runnable... runs) {
for (final Runnable r : runs) {
ThreadUtils.getCachedPool().execute(r);
}
}
static SPUtils getSpUtils4Utils() {
SPUtils spUtils=new SPUtils(activity);
return spUtils.getInstance("Utils");
}
static Application getApplicationByReflect() {
return UtilsActivityLifecycleImpl.INSTANCE.getApplicationByReflect();
}
}
不需要懂,不懂也不要问我谢谢!!!