[android] add: Application background transition tracker.

This commit is contained in:
Alexander Marchuk 2015-12-03 19:34:57 +03:00 committed by Constantin Shalnev
parent 6043e081ec
commit a4e6c5ccd8
4 changed files with 152 additions and 16 deletions

View file

@ -9,9 +9,12 @@ import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import java.io.File;
import com.google.gson.Gson;
import com.mapswithme.country.ActiveCountryTree;
import com.mapswithme.country.CountryItem;
import com.mapswithme.maps.background.AppBackgroundTracker;
import com.mapswithme.maps.background.Notifier;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import com.mapswithme.maps.sound.TtsPlayer;
@ -26,8 +29,6 @@ import com.parse.ParseException;
import com.parse.ParseInstallation;
import com.parse.SaveCallback;
import java.io.File;
public class MwmApplication extends Application
implements ActiveCountryTree.ActiveCountryListener
{
@ -38,14 +39,15 @@ public class MwmApplication extends Application
private static final String PREF_PARSE_INSTALLATION_ID = "ParseInstallationId";
private static MwmApplication sSelf;
private static SharedPreferences sPrefs;
private SharedPreferences mPrefs;
private AppBackgroundTracker mBackgroundTracker;
private final Gson mGson = new Gson();
private boolean mAreCountersInitialized;
private boolean mIsFrameworkInitialized;
private Handler mMainLoopHandler;
private Object mMainQueueToken = new Object();
private final Object mMainQueueToken = new Object();
public MwmApplication()
{
@ -63,9 +65,14 @@ public class MwmApplication extends Application
return sSelf.mGson;
}
public static AppBackgroundTracker backgroundTracker()
{
return sSelf.mBackgroundTracker;
}
public static SharedPreferences prefs()
{
return sPrefs;
return sSelf.mPrefs;
}
@Override
@ -105,7 +112,8 @@ public class MwmApplication extends Application
BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE,
Yota.isFirstYota(), UiUtils.isSmallTablet() || UiUtils.isBigTablet());
initParse();
sPrefs = getSharedPreferences(getString(R.string.pref_file_name), MODE_PRIVATE);
mPrefs = getSharedPreferences(getString(R.string.pref_file_name), MODE_PRIVATE);
mBackgroundTracker = new AppBackgroundTracker();
}
public void initNativeCore()
@ -151,6 +159,11 @@ public class MwmApplication extends Application
nativeAddLocalization("routing_failed_internal_error", getString(R.string.routing_failed_internal_error));
}
public boolean isFrameworkInitialized()
{
return mIsFrameworkInitialized;
}
public String getApkPath()
{
try
@ -163,7 +176,7 @@ public class MwmApplication extends Application
}
}
public String getDataStoragePath()
public static String getDataStoragePath()
{
return Environment.getExternalStorageDirectory().getAbsolutePath() + Constants.MWM_DIR_POSTFIX;
}
@ -178,7 +191,7 @@ public class MwmApplication extends Application
String.format(Constants.STORAGE_PATH, BuildConfig.APPLICATION_ID, Constants.CACHE_DIR);
}
private String getObbGooglePath()
private static String getObbGooglePath()
{
final String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
return storagePath.concat(String.format(Constants.OBB_PATH, BuildConfig.APPLICATION_ID));
@ -245,7 +258,7 @@ public class MwmApplication extends Application
}
}
public void onUpgrade()
public static void onUpgrade()
{
Config.resetAppSessionCounters();
}

View file

@ -0,0 +1,119 @@
package com.mapswithme.maps.background;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.SparseArray;
import java.lang.ref.WeakReference;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.util.Listeners;
import com.mapswithme.util.concurrency.UiThread;
/**
* Helper class that detects when the application goes to background and back to foreground.
* <br/>Must be created as early as possible, i.e. in Application.Create().
*/
public final class AppBackgroundTracker
{
private static final int TRANSITION_DELAY = 3000;
private final Listeners<OnTransitionListener> mListeners = new Listeners<>();
private SparseArray<WeakReference<Activity>> mActivities = new SparseArray<>();
private boolean mForeground;
private final Runnable mTransitionProc = new Runnable()
{
@Override
public void run()
{
SparseArray<WeakReference<Activity>> newArray = new SparseArray<>();
for (int i = 0; i < mActivities.size(); i++)
{
int key = mActivities.keyAt(i);
WeakReference<Activity> ref = mActivities.get(key);
if (ref.get() != null)
newArray.put(key, ref);
}
mActivities = newArray;
boolean old = mForeground;
mForeground = (mActivities.size() > 0);
if (mForeground != old)
notifyListeners();
}
};
/** @noinspection FieldCanBeLocal*/
private final Application.ActivityLifecycleCallbacks mAppLifecycleCallbacks = new Application.ActivityLifecycleCallbacks()
{
private void onActivityChanged()
{
UiThread.cancelDelayedTasks(mTransitionProc);
UiThread.runLater(mTransitionProc, TRANSITION_DELAY);
}
@Override
public void onActivityStarted(Activity activity)
{
mActivities.put(activity.hashCode(), new WeakReference<>(activity));
onActivityChanged();
}
@Override
public void onActivityStopped(Activity activity)
{
mActivities.remove(activity.hashCode());
onActivityChanged();
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivityDestroyed(Activity activity) {}
@Override
public void onActivityResumed(Activity activity) {}
@Override
public void onActivityPaused(Activity activity) {}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
};
public interface OnTransitionListener
{
void onTransit(boolean foreground);
}
public AppBackgroundTracker()
{
MwmApplication.get().registerActivityLifecycleCallbacks(mAppLifecycleCallbacks);
}
public boolean isForeground()
{
return mForeground;
}
private void notifyListeners()
{
for (OnTransitionListener listener: mListeners)
listener.onTransit(mForeground);
mListeners.finishIterate();
}
public void addListener(OnTransitionListener listener)
{
mListeners.register(listener);
}
public void removeListener(OnTransitionListener listener)
{
mListeners.unregister(listener);
}
}

View file

@ -11,6 +11,6 @@ public class UpgradeReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)
{
MwmApplication.get().onUpgrade();
MwmApplication.onUpgrade();
}
}

View file

@ -21,16 +21,20 @@ import android.util.Log;
import android.view.Window;
import android.widget.Toast;
import java.io.Closeable;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import com.mapswithme.maps.BuildConfig;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.activity.CustomNavigateUpListener;
import com.mapswithme.util.statistics.AlohaHelper;
import java.io.*;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class Utils
{
private static final String TAG = "Utils";
@ -182,7 +186,7 @@ public class Utils
*/
public static String saveLogToFile()
{
String fullName = MwmApplication.get().getDataStoragePath() + "log.txt";
String fullName = MwmApplication.getDataStoragePath() + "log.txt";
File file = new File(fullName);
InputStreamReader reader = null;
FileWriter writer = null;