Java tutorial
/* * Copyright 2016 Hippo Seven * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hippo.ehviewer; import android.app.Activity; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Debug; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.util.LruCache; import android.util.Log; import com.hippo.beerbelly.SimpleDiskCache; import com.hippo.conaco.Conaco; import com.hippo.ehviewer.client.EhClient; import com.hippo.ehviewer.client.EhCookieStore; import com.hippo.ehviewer.client.EhEngine; import com.hippo.ehviewer.client.EhUrl; import com.hippo.ehviewer.client.data.GalleryDetail; import com.hippo.ehviewer.download.DownloadManager; import com.hippo.ehviewer.spider.SpiderDen; import com.hippo.ehviewer.ui.CommonOperations; import com.hippo.image.Image; import com.hippo.image.ImageBitmap; import com.hippo.network.StatusCodeException; import com.hippo.okhttp.CookieDB; import com.hippo.scene.SceneApplication; import com.hippo.text.Html; import com.hippo.unifile.UniFile; import com.hippo.util.BitmapUtils; 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.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.WeakHashMap; import java.util.concurrent.TimeUnit; import okhttp3.Cookie; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; public class EhApplication extends SceneApplication implements Thread.UncaughtExceptionHandler { private static final String TAG = EhApplication.class.getSimpleName(); public static final boolean BETA = false; 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; private Thread.UncaughtExceptionHandler mDefaultHandler; private final IntIdGenerator mIdGenerator = new IntIdGenerator(); private final WeakHashMap<Integer, Object> mGlobalStuffMap = new WeakHashMap<>(); private EhCookieStore mEhCookieStore; private EhClient mEhClient; private OkHttpClient mOkHttpClient; private ImageBitmapHelper mImageBitmapHelper; private Conaco<ImageBitmap> mConaco; private LruCache<Long, GalleryDetail> mGalleryDetailCache; private SimpleDiskCache mSpiderInfoCache; private DownloadManager mDownloadManager; private final List<Activity> mActivityList = new ArrayList<>(); @Override public void onCreate() { // Prepare to catch crash mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); super.onCreate(); GetText.initialize(this); CookieDB.initialize(this); StatusCodeException.initialize(this); Settings.initialize(this); ReadableTime.initialize(this); Html.initialize(this); AppConfig.initialize(this); SpiderDen.initialize(this); EhDB.initialize(this); EhEngine.initialize(); BitmapUtils.initialize(this); if (EhDB.needMerge()) { EhDB.mergeOldDB(this); } if (Settings.getEnableAnalytics()) { Analytics.start(this); } // Check no media file UniFile downloadLocation = Settings.getDownloadLocation(); if (Settings.getMediaScan()) { CommonOperations.removeNoMediaFile(downloadLocation); } else { CommonOperations.ensureNoMediaFile(downloadLocation); } // Clear temp dir clearTempDir(); // Check app update update(); // Update version code try { PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0); Settings.putVersionCode(pi.versionCode); } catch (PackageManager.NameNotFoundException e) { // Ignore } if (DEBUG_PRINT_NATIVE_MEMORY || DEBUG_PRINT_IMAGE_COUNT) { debugPrint(); } } 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); } if (version < 56) { // Make cookie long live HttpUrl eUrl = HttpUrl.parse(EhUrl.HOST_E); HttpUrl exUrl = HttpUrl.parse(EhUrl.HOST_EX); EhCookieStore cookieStore = getEhCookieStore(this); Cookie c; c = cookieStore.get(eUrl, EhCookieStore.KEY_IPD_MEMBER_ID); if (null != c) { cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true)); } c = cookieStore.get(eUrl, EhCookieStore.KEY_IPD_PASS_HASH); if (null != c) { cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true)); } c = cookieStore.get(exUrl, EhCookieStore.KEY_IPD_MEMBER_ID); if (null != c) { cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true)); } c = cookieStore.get(exUrl, EhCookieStore.KEY_IPD_PASS_HASH); if (null != c) { cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true)); } } } public void clearMemoryCache() { if (null != mConaco) { mConaco.getBeerBelly().clearMemory(); } 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)); } if (DEBUG_PRINT_IMAGE_COUNT) { Log.i(TAG, "Image count: " + Image.getImageCount()); } SimpleHandler.getInstance().postDelayed(this, DEBUG_PRINT_INTERVAL); } }.run(); } public int putGlobalStuff(@NonNull Object o) { int id = mIdGenerator.nextId(); mGlobalStuffMap.put(id, o); 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 boolean removeGlobalStuff(Object o) { return mGlobalStuffMap.values().removeAll(Collections.singleton(o)); } public static EhCookieStore getEhCookieStore(@NonNull Context context) { EhApplication application = ((EhApplication) context.getApplicationContext()); if (application.mEhCookieStore == null) { application.mEhCookieStore = new EhCookieStore(); } 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 OkHttpClient getOkHttpClient(@NonNull Context context) { EhApplication application = ((EhApplication) context.getApplicationContext()); if (application.mOkHttpClient == null) { application.mOkHttpClient = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS) .cookieJar(getEhCookieStore(application)).build(); } return application.mOkHttpClient; } @NonNull public static ImageBitmapHelper getImageBitmapHelper(@NonNull Context context) { EhApplication application = ((EhApplication) context.getApplicationContext()); if (application.mImageBitmapHelper == null) { application.mImageBitmapHelper = new ImageBitmapHelper(); } return application.mImageBitmapHelper; } private static int getMemoryCacheMaxSize() { return Math.min(20 * 1024 * 1024, (int) OSUtils.getAppMaxMemory()); } @NonNull public static Conaco<ImageBitmap> getConaco(@NonNull Context context) { EhApplication application = ((EhApplication) context.getApplicationContext()); if (application.mConaco == null) { Conaco.Builder<ImageBitmap> builder = new Conaco.Builder<>(); builder.hasMemoryCache = true; builder.memoryCacheMaxSize = getMemoryCacheMaxSize(); builder.hasDiskCache = true; builder.diskCacheDir = new File(context.getCacheDir(), "thumb"); builder.diskCacheMaxSize = 80 * 1024 * 1024; // 80MB builder.okHttpClient = getOkHttpClient(context); builder.objectHelper = getImageBitmapHelper(context); builder.debug = DEBUG_CONACO; application.mConaco = builder.build(); } return application.mConaco; } @NonNull public static LruCache<Long, GalleryDetail> getGalleryDetailCache(@NonNull Context context) { EhApplication application = ((EhApplication) context.getApplicationContext()); if (application.mGalleryDetailCache == null) { // Max size 25, 3 min timeout application.mGalleryDetailCache = new LruCache<>(25); } 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"), 5 * 1024 * 1024); // 5M } return application.mSpiderInfoCache; } @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; } private boolean handleException(Throwable ex) { if (ex == null) { return false; } try { ex.printStackTrace(); Crash.saveCrashInfo2File(this, ex); return true; } catch (Throwable tr) { return false; } } @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } Activity activity = getTopActivity(); if (activity != null) { activity.finish(); } android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } @NonNull public static String getDeveloperEmail() { return "ehviewersu$gmail.com".replace('$', '@'); } public void registerActivity(Activity activity) { mActivityList.add(activity); } public void unregisterActivity(Activity activity) { mActivityList.remove(activity); } @Nullable public Activity getTopActivity() { if (!mActivityList.isEmpty()) { return mActivityList.get(mActivityList.size() - 1); } else { return null; } } }