Twidere-App-Android-Twitter.../twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java

303 lines
13 KiB
Java

/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.app;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.multidex.MultiDexApplication;
import android.util.Log;
import com.nostra13.universalimageloader.cache.disc.DiskCache;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.download.ImageDownloader;
import com.nostra13.universalimageloader.utils.L;
import com.squareup.otto.Bus;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.MainActivity;
import org.mariotaku.twidere.activity.MainHondaJOJOActivity;
import org.mariotaku.twidere.service.RefreshService;
import org.mariotaku.twidere.util.AsyncTaskManager;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.MessagesManager;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.VideoLoader;
import org.mariotaku.twidere.util.content.TwidereSQLiteOpenHelper;
import org.mariotaku.twidere.util.imageloader.TwidereImageDownloader;
import org.mariotaku.twidere.util.imageloader.URLFileNameGenerator;
import org.mariotaku.twidere.util.net.TwidereHostAddressResolver;
import java.io.File;
import edu.tsinghua.spice.SpiceService;
import edu.ucdavis.earlybird.UCDService;
import twitter4j.http.HostAddressResolver;
import static org.mariotaku.twidere.util.UserColorNameUtils.initUserColor;
import static org.mariotaku.twidere.util.Utils.getBestCacheDir;
import static org.mariotaku.twidere.util.Utils.getInternalCacheDir;
import static org.mariotaku.twidere.util.Utils.initAccountColor;
import static org.mariotaku.twidere.util.Utils.startRefreshServiceIfNeeded;
import static org.mariotaku.twidere.util.Utils.startUsageStatisticsServiceIfNeeded;
public class TwidereApplication extends MultiDexApplication implements Constants,
OnSharedPreferenceChangeListener {
public static final String KEY_UCD_DATA_PROFILING = "ucd_data_profiling";
public static final String KEY_SPICE_DATA_PROFILING = "spice_data_profiling";
private Handler mHandler;
private MediaLoaderWrapper mMediaLoaderWrapper;
private ImageLoader mImageLoader;
private AsyncTaskManager mAsyncTaskManager;
private SharedPreferences mPreferences;
private AsyncTwitterWrapper mTwitterWrapper;
private MultiSelectManager mMultiSelectManager;
private TwidereImageDownloader mImageDownloader, mFullImageDownloader;
private DiskCache mDiskCache, mFullDiskCache;
private MessagesManager mCroutonsManager;
private SQLiteOpenHelper mSQLiteOpenHelper;
private HostAddressResolver mResolver;
private SQLiteDatabase mDatabase;
private Bus mMessageBus;
private VideoLoader mVideoLoader;
public AsyncTaskManager getAsyncTaskManager() {
if (mAsyncTaskManager != null) return mAsyncTaskManager;
return mAsyncTaskManager = AsyncTaskManager.getInstance();
}
public DiskCache getDiskCache() {
if (mDiskCache != null) return mDiskCache;
return mDiskCache = createDiskCache(DIR_NAME_IMAGE_CACHE);
}
public DiskCache getFullDiskCache() {
if (mFullDiskCache != null) return mFullDiskCache;
return mFullDiskCache = createDiskCache(DIR_NAME_FULL_IMAGE_CACHE);
}
public ImageDownloader getFullImageDownloader() {
if (mFullImageDownloader != null) return mFullImageDownloader;
return mFullImageDownloader = new TwidereImageDownloader(this, true);
}
public Handler getHandler() {
return mHandler;
}
public HostAddressResolver getHostAddressResolver() {
if (mResolver != null) return mResolver;
return mResolver = new TwidereHostAddressResolver(this);
}
public ImageDownloader getImageDownloader() {
if (mImageDownloader != null) return mImageDownloader;
return mImageDownloader = new TwidereImageDownloader(this, false);
}
public ImageLoader getImageLoader() {
if (mImageLoader != null) return mImageLoader;
final ImageLoader loader = ImageLoader.getInstance();
final ImageLoaderConfiguration.Builder cb = new ImageLoaderConfiguration.Builder(this);
cb.threadPriority(Thread.NORM_PRIORITY - 2);
cb.denyCacheImageMultipleSizesInMemory();
cb.tasksProcessingOrder(QueueProcessingType.LIFO);
// cb.memoryCache(new ImageMemoryCache(40));
cb.diskCache(getDiskCache());
cb.imageDownloader(getImageDownloader());
L.writeDebugLogs(Utils.isDebugBuild());
loader.init(cb.build());
return mImageLoader = loader;
}
public VideoLoader getVideoLoader() {
if (mVideoLoader != null) return mVideoLoader;
final VideoLoader loader = new VideoLoader(this);
return mVideoLoader = loader;
}
public MediaLoaderWrapper getImageLoaderWrapper() {
if (mMediaLoaderWrapper != null) return mMediaLoaderWrapper;
return mMediaLoaderWrapper = new MediaLoaderWrapper(getImageLoader(), getVideoLoader());
}
@NonNull
public static TwidereApplication getInstance(@NonNull final Context context) {
return (TwidereApplication) context.getApplicationContext();
}
public Bus getMessageBus() {
return mMessageBus;
}
public MessagesManager getMessagesManager() {
if (mCroutonsManager != null) return mCroutonsManager;
return mCroutonsManager = new MessagesManager(this);
}
public MultiSelectManager getMultiSelectManager() {
if (mMultiSelectManager != null) return mMultiSelectManager;
return mMultiSelectManager = new MultiSelectManager();
}
public SQLiteDatabase getSQLiteDatabase() {
if (mDatabase != null) return mDatabase;
StrictModeUtils.checkDiskIO();
return mDatabase = getSQLiteOpenHelper().getWritableDatabase();
}
public SQLiteOpenHelper getSQLiteOpenHelper() {
if (mSQLiteOpenHelper != null) return mSQLiteOpenHelper;
return mSQLiteOpenHelper = new TwidereSQLiteOpenHelper(this, DATABASES_NAME, DATABASES_VERSION);
}
public AsyncTwitterWrapper getTwitterWrapper() {
if (mTwitterWrapper != null) return mTwitterWrapper;
return mTwitterWrapper = AsyncTwitterWrapper.getInstance(this);
}
@Override
public void onCreate() {
if (Utils.isDebugBuild()) {
StrictModeUtils.detectAllVmPolicy();
}
setTheme(ThemeUtils.getThemeResource(this));
super.onCreate();
mHandler = new Handler();
mMessageBus = new Bus();
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
mPreferences.registerOnSharedPreferenceChangeListener(this);
initializeAsyncTask();
initAccountColor(this);
initUserColor(this);
final PackageManager pm = getPackageManager();
final ComponentName main = new ComponentName(this, MainActivity.class);
final ComponentName main2 = new ComponentName(this, MainHondaJOJOActivity.class);
final boolean mainDisabled = pm.getComponentEnabledSetting(main) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
final boolean main2Disabled = pm.getComponentEnabledSetting(main2) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
final boolean no_entry = mainDisabled && main2Disabled;
if (no_entry) {
pm.setComponentEnabledSetting(main, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
} else if (!mainDisabled) {
pm.setComponentEnabledSetting(main2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
migrateUsageStatisticsPreferences();
startUsageStatisticsServiceIfNeeded(this);
startRefreshServiceIfNeeded(this);
}
private void migrateUsageStatisticsPreferences() {
final boolean hasUsageStatistics = mPreferences.contains(KEY_USAGE_STATISTICS);
final boolean hasUCDDataProfiling = mPreferences.contains(KEY_UCD_DATA_PROFILING);
final boolean hasSpiceDataProfiling = mPreferences.contains(KEY_SPICE_DATA_PROFILING);
Log.d(LOGTAG, String.format("usage: %b, ucd: %b, spice: %b", hasUsageStatistics, hasUCDDataProfiling, hasSpiceDataProfiling));
if (!hasUsageStatistics && (hasUCDDataProfiling || hasSpiceDataProfiling)) {
final boolean prevUsageEnabled = mPreferences.getBoolean(KEY_UCD_DATA_PROFILING, false)
|| mPreferences.getBoolean(KEY_SPICE_DATA_PROFILING, false);
final Editor editor = mPreferences.edit();
editor.putBoolean(KEY_USAGE_STATISTICS, prevUsageEnabled);
editor.remove(KEY_UCD_DATA_PROFILING);
editor.remove(KEY_SPICE_DATA_PROFILING);
editor.apply();
}
}
@Override
public void onLowMemory() {
if (mMediaLoaderWrapper != null) {
mMediaLoaderWrapper.clearMemoryCache();
}
super.onLowMemory();
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
if (KEY_REFRESH_INTERVAL.equals(key)) {
stopService(new Intent(this, RefreshService.class));
startRefreshServiceIfNeeded(this);
} else if (KEY_ENABLE_PROXY.equals(key) || KEY_CONNECTION_TIMEOUT.equals(key) || KEY_PROXY_HOST.equals(key)
|| KEY_PROXY_PORT.equals(key) || KEY_FAST_IMAGE_LOADING.equals(key)) {
reloadConnectivitySettings();
} else if (KEY_USAGE_STATISTICS.equals(key)) {
stopService(new Intent(this, UCDService.class));
startUsageStatisticsServiceIfNeeded(this);
//spice
stopService(new Intent(this, SpiceService.class));
startUsageStatisticsServiceIfNeeded(this);
//end
} else if (KEY_CONSUMER_KEY.equals(key) || KEY_CONSUMER_SECRET.equals(key) || KEY_API_URL_FORMAT.equals(key)
|| KEY_AUTH_TYPE.equals(key) || KEY_SAME_OAUTH_SIGNING_URL.equals(key)) {
final SharedPreferences.Editor editor = preferences.edit();
editor.putLong(KEY_API_LAST_CHANGE, System.currentTimeMillis());
editor.apply();
}
}
public void reloadConnectivitySettings() {
if (mImageDownloader != null) {
mImageDownloader.reloadConnectivitySettings();
}
}
private DiskCache createDiskCache(final String dirName) {
final File cacheDir = getBestCacheDir(this, dirName);
final File fallbackCacheDir = getInternalCacheDir(this, dirName);
// final LruDiscCache discCache = new LruDiscCache(cacheDir, new URLFileNameGenerator(), 384 *
// 1024 * 1024);
// discCache.setReserveCacheDir(fallbackCacheDir);
// return discCache;
return new UnlimitedDiscCache(cacheDir, fallbackCacheDir, new URLFileNameGenerator());
}
private void initializeAsyncTask() {
// AsyncTask class needs to be loaded in UI thread.
// So we load it here to comply the rule.
try {
Class.forName(AsyncTask.class.getName());
} catch (final ClassNotFoundException ignore) {
}
}
}