網站首頁 編程語言 正文
前言
前面的文章我們講到APP登錄攔截的功能實現,現在網上比較多的推薦使用AOP,我們使用下來還是太麻煩,兼容性問題很多,(坑太多,項目我已經改回來了,如果想體驗AOP可以切換aop分支運行)
難道就想實現一個這么簡單的功能,就非得使用AOP了嗎?有沒有簡單一點的方式,方式其實太多了,個人感覺的話,完全沒必要為了這么個小功能導入一個AOP庫。今天我們看看使用方法池與通知回調的方式來處理登錄攔截的邏輯。
一、使用通知與回調
其實本質邏輯就是想判斷用戶是否已經登錄,然后跳轉到登錄頁面,登錄完成之后再跳轉到個人中心,那我們使用通知回調不就行了嗎?
在登錄完成之后發出通知,在首頁我們接受這個通知就調用去個人中心的方法不就行了嗎?
使用通知的方式有很多,這里我們以LiveEventBus為例:
public class FunctionManager {
private static FunctionManager functionManager;
private static HashMap<String, Function> mFunctionMap;
public FunctionManager() {
mFunctionMap = new HashMap<>();
}
public static FunctionManager get() {
if (functionManager == null) {
functionManager = new FunctionManager();
}
return functionManager;
}
public void addLoginCallback(LifecycleOwner owner, ILoginCallback callback) {
LiveEventBus.get("login", Boolean.class).observe(owner, aBoolean -> {
if (aBoolean != null && aBoolean) {
callback.callback();
}
});
}
public interface ILoginCallback {
void callback();
}
public void finishLogin() {
LiveEventBus.get("login").post(true);
}
}
我們封裝一個發送事件和一個接收事件,注意使用的時候添加回調的方法不要放在點擊事件中。否則多次點擊會重復調用的。
override fun startObserve() {
FunctionManager.get().addLoginCallback(this) {
gotoProfilePage()
}
}
override fun init() {
mBtnCleanToken.click {
SP().remove(Constants.KEY_TOKEN)
toast("清除成功")
}
mBtnProfile.click {
checkLogin()
}
}
private fun checkLogin() {
if (SP().getString(Constants.KEY_TOKEN, "").checkEmpty()) {
gotoLoginPage()
} else {
gotoProfilePage()
}
}
private fun gotoLoginPage() {
gotoActivity<LoginDemoActivity>()
}
private fun gotoProfilePage() {
gotoActivity<ProfileDemoActivity>()
}
效果:
二、使用方法池
上面一種方法依賴于LiveData,我們都知道LiveData的值在一些特性情況下并不保險,當然我們可以使用FlowBus來緩解這一問題(只能在Kotlin項目中使用了),并且還存在使用不當,導致多次訂閱,就會發生執行N此的邏輯。就需要我們再添加回調的方法中自己判斷去重的邏輯。如果大家有興趣也可以自行擴展,并不復雜
我們還可以使用另一種方便的方式,支持 Java 和 Kotlin ,我們使用方法池把需要執行的方法放入緩存中,當我們登錄成功之后再把緩存中的方法拿出來執行,可以靈活放入多個方法。
定義方法對象
public abstract class IFunction {
public String functionName;
public IFunction(String functionName) {
this.functionName = functionName;
}
protected abstract void function();
}
方法管理類
public class FunctionManager {
private static FunctionManager functionManager;
private static HashMap<String, IFunction> mFunctionMap;
public FunctionManager() {
mFunctionMap = new HashMap<>();
}
public static FunctionManager get() {
if (functionManager == null) {
functionManager = new FunctionManager();
}
return functionManager;
}
/**
* 添加方法
*/
public FunctionManager addFunction(IFunction function) {
if (mFunctionMap != null) {
mFunctionMap.put(function.functionName, function);
}
return this;
}
/**
* 執行方法
*/
public void invokeFunction(String key) {
if (TextUtils.isEmpty(key)) {
return;
}
if (mFunctionMap != null) {
IFunction function = mFunctionMap.get(key);
if (function != null) {
function.function();
//用完移除掉
removeFunction(key);
} else {
try {
throw new RuntimeException("function not found");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 使用之后移除相關的緩存
*/
public void removeFunction(String key) {
if (mFunctionMap != null) {
mFunctionMap.remove(key);
}
}
}
使用:
override fun init() {
mBtnCleanToken.click {
SP().remove(Constants.KEY_TOKEN)
toast("清除成功")
}
mBtnProfile.click {
checkLogin()
}
}
private fun checkLogin() {
if (SP().getString(Constants.KEY_TOKEN, "").checkEmpty()) {
FunctionManager.get().addFunction(object : IFunction("gotoProfilePage") {
override fun function() {
gotoProfilePage()
}
})
gotoLoginPage()
} else {
gotoProfilePage()
}
}
private fun gotoLoginPage() {
gotoActivity<LoginDemoActivity>()
}
private fun gotoProfilePage() {
gotoActivity<ProfileDemoActivity>()
}
我這里是為了兼容其他的場景使用,需要傳入方法的key,如果大家只想用于攔截登錄這一個場景,大家可以把Key的值固定化。
記得在LoginActivity中登錄成功的時候回調處理
fun doLogin() {
showStateLoading()
CommUtils.getHandler().postDelayed({
showStateSuccess()
SP().putString(Constants.KEY_TOKEN, "abc")
finish()
//方法池的方式
FunctionManager.get().invokeFunction("gotoProfilePage")
}, 500)
}
效果和使用通知的效果一致
總結
不使用AOP我們一樣能完成登錄攔截的功能,思路不同但是實現的效果是相同的,使用原生的庫或一些特性我們就無需再導入一個不好控制的庫。
之前我們說過AOP框架的一些缺點,比如影響性能,編譯慢,安裝包體積大,Kotlin不友好,APG不友好等等,
那么這樣使用方法池或者回調的方式有什么優缺點呢?
- 優點:輕量,不影響性能,內存開銷小,支持Kotlin、Java。
- 缺點:相對使用沒有AOP那么簡便,判斷是否登錄的邏輯得自己寫了。
當然了這種工具類管理的方式只是一種思路,實現的方法有很多,我這里只是舉例兩種用的比較多的方式回調與方法池,如果大家對此思路有優化的地方也可以評論區交流。
后期我會再出一些攔截登錄的其他思路,比如基于Intent,基于線程池,基于協程等等,大家可以對比一下 AOP,方法池和其他一些實現思路,哪一種比較好。
原文鏈接:https://juejin.cn/post/7133018431774785550
相關推薦
- 2022-05-05 利用Python編寫一個記憶翻牌游戲_python
- 2022-02-17 Flutter InAppWebView在showModalBottomSheet中無法滾動
- 2022-09-27 Hive中常用正則表達式的運用小結_正則表達式
- 2023-03-26 詳解C/C++中低耦合代碼的設計實現_C 語言
- 2022-11-23 詳解React?Native中如何使用自定義的引用路徑_React
- 2022-12-06 React深入分析useEffect源碼_React
- 2022-12-19 Oracle?Instr函數實例講解_oracle
- 2023-07-08 windows編譯libevent報錯
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支