引入
一個(gè)應(yīng)用中有許多頁面沟沙,有些頁面是需要登錄才能看的河劝,當(dāng)我們進(jìn)行頁面跳轉(zhuǎn)時(shí)會(huì)先判斷用戶是否登錄,如果已經(jīng)登錄矛紫,則正常跳轉(zhuǎn)赎瞎,如果沒有登錄,則跳轉(zhuǎn)到登錄頁面先登錄颊咬,但凡是有注冊务甥,登錄的APP,這樣的操作喳篇,大家應(yīng)該都很熟悉吧敞临。一般情況下,我們的邏輯是這樣的:
if (TextUtils.isEmpty(HeaderUtils.getSessionId())) {//還沒登錄麸澜,先跳轉(zhuǎn)登錄頁面
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
} else {//已經(jīng)登錄了挺尿,跳轉(zhuǎn)訂單頁面
Intent intent = new Intent(this, OrderActivity.class);
startActivity(intent);
}
上面的做法需要在每一個(gè)目標(biāo)頁面重復(fù)做登陸檢查,這樣設(shè)計(jì)的擴(kuò)展性并不友好。在這里介紹阿里的ARouter路由框架票髓,可以更加優(yōu)雅的實(shí)現(xiàn)登錄攔截功能。
ARoute功能介紹
- 支持直接解析標(biāo)準(zhǔn)URL進(jìn)行跳轉(zhuǎn)铣耘,并自動(dòng)注入?yún)?shù)到目標(biāo)頁面中
- 支持多模塊工程使用
- 支持添加多個(gè)攔截器洽沟,自定義攔截順序
- 支持依賴注入,可單獨(dú)作為依賴注入框架使用
- 支持InstantRun
- 支持MultiDex(Google方案)
- 映射關(guān)系按組分類蜗细、多級管理裆操,按需初始化
- 支持用戶指定全局降級與局部降級策略
- 頁面、攔截器炉媒、服務(wù)等組件均自動(dòng)注冊到框架
- 支持多種方式配置轉(zhuǎn)場動(dòng)畫
- 支持獲取Fragment
- 完全支持Kotlin以及混編()
- 支持第三方 App 加固(使用 arouter-register 實(shí)現(xiàn)自動(dòng)注冊)
- 支持生成路由文檔
使用方法
1.gradle配置
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
?
dependencies {
...
implementation 'com.alibaba:arouter-api:1.4.0'
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
}
2.Application初始化sdk
if (BuildConfig.DEBUG) {
// 這兩行必須寫在init之前踪区,否則這些配置在init過程中將無效
ARouter.openLog(); // 打印日志
ARouter.openDebug();// 開啟調(diào)試模式(如果在InstantRun模式下運(yùn)行,必須開啟調(diào)試模式吊骤!線上版本需要關(guān)閉,否則有安全風(fēng)險(xiǎn))}
}
ARouter.init(this);// 盡可能早缎岗,推薦在Application中初始化
3.添加注解
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在baseActivity自動(dòng)注入屬性
ARouter.getInstance().inject(this);
}
}
//對應(yīng)的Activity 添加@Route注解 path路徑 這里的路徑需要注意的是至少需要有兩級,/xx/xx
@Route(path = RoutePath.FIRST_PATH)
public class FirstActivity extends BaseActivity {
@Autowired
public String msg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
((TextView)findViewById(R.id.tv_msg)).setText(msg);
}
}
4.攔截器的使用面向切面編程
// 在跳轉(zhuǎn)過程中處理登陸事件白粉,這樣就不需要在目標(biāo)頁重復(fù)做登陸檢查
// 攔截器會(huì)在跳轉(zhuǎn)之間執(zhí)行传泊,多個(gè)攔截器會(huì)按優(yōu)先級順序依次執(zhí)行
@Interceptor(name = "login", priority = 6)
public class LoginInterceptorImpl implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
String path = postcard.getPath();
LogUtils.e(path);
boolean isLogin = SPUtils.getInstance().getBoolean(RoutePath.SP_IS_LOGIN, false);
if (isLogin) { // 如果已經(jīng)登錄不攔截
callback.onContinue(postcard);
} else { // 如果沒有登錄
switch (path) {
// 不需要登錄的直接進(jìn)入這個(gè)頁面
case RoutePath.LOGIN_PATH:
case RoutePath.FIRST_PATH:
callback.onContinue(postcard);
break;
// 需要登錄的直接攔截下來
default:
callback.onInterrupt(null);
break;
}
}
}
@Override
public void init(Context context) {//此方法只會(huì)走一次
LogUtils.e("路由登錄攔截器初始化成功");
}
}
//啟動(dòng)Activity
ARouter.getInstance().build(RoutePath.SECOND_PATH)
.withString("msg", "ARouter傳遞過來的需要登錄的參數(shù)msg")
.navigation(this,new LoginNavigationCallbackImpl());//第二個(gè)參數(shù)是路由跳轉(zhuǎn)的回調(diào)
public class LoginNavigationCallbackImpl implements NavigationCallback {
@Override //找到了
public void onFound(Postcard postcard) {
}
@Override //找不到了
public void onLost(Postcard postcard) {
}
@Override //跳轉(zhuǎn)成功了
public void onArrival(Postcard postcard) {
}
@Override
public void onInterrupt(Postcard postcard) {
String path = postcard.getPath();
LogUtils.v(path);
Bundle bundle = postcard.getExtras();
// 被登錄攔截了下來了
// 需要調(diào)轉(zhuǎn)到登錄頁面,把參數(shù)跟被登錄攔截下來的路徑傳遞給登錄頁面鸭巴,登錄成功后再進(jìn)行跳轉(zhuǎn)被攔截的頁面
ARouter.getInstance().build(RoutePath.LOGIN_PATH)
.with(bundle)
.withString(RoutePath.PATH, path)
.navigation();
}
}
效果圖
項(xiàng)目地址:https://github.com/belong571/ARouteLogin