diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt index 22e7702ba..5e08ce14d 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt @@ -14,543 +14,315 @@ * limitations under the License. */ -package com.hippo.ehviewer; +package com.hippo.ehviewer -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.ComponentCallbacks2; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Debug; -import android.text.Html; -import android.text.method.LinkMovementMethod; -import android.util.Log; -import android.view.View; -import android.widget.TextView; +import android.annotation.SuppressLint +import android.app.Activity +import android.content.ComponentCallbacks2 +import android.os.Build +import android.text.Html +import android.text.method.LinkMovementMethod +import android.view.View +import android.widget.TextView +import androidx.appcompat.app.AppCompatDelegate +import androidx.collection.LruCache +import androidx.core.os.LocaleListCompat +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ProcessLifecycleOwner +import coil.Coil +import coil.ImageLoader +import com.hippo.Native +import com.hippo.app.BaseDialogBuilder +import com.hippo.beerbelly.SimpleDiskCache +import com.hippo.ehviewer.client.EhClient +import com.hippo.ehviewer.client.EhCookieStore +import com.hippo.ehviewer.client.EhDns +import com.hippo.ehviewer.client.EhEngine +import com.hippo.ehviewer.client.EhRequestBuilder +import com.hippo.ehviewer.client.EhSSLSocketFactory +import com.hippo.ehviewer.client.EhUrl +import com.hippo.ehviewer.client.EhX509TrustManager +import com.hippo.ehviewer.client.data.GalleryDetail +import com.hippo.ehviewer.client.parser.EventPaneParser +import com.hippo.ehviewer.download.DownloadManager +import com.hippo.ehviewer.spider.SpiderDen +import com.hippo.ehviewer.ui.CommonOperations +import com.hippo.ehviewer.ui.EhActivity +import com.hippo.image.Image +import com.hippo.network.StatusCodeException +import com.hippo.scene.SceneApplication +import com.hippo.util.BitmapUtils +import com.hippo.util.ExceptionUtils +import com.hippo.util.IoThreadPoolExecutor +import com.hippo.util.ReadableTime +import com.hippo.yorozuya.FileUtils +import com.hippo.yorozuya.IntIdGenerator +import okhttp3.Cache +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.OkHttpClient +import java.io.File +import java.security.KeyStore +import java.util.Arrays +import javax.net.ssl.TrustManagerFactory +import javax.net.ssl.X509TrustManager -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.collection.LruCache; -import androidx.core.os.LocaleListCompat; -import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.ProcessLifecycleOwner; - -import com.hippo.Native; -import com.hippo.app.BaseDialogBuilder; -import com.hippo.beerbelly.SimpleDiskCache; -import com.hippo.ehviewer.client.EhClient; -import com.hippo.ehviewer.client.EhCookieStore; -import com.hippo.ehviewer.client.EhDns; -import com.hippo.ehviewer.client.EhEngine; -import com.hippo.ehviewer.client.EhRequestBuilder; -import com.hippo.ehviewer.client.EhSSLSocketFactory; -import com.hippo.ehviewer.client.EhUrl; -import com.hippo.ehviewer.client.EhX509TrustManager; -import com.hippo.ehviewer.client.data.GalleryDetail; -import com.hippo.ehviewer.client.parser.EventPaneParser; -import com.hippo.ehviewer.download.DownloadManager; -import com.hippo.ehviewer.spider.SpiderDen; -import com.hippo.ehviewer.ui.CommonOperations; -import com.hippo.ehviewer.ui.EhActivity; -import com.hippo.image.Image; -import com.hippo.network.StatusCodeException; -import com.hippo.scene.SceneApplication; -import com.hippo.unifile.UniFile; -import com.hippo.util.BitmapUtils; -import com.hippo.util.ExceptionUtils; -import com.hippo.util.IoThreadPoolExecutor; -import com.hippo.util.ReadableTime; -import com.hippo.yorozuya.FileUtils; -import com.hippo.yorozuya.IntIdGenerator; -import com.hippo.yorozuya.OSUtils; -import com.hippo.yorozuya.SimpleHandler; - -import java.io.File; -import java.security.KeyStore; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -import coil.Coil; -import coil.ImageLoader; -import okhttp3.Cache; -import okhttp3.Call; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; - -public class EhApplication extends SceneApplication { - - public static final boolean BETA = false; - private static final String TAG = EhApplication.class.getSimpleName(); - private static final String KEY_GLOBAL_STUFF_NEXT_ID = "global_stuff_next_id"; - private static final boolean DEBUG_CONACO = false; - private static final boolean DEBUG_PRINT_NATIVE_MEMORY = false; - private static final boolean DEBUG_PRINT_IMAGE_COUNT = false; - private static final long DEBUG_PRINT_INTERVAL = 3000L; - - public static boolean locked = true; - public static long locked_last_leave_time = 0; - - private static EhApplication instance; - - private final IntIdGenerator mIdGenerator = new IntIdGenerator(); - private final HashMap mGlobalStuffMap = new HashMap<>(); - private final List mActivityList = new ArrayList<>(); - private EhCookieStore mEhCookieStore; - private EhClient mEhClient; - private EhProxySelector mEhProxySelector; - private OkHttpClient mOkHttpClient; - private Cache mOkHttpCache; - private LruCache mGalleryDetailCache; - private SimpleDiskCache mSpiderInfoCache; - private DownloadManager mDownloadManager; - private Hosts mHosts; - private FavouriteStatusRouter mFavouriteStatusRouter; - private boolean initialized = false; - - public static EhApplication getInstance() { - return instance; - } - - public static EhCookieStore getEhCookieStore(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mEhCookieStore == null) { - application.mEhCookieStore = new EhCookieStore(context); +class EhApplication : SceneApplication() { + private val mIdGenerator = IntIdGenerator() + private val mGlobalStuffMap = HashMap() + private val mActivityList = ArrayList() + private var initialized = false + val topActivity: EhActivity? + get() = if (mActivityList.isNotEmpty()) { + mActivityList[mActivityList.size - 1] as EhActivity + } else { + null } - return application.mEhCookieStore; - } - - @NonNull - public static EhClient getEhClient(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mEhClient == null) { - application.mEhClient = new EhClient(application); - } - return application.mEhClient; - } - - @NonNull - public static EhProxySelector getEhProxySelector(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mEhProxySelector == null) { - application.mEhProxySelector = new EhProxySelector(); - } - return application.mEhProxySelector; - } - - @NonNull - public static OkHttpClient getOkHttpClient(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mOkHttpClient == null) { - OkHttpClient.Builder builder = new OkHttpClient.Builder() - .cookieJar(getEhCookieStore(application)) - .cache(getOkHttpCache(application)) - .dns(new EhDns(application)) - .proxySelector(getEhProxySelector(application)); - - if (Settings.getDF()) { - X509TrustManager trustManager; - try { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init((KeyStore) null); - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager trustManager1)) { - throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); - } - trustManager = trustManager1; - } catch (Exception e) { - e.printStackTrace(); - trustManager = new EhX509TrustManager(); - } - builder.sslSocketFactory(new EhSSLSocketFactory(), trustManager); - } - - application.mOkHttpClient = builder.build(); - } - return application.mOkHttpClient; - } - - @NonNull - public static Cache getOkHttpCache(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mOkHttpCache == null) { - application.mOkHttpCache = new Cache(new File(application.getCacheDir(), "http_cache"), 50L * 1024L * 1024L); - } - return application.mOkHttpCache; - } - - private static int getMemoryCacheMaxSize() { - return Math.min(20 * 1024 * 1024, (int) OSUtils.getAppMaxMemory()); - } - - @NonNull - public static LruCache getGalleryDetailCache(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mGalleryDetailCache == null) { - // Max size 25, 3 min timeout - application.mGalleryDetailCache = new LruCache<>(25); - getFavouriteStatusRouter().addListener((gid, slot) -> { - GalleryDetail gd = application.mGalleryDetailCache.get(gid); - if (gd != null) { - gd.favoriteSlot = slot; - } - }); - } - return application.mGalleryDetailCache; - } - - @NonNull - public static SimpleDiskCache getSpiderInfoCache(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (null == application.mSpiderInfoCache) { - application.mSpiderInfoCache = new SimpleDiskCache( - new File(context.getCacheDir(), "spider_info"), 20 * 1024 * 1024); // 20M - } - return application.mSpiderInfoCache; - } - - @NonNull - public static DownloadManager getDownloadManager() { - return getDownloadManager(instance); - } - - @NonNull - public static DownloadManager getDownloadManager(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mDownloadManager == null) { - application.mDownloadManager = new DownloadManager(application); - } - return application.mDownloadManager; - } - - @NonNull - public static Hosts getHosts(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mHosts == null) { - application.mHosts = new Hosts(application, "hosts.db"); - } - return application.mHosts; - } - - @NonNull - public static FavouriteStatusRouter getFavouriteStatusRouter() { - return getFavouriteStatusRouter(getInstance()); - } - - @NonNull - public static FavouriteStatusRouter getFavouriteStatusRouter(@NonNull Context context) { - EhApplication application = ((EhApplication) context.getApplicationContext()); - if (application.mFavouriteStatusRouter == null) { - application.mFavouriteStatusRouter = new FavouriteStatusRouter(); - } - return application.mFavouriteStatusRouter; - } @SuppressLint("StaticFieldLeak") - @Override - public void onCreate() { - ProcessLifecycleOwner.get().getLifecycle().addObserver(new EhlifecycleObserver()); - instance = this; - - Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler(); - Thread.setDefaultUncaughtExceptionHandler((t, e) -> { + override fun onCreate() { + ProcessLifecycleOwner.get().lifecycle.addObserver(EhlifecycleObserver()) + application = this + val handler = Thread.getDefaultUncaughtExceptionHandler() + Thread.setDefaultUncaughtExceptionHandler { t, e -> try { // Always save crash file if onCreate() is not done if (!initialized || Settings.getSaveCrashLog()) { - Crash.saveCrashLog(instance, e); + Crash.saveCrashLog(application, e) } - } catch (Throwable ignored) { + } catch (ignored: Throwable) { } - if (handler != null) { - handler.uncaughtException(t, e); - } - }); - - super.onCreate(); - - Image.initialize(this); - Native.initialize(); - GetText.initialize(this); - StatusCodeException.initialize(this); - Settings.initialize(this); - ReadableTime.initialize(this); - AppConfig.initialize(this); - SpiderDen.initialize(this); - EhDB.initialize(this); - EhEngine.initialize(); - BitmapUtils.initialize(this); - - Coil.setImageLoader(new ImageLoader.Builder(this).okHttpClient(getOkHttpClient(this)).build()); + handler?.uncaughtException(t, e) + } + super.onCreate() + Image.initialize(this) + Native.initialize() + GetText.initialize(this) + StatusCodeException.initialize(this) + Settings.initialize(this) + ReadableTime.initialize(this) + AppConfig.initialize(this) + SpiderDen.initialize(this) + EhDB.initialize(this) + EhEngine.initialize() + BitmapUtils.initialize(this) + Coil.setImageLoader(ImageLoader.Builder(this).okHttpClient(okHttpClient).build()) // Locales can be managed by system automatically above Snow Cone v2 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) - AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Settings.getLocale())); + AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Settings.getLocale())) + AppCompatDelegate.setDefaultNightMode(Settings.getTheme()) - AppCompatDelegate.setDefaultNightMode(Settings.getTheme()); - - // Do io tasks in new thread - //noinspection deprecation - new AsyncTask() { - @Override - protected Void doInBackground(Void... voids) { - // Check no media file - try { - UniFile downloadLocation = Settings.getDownloadLocation(); - if (Settings.getMediaScan()) { - CommonOperations.removeNoMediaFile(downloadLocation); - } else { - CommonOperations.ensureNoMediaFile(downloadLocation); - } - } catch (Throwable t) { - t.printStackTrace(); - ExceptionUtils.throwIfFatal(t); + IoThreadPoolExecutor.getInstance().execute { + try { + val downloadLocation = Settings.getDownloadLocation() + if (Settings.getMediaScan()) { + CommonOperations.removeNoMediaFile(downloadLocation) + } else { + CommonOperations.ensureNoMediaFile(downloadLocation) } - - // Clear temp files - try { - clearTempDir(); - } catch (Throwable t) { - t.printStackTrace(); - ExceptionUtils.throwIfFatal(t); - } - - return null; + } catch (t: Throwable) { + t.printStackTrace() + ExceptionUtils.throwIfFatal(t) } - }.executeOnExecutor(IoThreadPoolExecutor.getInstance()); - // Check app update - update(); - - // Update version code - try { - PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0); - Settings.putVersionCode(pi.versionCode); - } catch (PackageManager.NameNotFoundException e) { - // Ignore + // Clear temp files + try { + clearTempDir() + } catch (t: Throwable) { + t.printStackTrace() + ExceptionUtils.throwIfFatal(t) + } } - - mIdGenerator.setNextId(Settings.getInt(KEY_GLOBAL_STUFF_NEXT_ID, 0)); - - if (DEBUG_PRINT_NATIVE_MEMORY || DEBUG_PRINT_IMAGE_COUNT) { - debugPrint(); - } - - initialized = true; - theDawnOfNewDay(); + mIdGenerator.setNextId(Settings.getInt(KEY_GLOBAL_STUFF_NEXT_ID, 0)) + initialized = true + theDawnOfNewDay() } - private void theDawnOfNewDay() { + private fun theDawnOfNewDay() { if (!Settings.getRequestNews()) { - return; + return } - EhCookieStore store = getEhCookieStore(this); - HttpUrl eh = HttpUrl.get(EhUrl.HOST_E); + val store = ehCookieStore + val eh = EhUrl.HOST_E.toHttpUrl() - if (store.contains(eh, EhCookieStore.KEY_IPD_MEMBER_ID) || store.contains(eh, EhCookieStore.KEY_IPD_PASS_HASH)) { - IoThreadPoolExecutor.getInstance().execute(() -> { - String referer = EhUrl.REFERER_E; - Request request = new EhRequestBuilder(EhUrl.HOST_E + "news.php", referer).build(); - Call call = getOkHttpClient(this).newCall(request); + if (store.contains(eh, EhCookieStore.KEY_IPD_MEMBER_ID) || store.contains( + eh, + EhCookieStore.KEY_IPD_PASS_HASH + ) + ) { + IoThreadPoolExecutor.getInstance().execute { + val referer = EhUrl.REFERER_E + val request = EhRequestBuilder(EhUrl.HOST_E + "news.php", referer).build() + val call = okHttpClient.newCall(request) try { - Response response = call.execute(); - ResponseBody responseBody = response.body(); - if (responseBody == null) { - return; - } - String body = responseBody.string(); - String html = EventPaneParser.parse(body); + val response = call.execute() + val responseBody = response.body + val body = responseBody.string() + val html = EventPaneParser.parse(body) if (html != null) { - showEventPane(html); + showEventPane(html) } - } catch (Throwable e) { - e.printStackTrace(); + } catch (e: Throwable) { + e.printStackTrace() } - }); - } - } - - public void showEventPane(String html) { - Activity activity = getTopActivity(); - if (activity != null) { - activity.runOnUiThread(() -> { - AlertDialog dialog = new BaseDialogBuilder(activity) - .setMessage(Html.fromHtml(html)) - .setPositiveButton(android.R.string.ok, null) - .create(); - dialog.setOnShowListener(d -> { - final View messageView = dialog.findViewById(android.R.id.message); - if (messageView instanceof TextView) { - ((TextView) messageView).setMovementMethod(LinkMovementMethod.getInstance()); - } - }); - try { - dialog.show(); - } catch (Throwable t) { - // ignore - } - }); - } - } - - private void clearTempDir() { - File dir = AppConfig.getTempDir(); - if (null != dir) { - FileUtils.deleteContent(dir); - } - dir = AppConfig.getExternalTempDir(); - if (null != dir) { - FileUtils.deleteContent(dir); - } - } - - private void update() { - int version = Settings.getVersionCode(); - if (version < 52) { - Settings.putGuideGallery(true); - } - } - - public void clearMemoryCache() { - if (null != mGalleryDetailCache) { - mGalleryDetailCache.evictAll(); - } - } - - @Override - public void onTrimMemory(int level) { - super.onTrimMemory(level); - - if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) { - clearMemoryCache(); - } - } - - private void debugPrint() { - new Runnable() { - @Override - public void run() { - if (DEBUG_PRINT_NATIVE_MEMORY) { - Log.i(TAG, "Native memory: " + FileUtils.humanReadableByteCount( - Debug.getNativeHeapAllocatedSize(), false)); - } - SimpleHandler.getInstance().postDelayed(this, DEBUG_PRINT_INTERVAL); } - }.run(); - } - - public int putGlobalStuff(@NonNull Object o) { - int id = mIdGenerator.nextId(); - mGlobalStuffMap.put(id, o); - Settings.putInt(KEY_GLOBAL_STUFF_NEXT_ID, mIdGenerator.nextId()); - return id; - } - - public boolean containGlobalStuff(int id) { - return mGlobalStuffMap.containsKey(id); - } - - public Object getGlobalStuff(int id) { - return mGlobalStuffMap.get(id); - } - - public Object removeGlobalStuff(int id) { - return mGlobalStuffMap.remove(id); - } - - public void removeGlobalStuff(Object o) { - mGlobalStuffMap.values().removeAll(Collections.singleton(o)); - } - - public void registerActivity(Activity activity) { - mActivityList.add(activity); - } - - public void unregisterActivity(Activity activity) { - mActivityList.remove(activity); - } - - @Nullable - public EhActivity getTopActivity() { - if (!mActivityList.isEmpty()) { - return (EhActivity) mActivityList.get(mActivityList.size() - 1); - } else { - return null; } } - // Avoid crash on some "energy saving" devices - @Override - public ComponentName startService(Intent service) { - try { - return super.startService(service); - } catch (Throwable t) { - t.printStackTrace(); - ExceptionUtils.throwIfFatal(t); - return null; + fun showEventPane(html: String) { + val activity = topActivity + activity?.runOnUiThread { + val dialog = BaseDialogBuilder(activity) + .setMessage(Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY)) + .setPositiveButton(android.R.string.ok, null) + .create() + dialog.setOnShowListener { + val messageView = dialog.findViewById(android.R.id.message) + if (messageView is TextView) { + messageView.movementMethod = LinkMovementMethod.getInstance() + } + } + try { + dialog.show() + } catch (t: Throwable) { + // ignore + } } } - // Avoid crash on some "energy saving" devices - @Override - public boolean bindService(Intent service, ServiceConnection conn, int flags) { - try { - return super.bindService(service, conn, flags); - } catch (Throwable t) { - t.printStackTrace(); - ExceptionUtils.throwIfFatal(t); - return false; + private fun clearTempDir() { + var dir = AppConfig.getTempDir() + if (null != dir) { + FileUtils.deleteContent(dir) + } + dir = AppConfig.getExternalTempDir() + if (null != dir) { + FileUtils.deleteContent(dir) } } - // Avoid crash on some "energy saving" devices - @Override - public void unbindService(ServiceConnection conn) { - try { - super.unbindService(conn); - } catch (Throwable t) { - t.printStackTrace(); - ExceptionUtils.throwIfFatal(t); + override fun onTrimMemory(level: Int) { + super.onTrimMemory(level) + if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) { + galleryDetailCache.evictAll() } } - // Avoid crash on some "energy saving" devices - @Override - public ComponentName startForegroundService(Intent service) { - try { - return super.startForegroundService(service); - } catch (Throwable t) { - t.printStackTrace(); - ExceptionUtils.throwIfFatal(t); - return null; - } + fun putGlobalStuff(o: Any): Int { + val id = mIdGenerator.nextId() + mGlobalStuffMap[id] = o + Settings.putInt(KEY_GLOBAL_STUFF_NEXT_ID, mIdGenerator.nextId()) + return id } - static class EhlifecycleObserver implements DefaultLifecycleObserver { - @Override - public void onPause(@NonNull LifecycleOwner owner) { + fun containGlobalStuff(id: Int): Boolean { + return mGlobalStuffMap.containsKey(id) + } + + fun getGlobalStuff(id: Int): Any? { + return mGlobalStuffMap[id] + } + + fun removeGlobalStuff(id: Int): Any? { + return mGlobalStuffMap.remove(id) + } + + fun removeGlobalStuff(o: Any) { + mGlobalStuffMap.values.removeAll(setOf(o)) + } + + fun registerActivity(activity: Activity) { + mActivityList.add(activity) + } + + fun unregisterActivity(activity: Activity) { + mActivityList.remove(activity) + } + + internal class EhlifecycleObserver : DefaultLifecycleObserver { + override fun onPause(owner: LifecycleOwner) { if (!locked) - locked_last_leave_time = System.currentTimeMillis() / 1000; - locked = true; + locked_last_leave_time = System.currentTimeMillis() / 1000 + locked = true } } + + companion object { + private const val KEY_GLOBAL_STUFF_NEXT_ID = "global_stuff_next_id" + var locked = true + var locked_last_leave_time: Long = 0 + + @JvmStatic + lateinit var application: EhApplication + private set + + @JvmStatic + val ehCookieStore by lazy { EhCookieStore(application) } + + @JvmStatic + val ehClient by lazy { EhClient(application) } + + @JvmStatic + val ehProxySelector by lazy { EhProxySelector() } + + @JvmStatic + val okHttpClient by lazy { + val builder = OkHttpClient.Builder() + .cookieJar(ehCookieStore) + .cache(Cache(File(application.cacheDir, "http_cache"), 50L * 1024L * 1024L)) + .dns(EhDns()) + .proxySelector(ehProxySelector) + + if (Settings.getDF()) { + var trustManager: X509TrustManager + try { + val trustManagerFactory = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm() + ) + trustManagerFactory.init(null as KeyStore?) + val trustManagers = trustManagerFactory.trustManagers + check(!(trustManagers.size != 1 || trustManagers[0] !is X509TrustManager)) { + "Unexpected default trust managers:" + Arrays.toString( + trustManagers + ) + } + trustManager = trustManagers[0] as X509TrustManager + } catch (e: Exception) { + e.printStackTrace() + trustManager = EhX509TrustManager() + } + + builder.sslSocketFactory(EhSSLSocketFactory(), trustManager) + } + builder.build() + } + + @JvmStatic + val galleryDetailCache by lazy { + LruCache(25).also { + favouriteStatusRouter.addListener { gid, slot -> + it[gid]?.favoriteSlot = slot + } + } + } + + @JvmStatic + val spiderInfoCache by lazy { + SimpleDiskCache( + File(application.cacheDir, "spider_info"), + 20 * 1024 * 1024 + ) + } + + @JvmStatic + val downloadManager by lazy { DownloadManager(application) } + + @JvmStatic + val hosts by lazy { Hosts(application, "hosts.db") } + + @JvmStatic + val favouriteStatusRouter by lazy { FavouriteStatusRouter() } + } } diff --git a/app/src/main/java/com/hippo/ehviewer/EhDB.java b/app/src/main/java/com/hippo/ehviewer/EhDB.java index d9e23e454..92ee45374 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhDB.java +++ b/app/src/main/java/com/hippo/ehviewer/EhDB.java @@ -491,7 +491,7 @@ public class EhDB { .createFromFile(file).allowMainThreadQueries().build(); // Download label - DownloadManager manager = EhApplication.getDownloadManager(context); + DownloadManager manager = EhApplication.getDownloadManager(); try { List downloadLabelList = oldRoomDatabase.downloadLabelDao().list(); manager.addDownloadLabel(downloadLabelList); diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.java b/app/src/main/java/com/hippo/ehviewer/Settings.java index a2063c670..0e97ad176 100755 --- a/app/src/main/java/com/hippo/ehviewer/Settings.java +++ b/app/src/main/java/com/hippo/ehviewer/Settings.java @@ -246,7 +246,6 @@ public class Settings { ****** Update ********************/ private static final String KEY_BETA_UPDATE_CHANNEL = "beta_update_channel"; - private static final boolean DEFAULT_BETA_UPDATE_CHANNEL = EhApplication.BETA; private static final String KEY_SKIP_UPDATE_VERSION = "skip_update_version"; private static final int DEFAULT_SKIP_UPDATE_VERSION = 0; private static final boolean DEFAULT_SAVE_PARSE_ERROR_BODY = true; @@ -424,14 +423,6 @@ public class Settings { sSettingsPre.edit().putString(key, Integer.toString(value)).apply(); } - public static int getVersionCode() { - return getInt(KEY_VERSION_CODE, DEFAULT_VERSION_CODE); - } - - public static void putVersionCode(int value) { - putInt(KEY_VERSION_CODE, value); - } - @Nullable public static String getDisplayName() { return getString(KEY_DISPLAY_NAME, DEFAULT_DISPLAY_NAME); @@ -1024,10 +1015,6 @@ public class Settings { return true; } - public static boolean getBetaUpdateChannel() { - return getBoolean(KEY_BETA_UPDATE_CHANNEL, DEFAULT_BETA_UPDATE_CHANNEL); - } - public static void putBetaUpdateChannel(boolean value) { putBoolean(KEY_BETA_UPDATE_CHANNEL, value); } diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java index cf999a386..e7c1eb192 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java @@ -61,7 +61,7 @@ public class EhClient { public EhClient(Context context) { mRequestThreadPool = IoThreadPoolExecutor.getInstance(); - mOkHttpClient = EhApplication.getOkHttpClient(context); + mOkHttpClient = EhApplication.getOkHttpClient(); } public void execute(EhRequest request) { diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt b/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt index 28c8724f2..bcad3d29c 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhDns.kt @@ -15,7 +15,6 @@ */ package com.hippo.ehviewer.client -import android.content.Context import com.hippo.ehviewer.EhApplication import com.hippo.ehviewer.Hosts import com.hippo.ehviewer.Settings @@ -23,8 +22,8 @@ import okhttp3.Dns import java.net.InetAddress import java.net.UnknownHostException -class EhDns(context: Context) : Dns { - private val hosts = EhApplication.getHosts(context) +class EhDns : Dns { + private val hosts = EhApplication.hosts private val builtInHosts: MutableMap> = mutableMapOf() init { diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java index 775ec7ced..e57041b26 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java @@ -361,7 +361,7 @@ public class EhEngine { body = response.body().string(); String html = EventPaneParser.parse(body); if (html != null) { - EhApplication.getInstance().showEventPane(html); + EhApplication.getApplication().showEventPane(html); } return GalleryDetailParser.parse(body); } catch (Throwable e) { diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.java b/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.java index 48a583e31..8bc741c67 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.java @@ -260,7 +260,7 @@ public class EhTagDatabase { } } - OkHttpClient client = EhApplication.getOkHttpClient(context); + OkHttpClient client = EhApplication.getOkHttpClient(); // Save new sha1 File tempSha1File = new File(dir, sha1Name + ".tmp"); diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhUtils.java b/app/src/main/java/com/hippo/ehviewer/client/EhUtils.java index 8a42f74d6..3a7e26331 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhUtils.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhUtils.java @@ -133,14 +133,14 @@ public class EhUtils { } public static void signOut(Context context) { - EhApplication.getEhCookieStore(context).signOut(); + EhApplication.getEhCookieStore().signOut(); Settings.putAvatar(null); Settings.putDisplayName(null); Settings.putNeedSignIn(true); } public static boolean needSignedIn(Context context) { - return Settings.getNeedSignIn() && !EhApplication.getEhCookieStore(context).hasSignedIn(); + return Settings.getNeedSignIn() && !EhApplication.getEhCookieStore().hasSignedIn(); } public static String getSuitableTitle(GalleryInfo gi) { diff --git a/app/src/main/java/com/hippo/ehviewer/download/DownloadService.kt b/app/src/main/java/com/hippo/ehviewer/download/DownloadService.kt index 426f6266c..4184e2346 100644 --- a/app/src/main/java/com/hippo/ehviewer/download/DownloadService.kt +++ b/app/src/main/java/com/hippo/ehviewer/download/DownloadService.kt @@ -67,7 +67,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener { .setName(getString(R.string.download_service)) .build() ) - mDownloadManager = EhApplication.getDownloadManager(applicationContext) + mDownloadManager = EhApplication.downloadManager mDownloadManager!!.setDownloadListener(this) ensureDownloadingBuilder() mDownloadingBuilder!!.setContentTitle(getString(R.string.download_service)) diff --git a/app/src/main/java/com/hippo/ehviewer/preference/AccountPreference.kt b/app/src/main/java/com/hippo/ehviewer/preference/AccountPreference.kt index f93199804..4af135b44 100644 --- a/app/src/main/java/com/hippo/ehviewer/preference/AccountPreference.kt +++ b/app/src/main/java/com/hippo/ehviewer/preference/AccountPreference.kt @@ -40,7 +40,7 @@ class AccountPreference @JvmOverloads constructor( private var message: String? = null init { - val store = EhApplication.getEhCookieStore(context) + val store = EhApplication.ehCookieStore val eCookies = store.getCookies(EhUrl.HOST_E.toHttpUrl()) val exCookies = store.getCookies(EhUrl.HOST_EX.toHttpUrl()) val cookies: MutableList = LinkedList(eCookies) diff --git a/app/src/main/java/com/hippo/ehviewer/preference/CleanRedundancyPreference.java b/app/src/main/java/com/hippo/ehviewer/preference/CleanRedundancyPreference.java index a45facc19..ab2bdec0f 100644 --- a/app/src/main/java/com/hippo/ehviewer/preference/CleanRedundancyPreference.java +++ b/app/src/main/java/com/hippo/ehviewer/preference/CleanRedundancyPreference.java @@ -55,7 +55,7 @@ public class CleanRedundancyPreference extends TaskPreference { public ClearTask(@NonNull Context context) { super(context); - mManager = EhApplication.getDownloadManager(context.getApplicationContext()); + mManager = EhApplication.getDownloadManager(); } // True for cleared diff --git a/app/src/main/java/com/hippo/ehviewer/preference/ProxyPreference.kt b/app/src/main/java/com/hippo/ehviewer/preference/ProxyPreference.kt index 342f43322..bce06eaf1 100644 --- a/app/src/main/java/com/hippo/ehviewer/preference/ProxyPreference.kt +++ b/app/src/main/java/com/hippo/ehviewer/preference/ProxyPreference.kt @@ -161,7 +161,7 @@ class ProxyPreference @JvmOverloads constructor( Settings.putProxyIp(ip) Settings.putProxyPort(port) updateSummary(type, ip, port) - EhApplication.getEhProxySelector(getContext()).updateProxy() + EhApplication.ehProxySelector.updateProxy() dialog.dismiss() } } \ No newline at end of file diff --git a/app/src/main/java/com/hippo/ehviewer/preference/RestoreDownloadPreference.java b/app/src/main/java/com/hippo/ehviewer/preference/RestoreDownloadPreference.java index 62215a243..66c866a1d 100644 --- a/app/src/main/java/com/hippo/ehviewer/preference/RestoreDownloadPreference.java +++ b/app/src/main/java/com/hippo/ehviewer/preference/RestoreDownloadPreference.java @@ -74,8 +74,8 @@ public class RestoreDownloadPreference extends TaskPreference { public RestoreTask(@NonNull Context context) { super(context); - mManager = EhApplication.getDownloadManager(context.getApplicationContext()); - mHttpClient = EhApplication.getOkHttpClient(context.getApplicationContext()); + mManager = EhApplication.getDownloadManager(); + mHttpClient = EhApplication.getOkHttpClient(); } private RestoreItem getRestoreItem(UniFile file) { diff --git a/app/src/main/java/com/hippo/ehviewer/preference/SignInRequiredPreference.java b/app/src/main/java/com/hippo/ehviewer/preference/SignInRequiredPreference.java index f916eb20b..684887c00 100644 --- a/app/src/main/java/com/hippo/ehviewer/preference/SignInRequiredPreference.java +++ b/app/src/main/java/com/hippo/ehviewer/preference/SignInRequiredPreference.java @@ -58,7 +58,7 @@ public class SignInRequiredPreference extends Preference implements Preference.O @Override public boolean onPreferenceClick(Preference preference) { - EhCookieStore store = EhApplication.getEhCookieStore(getContext()); + EhCookieStore store = EhApplication.getEhCookieStore(); HttpUrl e = HttpUrl.get(EhUrl.HOST_E); HttpUrl ex = HttpUrl.get(EhUrl.HOST_EX); diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java index e3e9c37ab..f89766e62 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java @@ -158,8 +158,8 @@ public final class SpiderQueen implements Runnable { private volatile int mDownloadPage = -1; private SpiderQueen(EhApplication application, @NonNull GalleryInfo galleryInfo) { - mHttpClient = EhApplication.getOkHttpClient(application); - mSpiderInfoCache = EhApplication.getSpiderInfoCache(application); + mHttpClient = EhApplication.getOkHttpClient(); + mSpiderInfoCache = EhApplication.getSpiderInfoCache(); mGalleryInfo = galleryInfo; mSpiderDen = new SpiderDen(mGalleryInfo); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/CommonOperations.java b/app/src/main/java/com/hippo/ehviewer/ui/CommonOperations.java index 84e3bfa44..9a186e81c 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/CommonOperations.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/CommonOperations.java @@ -53,7 +53,7 @@ public final class CommonOperations { EhDB.putLocalFavorites(galleryInfo); listener.onSuccess(null); } else if (slot >= 0 && slot <= 9) { - EhClient client = EhApplication.getEhClient(activity); + EhClient client = EhApplication.getEhClient(); EhRequest request = new EhRequest(); request.setMethod(EhClient.METHOD_ADD_FAVORITES); request.setArgs(galleryInfo.gid, galleryInfo.token, slot, ""); @@ -100,7 +100,7 @@ public final class CommonOperations { public static void removeFromFavorites(Activity activity, GalleryInfo galleryInfo, final EhClient.Callback listener) { EhDB.removeLocalFavorites(galleryInfo.gid); - EhClient client = EhApplication.getEhClient(activity); + EhClient client = EhApplication.getEhClient(); EhRequest request = new EhRequest(); request.setMethod(EhClient.METHOD_ADD_FAVORITES); request.setArgs(galleryInfo.gid, galleryInfo.token, -1, ""); @@ -114,13 +114,13 @@ public final class CommonOperations { public static void startDownload(final MainActivity activity, final List galleryInfos, boolean forceDefault) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - Objects.requireNonNull(EhApplication.getInstance().getTopActivity()).checkAndRequestNotificationPermission(); + Objects.requireNonNull(EhApplication.getApplication().getTopActivity()).checkAndRequestNotificationPermission(); } doStartDownload(activity, galleryInfos, forceDefault); } private static void doStartDownload(final MainActivity activity, final List galleryInfos, boolean forceDefault) { - final DownloadManager dm = EhApplication.getDownloadManager(activity); + final DownloadManager dm = EhApplication.getDownloadManager(); LongList toStart = new LongList(); List toAdd = new ArrayList<>(); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.kt b/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.kt index 2810511a4..2078c14ed 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.kt @@ -31,7 +31,6 @@ import androidx.annotation.StyleRes import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import com.hippo.ehviewer.EhApplication -import com.hippo.ehviewer.EhApplication.locked_last_leave_time import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings import rikka.core.res.resolveColor @@ -91,7 +90,7 @@ abstract class EhActivity : AppCompatActivity() { override fun onResume() { val locked_resume_time = System.currentTimeMillis() / 1000 - val locked_delay_time = locked_resume_time - locked_last_leave_time + val locked_delay_time = locked_resume_time - EhApplication.locked_last_leave_time if (locked_delay_time < Settings.getSecurityDelay() * 60) { EhApplication.locked = false } else if (Settings.getSecurity() && isAuthenticationSupported() && EhApplication.locked) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java b/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java index 00dbae68d..b656331c0 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java @@ -305,7 +305,7 @@ public class AdvancedFragment extends BasePreferenceFragment { } private void backupFavorite() { - EhClient mClient = EhApplication.getEhClient(requireContext()); + EhClient mClient = EhApplication.getEhClient(); FavListUrlBuilder favListUrlBuilder = new FavListUrlBuilder(); favTotal = 0; favIndex = 1; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/HostsFragment.kt b/app/src/main/java/com/hippo/ehviewer/ui/fragment/HostsFragment.kt index 104abe699..0cdf3fe4b 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/HostsFragment.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/HostsFragment.kt @@ -43,7 +43,7 @@ class HostsFragment : BaseFragment(), View.OnClickListener { private var adapter: HostsAdapter? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - EhApplication.getHosts(requireContext()).apply { + EhApplication.hosts.apply { hosts = this data = all } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/MyTagsFragment.java b/app/src/main/java/com/hippo/ehviewer/ui/fragment/MyTagsFragment.java index 172395dba..4b0a83155 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/MyTagsFragment.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/MyTagsFragment.java @@ -84,7 +84,7 @@ public class MyTagsFragment extends BaseFragment { // Copy cookies from okhttp cookie store to CookieManager url = EhUrl.getMyTagsUrl(); - EhCookieStore store = EhApplication.getEhCookieStore(requireContext()); + EhCookieStore store = EhApplication.getEhCookieStore(); for (Cookie cookie : store.getCookies(HttpUrl.parse(url))) { cookieManager.setCookie(url, cookie.toString()); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/UConfigFragment.java b/app/src/main/java/com/hippo/ehviewer/ui/fragment/UConfigFragment.java index 2fa01e8d9..ce8a3f966 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/UConfigFragment.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/UConfigFragment.java @@ -91,7 +91,7 @@ public class UConfigFragment extends BaseFragment { // Copy cookies from okhttp cookie store to CookieManager url = EhUrl.getUConfigUrl(); - EhCookieStore store = EhApplication.getEhCookieStore(requireContext()); + EhCookieStore store = EhApplication.getEhCookieStore(); for (Cookie cookie : store.getCookies(HttpUrl.parse(url))) { cookieManager.setCookie(url, cookie.toString()); } @@ -142,7 +142,7 @@ public class UConfigFragment extends BaseFragment { String cookiesString = cookieManager.getCookie(url); if (cookiesString != null && !cookiesString.isEmpty()) { - EhCookieStore store = EhApplication.getEhCookieStore(requireContext()); + EhCookieStore store = EhApplication.getEhCookieStore(); HttpUrl eUrl = HttpUrl.parse(EhUrl.HOST_E); HttpUrl exUrl = HttpUrl.parse(EhUrl.HOST_EX); if (eUrl == null || exUrl == null) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/CookieSignInScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/CookieSignInScene.java index 3fc6582f6..85c8f3ec5 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/CookieSignInScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/CookieSignInScene.java @@ -240,7 +240,7 @@ public class CookieSignInScene extends SolidScene implements EditText.OnEditorAc EhUtils.signOut(context); - EhCookieStore store = EhApplication.getEhCookieStore(context); + EhCookieStore store = EhApplication.getEhCookieStore(); store.addCookie(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_E)); store.addCookie(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_EX)); store.addCookie(newCookie(EhCookieStore.KEY_IPD_PASS_HASH, hash, EhUrl.DOMAIN_E)); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java index 09edfebeb..90d65d616 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java @@ -162,7 +162,7 @@ public class DownloadsScene extends ToolbarScene if (context == null) { return; } - List listLabel = EhApplication.getDownloadManager(context).getLabelList(); + List listLabel = EhApplication.getDownloadManager().getLabelList(); mLabels = new ArrayList<>(listLabel.size() + 1); // Add default label name mLabels.add(getString(R.string.default_download_label_name)); @@ -214,7 +214,7 @@ public class DownloadsScene extends ToolbarScene Context context = getContext(); AssertUtils.assertNotNull(context); - mDownloadManager = EhApplication.getDownloadManager(context); + mDownloadManager = EhApplication.getDownloadManager(); mDownloadManager.addDownloadInfoListener(this); if (savedInstanceState == null) { @@ -233,7 +233,7 @@ public class DownloadsScene extends ToolbarScene if (null == manager) { Context context = getContext(); if (null != context) { - manager = EhApplication.getDownloadManager(context); + manager = EhApplication.getDownloadManager(); } } else { mDownloadManager = null; @@ -697,7 +697,7 @@ public class DownloadsScene extends ToolbarScene break; } case 4: {// Move - List labelRawList = EhApplication.getDownloadManager(context).getLabelList(); + List labelRawList = EhApplication.getDownloadManager().getLabelList(); List labelList = new ArrayList<>(labelRawList.size() + 1); labelList.add(getString(R.string.default_download_label_name)); for (int i = 0, n = labelRawList.size(); i < n; i++) { @@ -906,7 +906,7 @@ public class DownloadsScene extends ToolbarScene String label = mLabels.get(position); if (mDownloadManager == null) { if (context != null) { - mDownloadManager = EhApplication.getDownloadManager(context); + mDownloadManager = EhApplication.getDownloadManager(); } } List list = null; @@ -1040,7 +1040,7 @@ public class DownloadsScene extends ToolbarScene } else { label = mLabels[which]; } - EhApplication.getDownloadManager(context).changeLabel(mDownloadInfoList, label); + EhApplication.getDownloadManager().changeLabel(mDownloadInfoList, label); if (mLabelAdapter != null) { mLabelAdapter.notifyDataSetChanged(); } @@ -1162,7 +1162,7 @@ public class DownloadsScene extends ToolbarScene return; } DownloadInfo info = mList.get(position); - holder.thumb.load(EhCacheKeyFactory.getThumbKey(info.gid), info.thumb, true); + holder.thumb.load(EhCacheKeyFactory.getThumbKey(info.gid), info.thumb); holder.title.setText(EhUtils.getSuitableTitle(info)); holder.uploader.setText(info.uploader); holder.rating.setRating(info.rating); @@ -1246,12 +1246,12 @@ public class DownloadsScene extends ToolbarScene mBuilder.setError(getString(R.string.label_text_is_empty)); } else if (getString(R.string.default_download_label_name).equals(text)) { mBuilder.setError(getString(R.string.label_text_is_invalid)); - } else if (EhApplication.getDownloadManager(context).containLabel(text)) { + } else if (EhApplication.getDownloadManager().containLabel(text)) { mBuilder.setError(getString(R.string.label_text_exist)); } else { mBuilder.setError(null); mDialog.dismiss(); - EhApplication.getDownloadManager(context).renameLabel(mOriginalLabel, text); + EhApplication.getDownloadManager().renameLabel(mOriginalLabel, text); if (mLabelAdapter != null) { initLabels(); mLabelAdapter.notifyDataSetChanged(); @@ -1286,12 +1286,12 @@ public class DownloadsScene extends ToolbarScene mBuilder.setError(getString(R.string.label_text_is_empty)); } else if (getString(R.string.default_download_label_name).equals(text)) { mBuilder.setError(getString(R.string.label_text_is_invalid)); - } else if (EhApplication.getDownloadManager(context).containLabel(text)) { + } else if (EhApplication.getDownloadManager().containLabel(text)) { mBuilder.setError(getString(R.string.label_text_exist)); } else { mBuilder.setError(null); mDialog.dismiss(); - EhApplication.getDownloadManager(context).addLabel(text); + EhApplication.getDownloadManager().addLabel(text); initLabels(); if (mLabelAdapter != null && mLabels != null) { mLabelAdapter.notifyItemInserted(mLabels.size() - 1); @@ -1317,7 +1317,7 @@ public class DownloadsScene extends ToolbarScene return false; } - EhApplication.getDownloadManager(context).moveLabel(fromPosition - 1, toPosition - 1); + EhApplication.getDownloadManager().moveLabel(fromPosition - 1, toPosition - 1); final String item = mLabels.remove(fromPosition); mLabels.add(toPosition, item); mLabelAdapter.notifyDataSetChanged(); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java index f1fa4077c..ab747c57c 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java @@ -188,7 +188,7 @@ public class FavoritesScene extends BaseScene implements Context context = getContext(); AssertUtils.assertNotNull(context); - mClient = EhApplication.getEhClient(context); + mClient = EhApplication.getEhClient(); mFavCatArray = Settings.getFavCat(); mFavCountArray = Settings.getFavCount(); mFavLocalCount = Settings.getFavLocalCount(); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java index 818acc3ae..5bab0ff94 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java @@ -85,7 +85,7 @@ abstract class GalleryAdapter extends RecyclerView.Adapter { setType(type); - mDownloadManager = EhApplication.getDownloadManager(inflater.getContext()); + mDownloadManager = EhApplication.getDownloadManager(); } private void adjustPaddings() { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java index 315d08df1..9f51edfff 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java @@ -278,7 +278,7 @@ public final class GalleryCommentsScene extends ToolbarScene .setArgs(mGalleryDetail.apiUid, mGalleryDetail.apiKey, mGalleryDetail.gid, mGalleryDetail.token, id, vote) .setCallback(new VoteCommentListener(context, activity.getStageId(), getTag())); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); } @SuppressLint("InflateParams") @@ -408,7 +408,7 @@ public final class GalleryCommentsScene extends ToolbarScene .setMethod(EhClient.METHOD_GET_GALLERY_DETAIL) .setArgs(url) .setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag())); - EhApplication.getEhClient(activity).execute(request); + EhApplication.getEhClient().execute(request); } } @@ -591,7 +591,7 @@ public final class GalleryCommentsScene extends ToolbarScene .setArgs(url, comment, mCommentId != 0 ? Long.toString(mCommentId) : null) .setCallback(new CommentGalleryListener(context, activity.getStageId(), getTag(), mCommentId)); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); hideSoftInput(); hideEditPanel(true); } @@ -709,7 +709,7 @@ public final class GalleryCommentsScene extends ToolbarScene .setMethod(EhClient.METHOD_GET_GALLERY_DETAIL) .setArgs(url) .setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag())); - EhApplication.getEhClient(activity).execute(request); + EhApplication.getEhClient().execute(request); } } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java index a0be5f3b5..623ad633b 100755 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -555,7 +555,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O if (gid != -1) { Context context = getContext(); AssertUtils.assertNotNull(context); - mDownloadState = EhApplication.getDownloadManager(context).getDownloadState(gid); + mDownloadState = EhApplication.getDownloadManager().getDownloadState(gid); } else { mDownloadState = DownloadInfo.STATE_INVALID; } @@ -663,7 +663,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O adjustViewVisibility(STATE_FAILED, false); } - EhApplication.getDownloadManager(context).addDownloadInfoListener(this); + EhApplication.getDownloadManager().addDownloadInfoListener(this); return view; } @@ -674,7 +674,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O Context context = getContext(); AssertUtils.assertNotNull(context); - EhApplication.getDownloadManager(context).removeDownloadInfoListener(this); + EhApplication.getDownloadManager().removeDownloadInfoListener(this); mTip = null; mViewTransition = null; @@ -737,7 +737,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O } // Get from cache - mGalleryDetail = EhApplication.getGalleryDetailCache(context).get(gid); + mGalleryDetail = EhApplication.getGalleryDetailCache().get(gid); if (mGalleryDetail != null) { return true; } @@ -767,7 +767,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O .setMethod(EhClient.METHOD_GET_GALLERY_DETAIL) .setArgs(url) .setCallback(callback); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); return true; } @@ -878,6 +878,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O Resources resources = getResources(); + mThumb.load(EhCacheKeyFactory.getThumbKey(gd.gid), gd.thumb); setTitle(EhUtils.getSuitableTitle(gd)); mUploader.setText(gd.uploader); mUploader.setAlpha(gd.disowned ? .5f : 1f); @@ -1148,7 +1149,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O } else if (mDownload == v) { GalleryInfo galleryInfo = getGalleryInfo(); if (galleryInfo != null) { - if (EhApplication.getDownloadManager(context).getDownloadState(galleryInfo.gid) == DownloadInfo.STATE_INVALID) { + if (EhApplication.getDownloadManager().getDownloadState(galleryInfo.gid) == DownloadInfo.STATE_INVALID) { CommonOperations.startDownload(activity, galleryInfo, false); } else { CheckBoxDialogBuilder builder = new CheckBoxDialogBuilder(context, @@ -1156,7 +1157,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O getString(R.string.download_remove_dialog_check_text), Settings.getRemoveImageFiles()); DeleteDialogHelper helper = new DeleteDialogHelper( - EhApplication.getDownloadManager(context), galleryInfo, builder); + EhApplication.getDownloadManager(), galleryInfo, builder); builder.setTitle(R.string.download_remove_dialog_title) .setPositiveButton(android.R.string.ok, helper) .show(); @@ -1424,7 +1425,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O .setArgs(mGalleryDetail.apiUid, mGalleryDetail.apiKey, mGalleryDetail.gid, mGalleryDetail.token, tag, vote) .setCallback(new VoteTagListener(context, activity.getStageId(), getTag())); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); } @Override @@ -1527,7 +1528,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O return; } - int downloadState = EhApplication.getDownloadManager(context).getDownloadState(gid); + int downloadState = EhApplication.getDownloadManager().getDownloadState(gid); if (downloadState == mDownloadState) { return; } @@ -1645,7 +1646,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O getApplication().removeGlobalStuff(this); // Put gallery detail to cache - EhApplication.getGalleryDetailCache(getApplication()).put(result.gid, result); + EhApplication.getGalleryDetailCache().put(result.gid, result); // Add history EhDB.putHistoryInfo(result); @@ -1725,7 +1726,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O scene.onRateGallerySuccess(result); } else { // Update rating in cache - GalleryDetail gd = EhApplication.getGalleryDetailCache(getApplication()).get(mGid); + GalleryDetail gd = EhApplication.getGalleryDetailCache().get(mGid); if (gd != null) { gd.rating = result.rating; gd.ratingCount = result.ratingCount; @@ -1854,7 +1855,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O mRequest = new EhRequest().setMethod(EhClient.METHOD_ARCHIVE_LIST) .setArgs(url, mGid, mToken) .setCallback(this); - EhApplication.getEhClient(context).execute(mRequest); + EhApplication.getEhClient().execute(mRequest); } else { bind(mArchiveList); } @@ -1893,7 +1894,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O request.setMethod(EhClient.METHOD_DOWNLOAD_ARCHIVE); request.setArgs(mGalleryDetail.gid, mGalleryDetail.token, mArchiveFormParamOr, res); request.setCallback(new DownloadArchiveListener(context, activity.getStageId(), getTag())); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); } if (mDialog != null) { @@ -1971,7 +1972,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O mRequest = new EhRequest().setMethod(EhClient.METHOD_GET_TORRENT_LIST) .setArgs(url, mGid, mToken) .setCallback(this); - EhApplication.getEhClient(context).execute(mRequest); + EhApplication.getEhClient().execute(mRequest); } else { bind(mTorrentList); } @@ -2012,7 +2013,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O FileUtils.sanitizeFilename(name + ".torrent")); r.allowScanningByMediaScanner(); r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - r.addRequestHeader("Cookie", EhApplication.getEhCookieStore(context).getCookieHeader(HttpUrl.get(url))); + r.addRequestHeader("Cookie", EhApplication.getEhCookieStore().getCookieHeader(HttpUrl.get(url))); DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); if (dm != null) { try { @@ -2107,7 +2108,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O mGalleryDetail.gid, mGalleryDetail.token, mRatingBar.getRating()) .setCallback(new RateGalleryListener(context, activity.getStageId(), getTag(), mGalleryDetail.gid)); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java index e56f3b04b..95c35416d 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java @@ -339,9 +339,9 @@ public final class GalleryListScene extends BaseScene Context context = getContext(); AssertUtils.assertNotNull(context); - mClient = EhApplication.getEhClient(context); - mDownloadManager = EhApplication.getDownloadManager(context); - mFavouriteStatusRouter = EhApplication.getFavouriteStatusRouter(context); + mClient = EhApplication.getEhClient(); + mDownloadManager = EhApplication.getDownloadManager(); + mFavouriteStatusRouter = EhApplication.getFavouriteStatusRouter(); mDownloadInfoListener = new DownloadManager.DownloadInfoListener() { @Override @@ -1030,7 +1030,7 @@ public final class GalleryListScene extends BaseScene } break; case 3: // Move - List labelRawList = EhApplication.getDownloadManager(context).getLabelList(); + List labelRawList = EhApplication.getDownloadManager().getLabelList(); List labelList = new ArrayList<>(labelRawList.size() + 1); labelList.add(getString(R.string.default_download_label_name)); for (int i = 0, n = labelRawList.size(); i < n; i++) { @@ -1571,7 +1571,7 @@ public final class GalleryListScene extends BaseScene mRecyclerView.outOfCustomChoiceMode(); } - DownloadManager downloadManager = EhApplication.getDownloadManager(context); + DownloadManager downloadManager = EhApplication.getDownloadManager(); DownloadInfo downloadInfo = downloadManager.getDownloadInfo(mGi.gid); if (downloadInfo == null) { return; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java index 3d3d93f7b..0e0134b98 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java @@ -96,7 +96,7 @@ public class GalleryPreviewsScene extends ToolbarScene { Context context = getContext(); AssertUtils.assertNotNull(context); - mClient = EhApplication.getEhClient(context); + mClient = EhApplication.getEhClient(); if (savedInstanceState == null) { onInit(); } else { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.kt index d7b3bd573..38a0eb269 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.kt @@ -72,9 +72,7 @@ class HistoryScene : ToolbarScene() { } }) } - private val mDownloadManager: DownloadManager by lazy { - EhApplication.getDownloadManager(requireContext()) - } + private val mDownloadManager = EhApplication.downloadManager private val mDownloadInfoListener: DownloadInfoListener by lazy { object : DownloadInfoListener { override fun onAdd(info: DownloadInfo, list: List, position: Int) { @@ -99,9 +97,7 @@ class HistoryScene : ToolbarScene() { override fun onUpdateLabels() {} } } - private val mFavouriteStatusRouter: FavouriteStatusRouter by lazy { - EhApplication.getFavouriteStatusRouter(requireContext()) - } + private val mFavouriteStatusRouter = EhApplication.favouriteStatusRouter private val mFavouriteStatusRouterListener: FavouriteStatusRouter.Listener by lazy { FavouriteStatusRouter.Listener { _: Long, _: Int -> mAdapter.notifyDataSetChanged() @@ -302,7 +298,7 @@ class HistoryScene : ToolbarScene() { } 3 -> { - val labelRawList = EhApplication.getDownloadManager(context).labelList + val labelRawList = EhApplication.downloadManager.labelList val labelList: MutableList = ArrayList(labelRawList.size + 1) labelList.add(getString(R.string.default_download_label_name)) var i = 0 @@ -373,7 +369,7 @@ class HistoryScene : ToolbarScene() { private val mGi: GalleryInfo ) : DialogInterface.OnClickListener { override fun onClick(dialog: DialogInterface, which: Int) { - val downloadManager = EhApplication.getDownloadManager(requireContext()) + val downloadManager = EhApplication.downloadManager val downloadInfo = downloadManager.getDownloadInfo(mGi.gid) ?: return val label = if (which == 0) null else mLabels[which] downloadManager.changeLabel(listOf(downloadInfo), label) diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/ProgressScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/ProgressScene.java index de03f75db..35aec633f 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/ProgressScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/ProgressScene.java @@ -99,7 +99,7 @@ public final class ProgressScene extends BaseScene implements View.OnClickListen .setArgs(mGid, mPToken, mPage) .setCallback(new GetGalleryTokenListener(context, activity.getStageId(), getTag())); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); return true; } return false; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SelectSiteScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/SelectSiteScene.java index de00b9b47..d33f68438 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SelectSiteScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/SelectSiteScene.java @@ -50,7 +50,7 @@ public class SelectSiteScene extends SolidScene implements View.OnClickListener View view = inflater.inflate(R.layout.scene_select_site, container, false); mButtonGroup = (MaterialButtonToggleGroup) ViewUtils.$$(view, R.id.button_group); - if (EhApplication.getEhCookieStore(requireContext()).hasSignedIn()) { + if (EhApplication.getEhCookieStore().hasSignedIn()) { ((MaterialButton) view.findViewById(R.id.site_ex)).setChecked(true); } else { ((MaterialButton) view.findViewById(R.id.site_e)).setChecked(true); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java index 2ca6da18b..c2ffa0dc3 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java @@ -289,7 +289,7 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc .setMethod(EhClient.METHOD_SIGN_IN) .setArgs(username, password) .setCallback(callback); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); mSigningIn = true; } @@ -310,7 +310,7 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc EhRequest request = new EhRequest() .setMethod(EhClient.METHOD_GET_PROFILE) .setCallback(callback); - EhApplication.getEhClient(context).execute(request); + EhApplication.getEhClient().execute(request); } private void redirectTo() { @@ -341,7 +341,7 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc return; } - if (EhApplication.getEhCookieStore(context).hasSignedIn()) { + if (EhApplication.getEhCookieStore().hasSignedIn()) { getProfile(); } else { mSigningIn = false; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewSignInScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewSignInScene.java index 1fce4f994..f141b9ef6 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewSignInScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewSignInScene.java @@ -118,7 +118,7 @@ public class WebViewSignInScene extends SolidScene { } private void addCookie(Context context, String domain, Cookie cookie) { - EhApplication.getEhCookieStore(context).addCookie(EhCookieStore.newCookie(cookie, domain, true, true, true)); + EhApplication.getEhCookieStore().addCookie(EhCookieStore.newCookie(cookie, domain, true, true, true)); } @Override diff --git a/app/src/main/java/com/hippo/ehviewer/widget/GalleryInfoContentHelper.kt b/app/src/main/java/com/hippo/ehviewer/widget/GalleryInfoContentHelper.kt index 2b7c33612..9784ea20f 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/GalleryInfoContentHelper.kt +++ b/app/src/main/java/com/hippo/ehviewer/widget/GalleryInfoContentHelper.kt @@ -51,11 +51,11 @@ abstract class GalleryInfoContentHelper : ContentHelper() { info.favoriteSlot = slot } } - EhApplication.getFavouriteStatusRouter().addListener(listener) + EhApplication.favouriteStatusRouter.addListener(listener) } fun destroy() { - EhApplication.getFavouriteStatusRouter().removeListener(listener) + EhApplication.favouriteStatusRouter.removeListener(listener) } override fun onAddData(data: GalleryInfo?) { @@ -100,7 +100,7 @@ abstract class GalleryInfoContentHelper : ContentHelper() { val bundle = super.saveInstanceState(superState) as Bundle // TODO It's a bad design - val router = EhApplication.getFavouriteStatusRouter() + val router = EhApplication.favouriteStatusRouter val id = router.saveDataMap(map) bundle.putInt(KEY_DATA_MAP, id) bundle.putInt(KEY_MIN_GID, minGid) @@ -112,7 +112,7 @@ abstract class GalleryInfoContentHelper : ContentHelper() { val bundle = state as Bundle val id = bundle.getInt(KEY_DATA_MAP, IntIdGenerator.INVALID_ID) if (id != IntIdGenerator.INVALID_ID) { - val router = EhApplication.getFavouriteStatusRouter() + val router = EhApplication.favouriteStatusRouter val map = router.restoreDataMap(id) if (map != null) { this.map = map diff --git a/app/src/main/java/com/hippo/widget/LoadImageView.kt b/app/src/main/java/com/hippo/widget/LoadImageView.kt index e7cd8e7eb..fcc679ca4 100644 --- a/app/src/main/java/com/hippo/widget/LoadImageView.kt +++ b/app/src/main/java/com/hippo/widget/LoadImageView.kt @@ -14,310 +14,207 @@ * limitations under the License. */ -package com.hippo.widget; +package com.hippo.widget -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.graphics.drawable.Animatable; -import android.graphics.drawable.AnimatedImageDrawable; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.TransitionDrawable; -import android.util.AttributeSet; -import android.view.View; +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable +import android.graphics.drawable.TransitionDrawable +import android.util.AttributeSet +import android.view.View +import androidx.annotation.IntDef +import androidx.core.content.ContextCompat +import coil.imageLoader +import coil.request.Disposable +import coil.request.ImageRequest +import com.hippo.drawable.PreciselyClipDrawable +import com.hippo.ehviewer.R -import androidx.annotation.DrawableRes; -import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.core.content.ContextCompat; - -import com.hippo.drawable.PreciselyClipDrawable; -import com.hippo.ehviewer.R; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import coil.Coil; -import coil.request.Disposable; -import coil.request.ImageRequest; - -public class LoadImageView extends FixedAspectImageView implements View.OnClickListener, View.OnLongClickListener, Animatable { - - public static final int RETRY_TYPE_NONE = 0; - public static final int RETRY_TYPE_CLICK = 1; - public static final int RETRY_TYPE_LONG_CLICK = 2; - private static final String TAG = LoadImageView.class.getSimpleName(); - private String mKey; - private String mUrl; - private boolean mUseNetwork; - private int mOffsetX = Integer.MIN_VALUE; - private int mOffsetY = Integer.MIN_VALUE; - private int mClipWidth = Integer.MIN_VALUE; - private int mClipHeight = Integer.MIN_VALUE; - private int mRetryType; - private boolean mFailed; - private boolean mLoadFromDrawable = false; - - private Disposable task = null; - - public LoadImageView(Context context) { - super(context); - init(context, null, 0); - } - - public LoadImageView(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs, 0); - } - - public LoadImageView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(context, attrs, defStyle); - } - - private void init(Context context, AttributeSet attrs, int defStyleAttr) { - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LoadImageView, defStyleAttr, 0); - setRetryType(a.getInt(R.styleable.LoadImageView_retryType, 0)); - a.recycle(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - - if (!mLoadFromDrawable) { - if (mFailed) { - onFailure(); - } else if (task != null && task.isDisposed()) { - load(mKey, mUrl, mUseNetwork); +open class LoadImageView @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : FixedAspectImageView(context, attrs, defStyleAttr), View.OnClickListener, + View.OnLongClickListener { + private var mRequest: ImageRequest? = null + private var mOffsetX = Integer.MIN_VALUE + private var mOffsetY = Integer.MIN_VALUE + private var mClipWidth = Integer.MIN_VALUE + private var mClipHeight = Integer.MIN_VALUE + private var mRetryType: Int = 0 + private var mFailed: Boolean = false + private var task: Disposable? = null + private val imageDrawable: Drawable? + get() { + var drawable = drawable + if (drawable is TransitionDrawable) { + if (drawable.numberOfLayers == 2) { + drawable = drawable.getDrawable(1) + } } - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - - if (!mLoadFromDrawable) { - if (task != null && !task.isDisposed()) { - // Cancel - task.dispose(); - // Clear drawable - clearDrawable(); + if (drawable is PreciselyClipDrawable) { + drawable = drawable.wrappedDrawable } + return drawable } + + init { + val a = context.obtainStyledAttributes(attrs, R.styleable.LoadImageView, defStyleAttr, 0) + setRetryType(a.getInt(R.styleable.LoadImageView_retryType, 0)) + a.recycle() } - private Drawable getImageDrawable() { - Drawable drawable = getDrawable(); - if (drawable instanceof TransitionDrawable transitionDrawable) { - if (transitionDrawable.getNumberOfLayers() == 2) { - drawable = transitionDrawable.getDrawable(1); - } - } - if (drawable instanceof PreciselyClipDrawable) { - drawable = ((PreciselyClipDrawable) drawable).getWrappedDrawable(); - } - return drawable; + override fun onAttachedToWindow() { + super.onAttachedToWindow() + if (mFailed) onFailure() + else task?.run { if (isDisposed) reload() } } - private void clearDrawable() { - // Set drawable null - setImageDrawable(null); + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + task?.run { if (!isDisposed) dispose() } + clearDrawable() } - private void clearRetry() { + private fun clearDrawable() { + setImageDrawable(null) + } + + private fun clearRetry() { if (mRetryType == RETRY_TYPE_CLICK) { - setOnClickListener(null); - setClickable(false); + setOnClickListener(null) + isClickable = false } else if (mRetryType == RETRY_TYPE_LONG_CLICK) { - setOnLongClickListener(null); - setLongClickable(false); + setOnLongClickListener(null) + isLongClickable = false } } - public void setRetryType(@RetryType int retryType) { + private fun setRetryType(@RetryType retryType: Int) { if (mRetryType != retryType) { - int oldRetryType = mRetryType; - mRetryType = retryType; + val oldRetryType = mRetryType + mRetryType = retryType if (mFailed) { if (oldRetryType == RETRY_TYPE_CLICK) { - setOnClickListener(null); - setClickable(false); + setOnClickListener(null) + isClickable = false } else if (oldRetryType == RETRY_TYPE_LONG_CLICK) { - setOnLongClickListener(null); - setLongClickable(false); + setOnLongClickListener(null) + isLongClickable = false } if (retryType == RETRY_TYPE_CLICK) { - setOnClickListener(this); + setOnClickListener(this) } else if (retryType == RETRY_TYPE_LONG_CLICK) { - setOnLongClickListener(this); + setOnLongClickListener(this) } } } } - public void setClip(int offsetX, int offsetY, int clipWidth, int clipHeight) { - mOffsetX = offsetX; - mOffsetY = offsetY; - mClipWidth = clipWidth; - mClipHeight = clipHeight; + fun setClip(offsetX: Int, offsetY: Int, clipWidth: Int, clipHeight: Int) { + mOffsetX = offsetX + mOffsetY = offsetY + mClipWidth = clipWidth + mClipHeight = clipHeight } - public void resetClip() { - mOffsetX = Integer.MIN_VALUE; - mOffsetY = Integer.MIN_VALUE; - mClipWidth = Integer.MIN_VALUE; - mClipHeight = Integer.MIN_VALUE; + fun resetClip() { + mOffsetX = Integer.MIN_VALUE + mOffsetY = Integer.MIN_VALUE + mClipWidth = Integer.MIN_VALUE + mClipHeight = Integer.MIN_VALUE } - public void load(String key, String url) { - load(key, url, true); + fun load(key: String, url: String) { + if ((mRequest?.data as? String?) == url) + return + mFailed = false + clearRetry() + mRequest = + ImageRequest.Builder(context).data(url).memoryCacheKey(key).diskCacheKey(key).target( + { onWait() }, + { onFailure() }, + { onGetValue(it) } + ).build().also { load(it) } } - public void load(String key, String url, boolean useNetwork) { - if (url == null || (key == null)) { - return; - } - - mFailed = false; - clearRetry(); - - mKey = key; - mUrl = url; - mUseNetwork = useNetwork; - - var imageLoader = Coil.imageLoader(getContext()); - var request = new ImageRequest.Builder(getContext()).data(url).memoryCacheKey(key).diskCacheKey(key).target( - drawable -> { - onWait(); - return null; - }, - drawable -> { - onFailure(); - return null; - }, - drawable -> { - onGetValue(drawable); - return null; - } - ).build(); - task = imageLoader.enqueue(request); + fun load(request: ImageRequest) { + task = context.imageLoader.enqueue(request) } - public void load(Drawable drawable) { - unload(); - onPreSetImageDrawable(drawable, true); - setImageDrawable(drawable); + private fun reload() { + mRequest?.let { load(it) } } - public void load(@DrawableRes int id) { - unload(); - mLoadFromDrawable = true; - onPreSetImageResource(id, true); - setImageResource(id); + + private fun onWait() { + mFailed = false + clearDrawable() } - public void unload() { - task.dispose(); - mKey = null; - mUrl = null; - clearDrawable(); - } - - public void onWait() { - clearDrawable(); - } - - public void onGetValue(Drawable drawable) { - clearDrawable(); + private fun onGetValue(drawable: Drawable) { + var drawable = drawable + clearDrawable() if (Integer.MIN_VALUE != mOffsetX) { - drawable = new PreciselyClipDrawable(drawable, mOffsetX, mOffsetY, mClipWidth, mClipHeight); + drawable = PreciselyClipDrawable(drawable, mOffsetX, mOffsetY, mClipWidth, mClipHeight) } - onPreSetImageDrawable(drawable, true); - if (isShown()) { - Drawable[] layers = new Drawable[2]; - layers[0] = new ColorDrawable(Color.TRANSPARENT); - layers[1] = drawable; - TransitionDrawable transitionDrawable = new TransitionDrawable(layers); - setImageDrawable(transitionDrawable); - transitionDrawable.startTransition(300); + onPreSetImageDrawable(drawable, true) + if (isShown) { + val layers = arrayOfNulls(2) + layers[0] = ColorDrawable(Color.TRANSPARENT) + layers[1] = drawable + val transitionDrawable = TransitionDrawable(layers) + setImageDrawable(transitionDrawable) + transitionDrawable.startTransition(300) } else { - setImageDrawable(drawable); + setImageDrawable(drawable) } } - public void onFailure() { - mFailed = true; - clearDrawable(); - Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.image_failed); - onPreSetImageDrawable(drawable, true); - setImageDrawable(drawable); - if (mRetryType == RETRY_TYPE_CLICK) { - setOnClickListener(this); - } else if (mRetryType == RETRY_TYPE_LONG_CLICK) { - setOnLongClickListener(this); - } else { - // Can't retry, so release - mKey = null; - mUrl = null; + fun onFailure() { + mFailed = true + clearDrawable() + val drawable = ContextCompat.getDrawable(context, R.drawable.image_failed) + onPreSetImageDrawable(drawable, true) + setImageDrawable(drawable) + when (mRetryType) { + RETRY_TYPE_CLICK -> { + setOnClickListener(this) + } + + RETRY_TYPE_LONG_CLICK -> { + setOnLongClickListener(this) + } + + else -> { + mRequest = null + } } } - public void onCancel() { - mFailed = false; + override fun onClick(v: View) { + reload() } - @Override - public void start() { - Drawable drawable = getImageDrawable(); - if (drawable instanceof AnimatedImageDrawable animatedImageDrawable) { - animatedImageDrawable.start(); - } + override fun onLongClick(v: View): Boolean { + reload() + return true } - @Override - public void stop() { - Drawable drawable = getImageDrawable(); - if (drawable instanceof AnimatedImageDrawable animatedImageDrawable) { - animatedImageDrawable.stop(); - } - } + open fun onPreSetImageDrawable(drawable: Drawable?, isTarget: Boolean) {} - @Override - public boolean isRunning() { - Drawable drawable = getImageDrawable(); - if (drawable instanceof AnimatedImageDrawable animatedImageDrawable) { - return animatedImageDrawable.isRunning(); - } else { - return false; - } - } + open fun onPreSetImageResource(resId: Int, isTarget: Boolean) {} - @Override - public void onClick(@NonNull View v) { - load(mKey, mUrl, true); - } + @IntDef(RETRY_TYPE_NONE, RETRY_TYPE_CLICK, RETRY_TYPE_LONG_CLICK) + @Retention(AnnotationRetention.SOURCE) + private annotation class RetryType - @Override - public boolean onLongClick(@NonNull View v) { - load(mKey, mUrl, true); - return true; - } - - public void onPreSetImageDrawable(Drawable drawable, boolean isTarget) { - } - - public void onPreSetImageResource(int resId, boolean isTarget) { - } - - @IntDef({RETRY_TYPE_NONE, RETRY_TYPE_CLICK, RETRY_TYPE_LONG_CLICK}) - @Retention(RetentionPolicy.SOURCE) - private @interface RetryType { + companion object { + const val RETRY_TYPE_NONE = 0 + const val RETRY_TYPE_CLICK = 1 + const val RETRY_TYPE_LONG_CLICK = 2 } }