package me.wcy.music.application;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.util.LongSparseArray;
import android.util.Log;
import com.amap.api.location.AMapLocalWeatherLive;
import java.util.ArrayList;
import java.util.List;
import me.wcy.music.executor.DownloadMusicInfo;
import me.wcy.music.model.Music;
import me.wcy.music.model.SheetInfo;
import me.wcy.music.utils.CoverLoader;
import me.wcy.music.storage.preference.Preferences;
import me.wcy.music.utils.ScreenUtils;
import me.wcy.music.utils.ToastUtils;
public class AppCache {
private Context mContext;
private final List<Music> mLocalMusicList = new ArrayList<>();
private final List<SheetInfo> mSheetList = new ArrayList<>();
private final List<Activity> mActivityStack = new ArrayList<>();
private final LongSparseArray<DownloadMusicInfo> mDownloadList = new LongSparseArray<>();
private AMapLocalWeatherLive mAMapLocalWeatherLive;
private AppCache() {
}
private static class SingletonHolder {
private static AppCache instance = new AppCache();
}
public static AppCache get() {
return SingletonHolder.instance;
}
public void init(Application application) {
mContext = application.getApplicationContext();
ToastUtils.init(mContext);
Preferences.init(mContext);
ScreenUtils.init(mContext);
CrashHandler.getInstance().init();
CoverLoader.get().init(mContext);
application.registerActivityLifecycleCallbacks(new ActivityLifecycle());
}
public Context getContext() {
return mContext;
}
public List<Music> getLocalMusicList() {
return mLocalMusicList;
}
public List<SheetInfo> getSheetList() {
return mSheetList;
}
public void clearStack() {
List<Activity> activityStack = mActivityStack;
for (int i = activityStack.size() - 1; i >= 0; i--) {
Activity activity = activityStack.get(i);
if (!activity.isFinishing()) {
activity.finish();
}
}
activityStack.clear();
}
public LongSparseArray<DownloadMusicInfo> getDownloadList() {
return mDownloadList;
}
public AMapLocalWeatherLive getAMapLocalWeatherLive() {
return mAMapLocalWeatherLive;
}
public void setAMapLocalWeatherLive(AMapLocalWeatherLive aMapLocalWeatherLive) {
mAMapLocalWeatherLive = aMapLocalWeatherLive;
}
private class ActivityLifecycle implements Application.ActivityLifecycleCallbacks {
private static final String TAG = "Activity";
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i(TAG, "onCreate: " + activity.getClass().getSimpleName());
mActivityStack.add(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.i(TAG, "onDestroy: " + activity.getClass().getSimpleName());
mActivityStack.remove(activity);
}
}
}
package me.wcy.music.application;
import android.os.Build;
import android.util.Log;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import me.wcy.music.BuildConfig;
import me.wcy.music.utils.FileUtils;
/**
* 异常捕获
* Created by hzwangchenyan on 2016/1/25.
*/
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.getDefault());
private Thread.UncaughtExceptionHandler mDefaultHandler;
public static CrashHandler getInstance() {
return SingletonHolder.instance;
}
private static class SingletonHolder {
private static CrashHandler instance = new CrashHandler();
}
public void init() {
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
saveCrashInfo(ex);
mDefaultHandler.uncaughtException(thread, ex);
}
private void saveCrashInfo(Throwable ex) {
String stackTrace = Log.getStackTraceString(ex);
String filePath = FileUtils.getLogDir() + "crash.log";
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(filePath, true));
bw.write("*** crash ***\n");
bw.write(getInfo());
bw.write(stackTrace);
bw.newLine();
bw.newLine();
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private String getInfo() {
String time = TIME_FORMAT.format(new Date());
String version = BuildConfig.VERSION_NAME + "/" + BuildConfig.VERSION_CODE;
String device = Build.MANUFACTURER + "/" + Build.MODEL + "/" + Build.VERSION.RELEASE;
StringBuilder sb = new StringBuilder();
sb.append("*** time: ").append(time).append(" ***").append("\n");
sb.append("*** version: ").append(version).append(" ***").append("\n");
sb.append("*** device: ").append(device).append(" ***").append("\n");
return sb.toString();
}
}
package me.wcy.music.application;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by hzwangchenyan on 2017/9/20.
*/
public class ForegroundObserver implements Application.ActivityLifecycleCallbacks {
private static final String TAG = "ForegroundObserver";
private static final long CHECK_TASK_DELAY = 500;
private List<Observer> observerList;
private Handler handler;
private boolean isForeground;
private int resumeActivityCount;
public interface Observer {
/**
* 进入前台
*
* @param activity 当前处于栈顶的Activity
*/
void onForeground(Activity activity);
/**
* 进入后台
*
* @param activity 当前处于栈顶的Activity
*/
void onBackground(Activity activity);
}
public static void init(Application application) {
application.registerActivityLifecycleCallbacks(getInstance());
}
private static ForegroundObserver getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static ForegroundObserver sInstance = new ForegroundObserver();
}
private ForegroundObserver() {
observerList = Collections.synchronizedList(new ArrayList<Observer>());
handler = new Handler(Looper.getMainLooper());
}
public static void addObserver(Observer observer) {
if (observer == null) {
return;
}
if (getInstance().observerList.contains(observer)) {
return;
}
getInstance().observerList.add(observer);
}
public static void removeObserver(Observer observer) {
if (observer == null) {
return;
}
getInstance().observerList.remove(observer);
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
resumeActivityCount++;
if (!isForeground && resumeActivityCount > 0) {
isForeground = true;
// 从后台进入前台
Log.i(TAG, "app in foreground");
notify(activity, true);
}
}
@Override
public void onActivityPaused(final Activity activity) {
resumeActivityCount--;
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (isForeground && resumeActivityCount == 0) {
isForeground = false;
// 从前台进入后台
Log.i(TAG, "app in background");
ForegroundObserver.this.notify(activity, false);
}
}
}, CHECK_TASK_DELAY);
}
private void notify(Activity activity, boolean foreground) {
for (Observer observer : observerList) {
if (foreground) {
observer.onForeground(activity);
} else {
observer.onBackground(activity);
}
}
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}