之前 APP 一直都是通過桌面的 icon 點(diǎn)擊進(jìn)入應(yīng)用挪蹭,所以都會(huì)跳轉(zhuǎn)到登錄頁(yè)進(jìn)行驗(yàn)證式廷,再跳轉(zhuǎn)到首頁(yè)承冰,最近有新的需求华弓,第三方直接打開應(yīng)用的某個(gè) activity ,如果沒有 token 會(huì)報(bào) 500 或者 token 無效困乒,所以給應(yīng)用加個(gè)登錄攔截寂屏,如果沒有登錄,就跳轉(zhuǎn)到登錄頁(yè)登錄之后再返回要跳轉(zhuǎn)的 activity 顶燕。
先是看了一遍網(wǎng)上的實(shí)現(xiàn)方式凑保,覺得都挺麻煩的,就自己試試通過 ActivityLifecycleCallbacks 來做一個(gè)登錄攔截涌攻。
首先寫個(gè) MyApplicationLifecycleCallback 實(shí)現(xiàn) ActivityLifecycleCallbacks 接口欧引,該 class 如下:
public class MyApplicationLifecycleCallback implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(final 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) {
}
}
然后在 onActivityStarted 里面寫攔截的代碼:
// 當(dāng)前activity的名字
String className = activity.getLocalClassName();
// 不需要攔截的activity名字
String permissionClassName = "com.permission.PermissionActivity";
// 是否是需要攔截的activity
boolean isInterceptActivity = !loginClassName.equals(className) && !permissionClassName.equals(className);
// 是否有token 這里取application的全局token
boolean haveToken = !(GlobalValue.TOKEN== null || "".equals(GlobalValue.TOKEN));
if (isInterceptActivity && !haveToken) {
Intent loginIntent = new Intent();
loginIntent.setClass(activity, LoginActivity.class);
activity.startActivity(loginIntent);
}
這樣子就可以攔截沒有登錄的時(shí)候,其他應(yīng)用打開需要登錄的界面打開的就是登錄頁(yè)了恳谎。
緊接著發(fā)現(xiàn)一個(gè)問題芝此。在 ActivityLifecycleCallbacks 攔截的話,被攔截的 activity 已經(jīng) onResumed() 顯示到前臺(tái)因痛,再跳轉(zhuǎn)到 LoginActivity 婚苹,所以所有操作已經(jīng)做完了,包括網(wǎng)絡(luò)請(qǐng)求鸵膏,所以跳轉(zhuǎn)登錄之后膊升,finish 掉 LoginActivity 后,打開的是一個(gè)空白頁(yè)面谭企,不是我們想要的效果廓译。
所以我就想到保存當(dāng)前跳轉(zhuǎn)的 intent ,結(jié)束掉當(dāng)前被攔截的 activity 债查,等到登錄結(jié)束后再跳回去非区。
// 當(dāng)前activity的名字
String className = activity.getLocalClassName();
// 不需要攔截的activity名字
String permissionClassName = "com.permission.PermissionActivity";
// 是否是需要攔截的activity
boolean isInterceptActivity = !loginClassName.equals(className) && !permissionClassName.equals(className);
// 是否有token 這里取application的全局token
boolean haveToken = !(GlobalValue.TOKEN== null || "".equals(GlobalValue.TOKEN));
if (isInterceptActivity && !haveToken) {
Intent loginIntent = new Intent();
loginIntent.setClass(activity, LoginActivity.class);
activity.startActivity(loginIntent);
// 被攔截的activity的intent
beforeIntent = activity.getIntent();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// 在這里finish掉,然后一會(huì)loginActivity結(jié)束了再打開
activity.finish();
}
}, 500);
}
然后在 onActivityStopped 里面增加判斷
String className = activity.getLocalClassName();
if (loginClassName.equals(className)) {
// 當(dāng)loginActivity結(jié)束的時(shí)候盹廷,判斷beforeIntent為不為空征绸,不為空就說明是第三方打開的,跳轉(zhuǎn)回去
if (beforeIntent != null) {
activity.startActivity(beforeIntent);
beforeIntent = null;
}
}
所以這個(gè) MyApplicationLifecycleCallback.java 文件的全部代碼是:
public class MyApplicationLifecycleCallback implements Application.ActivityLifecycleCallbacks {
private Intent beforeIntent;
String loginClassName = "com.LoginActivity";
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(final Activity activity) {
// 登錄攔截 登錄過后再跳回去
// 當(dāng)前activity的名字
String className = activity.getLocalClassName();
// 不需要攔截的activity名字
String permissionClassName = "com.permission.PermissionActivity";
// 是否是需要攔截的activity
boolean isInterceptActivity = !loginClassName.equals(className) && !permissionClassName.equals(className);
// 是否有token 這里取application的全局token
boolean haveToken = !(GlobalValue.TOKEN== null || "".equals(GlobalValue.TOKEN));
if (isInterceptActivity && !haveToken) {
Intent loginIntent = new Intent();
loginIntent.setClass(activity, LoginActivity.class);
activity.startActivity(loginIntent);
// 被攔截的activity的intent
beforeIntent = activity.getIntent();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// 在這里finish掉俄占,然后一會(huì)loginActivity結(jié)束了再打開
activity.finish();
}
}, 500);
}
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
String className = activity.getLocalClassName();
if (loginClassName.equals(className)) {
// 當(dāng)loginActivity結(jié)束的時(shí)候管怠,判斷beforeIntent為不為空,不為空就說明是第三方打開的缸榄,跳轉(zhuǎn)回去
if (beforeIntent != null) {
activity.startActivity(beforeIntent);
beforeIntent = null;
}
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}