寫在前面:
最近做項(xiàng)目有一個(gè)鎖屏的功能彻采,需求是:當(dāng)APP從后臺(tái)切到前臺(tái)時(shí),需要打開鎖屏頁(yè)面(5分鐘內(nèi)不鎖屏)
APP前后臺(tái)說(shuō)明
前臺(tái):有一個(gè)或多個(gè)Activity可見
后臺(tái):應(yīng)用內(nèi)所有Activity不可見
兼容性:Android4.0及以上 ActivityLifecycleCallbacks added in [API level 14]
參考 http://blog.csdn.net/goodlixueyong/article/details/50543627
在Activity的onStart和onStop方法中用變量count計(jì)數(shù)慢蜓,在onStart中將變量加1,onStop中減1郭膛。
假設(shè)應(yīng)用有兩個(gè)Activity晨抡,分別為A和B。
情況1则剃,首先啟動(dòng)A耘柱,A再啟動(dòng)B,然后關(guān)掉B:
啟動(dòng)A棍现,count=1调煎;
A啟動(dòng)B,先B.onStart 然后A.onStop己肮,count先加1后減1士袄,count為1。
關(guān)掉B谎僻,先A.onStart 然后B.onStop娄柳,count先加1后減1,count為1
情況2艘绍,首先啟動(dòng)A赤拒,然后按Home鍵返回桌面:
啟動(dòng)A,count=1诱鞠,
按Home鍵返回桌面挎挖,會(huì)執(zhí)行A.onStop,count的計(jì)數(shù)變位0航夺。
以上肋乍,可以通過(guò)對(duì)count的值來(lái)判斷應(yīng)用從前后臺(tái)狀態(tài)。
這篇文章給了我思路敷存,可以通過(guò)Activity計(jì)數(shù)來(lái)實(shí)現(xiàn)前后臺(tái)狀態(tài)的判斷墓造,其它方法都沒有該方法簡(jiǎn)潔高效堪伍。
但是實(shí)踐的時(shí)候發(fā)現(xiàn)只通過(guò)變量計(jì)數(shù)的方法,不能完美解決問題觅闽。
bug1:當(dāng)應(yīng)用第一次啟動(dòng)時(shí)帝雇,仍然會(huì)調(diào)用app從后臺(tái)切到前臺(tái)的方法。(我這里需要屏蔽掉這種情況)
仔細(xì)琢磨發(fā)現(xiàn)可以再加一個(gè)條件進(jìn)行判斷蛉拙,增加一個(gè)最后一次可見的Activity變量(也可以增加一個(gè)后臺(tái)超時(shí)時(shí)間)尸闸,在執(zhí)行onResume方法時(shí)進(jìn)行判斷最后一次可見Activity是否是當(dāng)前可見的Activity,就可以解決以上問題
寫在最后:
因?yàn)轫?xiàng)目需要孕锄,我只實(shí)現(xiàn)了后臺(tái)切換到前臺(tái)的功能吮廉,聰明如你,實(shí)現(xiàn)后臺(tái)切換到前臺(tái)也炒雞簡(jiǎn)單吧
關(guān)鍵代碼:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new AppForeBackStatusCallback());
}
}
public class AppForeBackStatusCallback implements Application.ActivityLifecycleCallbacks {
/**
* 活動(dòng)的Activity數(shù)量,為1時(shí)畸肆,APP處于前臺(tái)狀態(tài)宦芦,為0時(shí),APP處于后臺(tái)狀態(tài)
*/
private int activityCount = 0;
/**
* 最后一次可見的Activity
* 用于比對(duì)Activity轴脐,這樣可以排除啟動(dòng)應(yīng)用時(shí)的這種特殊情況调卑,
* 如果啟動(dòng)應(yīng)用時(shí)也需要鎖屏等操作,請(qǐng)?jiān)趩?dòng)頁(yè)里進(jìn)行操作大咱。
*/
private Activity lastVisibleActivity;
/**
* 最大無(wú)需解鎖時(shí)長(zhǎng) 5分鐘 單位:毫秒
*/
private final static long MAX_UNLOCK_DURATION = 5 * 60 * 1000;
/**
* 最后一次離開應(yīng)用時(shí)間 單位:毫秒
*/
private long lastTime;
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
activityCount++;
}
@Override
public void onActivityResumed(Activity activity) {
// 后臺(tái)進(jìn)程切換到前臺(tái)進(jìn)程,不包含啟動(dòng)應(yīng)用時(shí)的這種特殊情況
//最后一次可見Activity是被喚醒的Activity && 活動(dòng)的Activity數(shù)量為1
if (lastVisibleActivity == activity && activityCount == 1) {
//Background -> Foreground , do something
startLockScreen(activity);
}
lastVisibleActivity = activity;
}
/**
* 打開手勢(shì)密碼
*
* @param activity Activity
*/
private void startLockScreen(Activity activity) {
if (lockScreen(activity)) {
Intent intent = new Intent(activity, LockScreenActivity.class);
activity.startActivity(intent);
}
}
/**
* 鎖屏
*
* @param activity Activity
* @return true 鎖屏恬涧,反之不鎖屏
*/
private boolean lockScreen(Activity activity) {
//解鎖未超時(shí),不鎖屏
if (!unlockTimeout())
return false;
// 當(dāng)前Activity是鎖屏Activity或登錄Activity碴巾,不鎖屏
if (activity instanceof LockScreenActivity || activity instanceof LoginActivity)
return false;
//不滿足其它條件溯捆,不鎖屏,#備用#
if (!otherCondition()) {
return false;
}
//鎖屏
return true;
}
/**
* 由后臺(tái)切到前臺(tái)時(shí)厦瓢,解鎖時(shí)間超時(shí)
*
* @return 時(shí)間間隔大于解鎖時(shí)長(zhǎng)為true现使,反之為false
*/
private boolean unlockTimeout() {
//當(dāng)前時(shí)間和上次離開應(yīng)用時(shí)間間隔
long dTime = System.currentTimeMillis() - lastTime;
return dTime > MAX_UNLOCK_DURATION;
}
/**
* 其它條件
*
* @return boolean
*/
private boolean otherCondition() {
return true;
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
activityCount--;
lastTime = System.currentTimeMillis();
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}