Android 如何設計用戶Session管理?

相信你們都知道,每個App都須要登陸,登陸信息都保存在本地文件中,而後咱們就寫一堆的操做SharedPreferences的代碼了。java

如今,你能夠徹底拋棄這種方法,一句代碼搞定登陸信息,用戶信息管理。實現全局操做。爲你的程序解耦。git

立刻開始上手吧github

public void sessionDemo() {

        // 獲取登陸信息
        TokenInfo token = SessionManager.getDefault().getUserToken();
        // 獲取用戶信息
        UserInfo userInfo = SessionManager.getDefault().getUser();
        // 是否登陸
        boolean isLogin = SessionManager.getDefault().isLogin();
        // 退出登陸
        SessionManager.getDefault().clear();

        // 登陸成功後,設置用戶信息
        SessionManager.getDefault().setUser(new UserInfo());
        // 登陸成功後,設置登陸信息
        SessionManager.getDefault().setUserToken(new TokenInfo());


        Log.i("rae", "登陸信息:" + token);
        Log.i("rae", "用戶信息:" + userInfo);
        Log.i("rae", "是否登陸:" + isLogin);
    }
複製代碼

初始化配置cookie

// 這句請在Application onCreate 的時候調用初始化配置信息
SessionManager.initWithConfig(
        new SessionManager.ConfigBuilder()
                .context(this)
                .tokenClass(TokenInfo.class)
                .userClass(UserInfo.class)
                .build());
複製代碼

自定義用戶信息UserInfo實體類session

默認的UserInfo類型字段不知足需求?沒問題,徹底能夠自定義!app

// 初始化配置信息
SessionManager.initWithConfig(
        new SessionManager.ConfigBuilder()
                .context(this)
                .tokenClass(MyTokenInfo.class) // 你自定義的TokenInfo類
                .userClass(MyUserInfo.class) // 你自定義的UserInfo類
                .build());
複製代碼

引用庫:maven

implementation 'com.github.raedev:session:1.0.0'
複製代碼

若是下載失敗,請在根目錄 build.gradle添加:gradle

allprojects {
    repositories {
        maven { url "https://dl.bintray.com/raee/Android" }
    }
}
複製代碼

1、設計

抽象工廠模式,總體UML以下圖,總體思路爲:ui

抽象出SessionManager類,實際仍是PreferencesSessionManager實現了這個抽象類,進行本地SharePreferences保存。this

Config: 負責維護實體類的class,用來作JSON序列化保存到本地的。這個類起到泛型解析的做用,getUser()返回的對象就由這個類去維護了。從而達到了解耦的做用。

ConfigBuild: 構建者模式,提供方便的會話配置。

SessionManager.getDefault(); 默認返回的是PreferencesSessionManager的實例。

2、自定義SessionManger

若是不想用SharePreferences來保存用戶信息,也能夠繼承SessionManger類實現抽象方法實現自定義的Session管理。

若是你的自定義也想全局訪問,那麼能夠新增一個AppSessionManger的類,來實現一個單例方法,返回你自定義的實現。

參考SessionManger.getDefault()的實現就能夠了。

3、 SessionManger 代碼實現

/** * 會話管理 * Created by ChenRui on 2017/4/28 0028 17:27. */
public abstract class SessionManager {

    public static class Config {
        Class<?> userTokenClass;
        Class<?> userClass;
        Context context;
    }

    public static class ConfigBuilder {
        private final Config mConfig;

        public ConfigBuilder() {
            mConfig = new Config();
        }

        public ConfigBuilder tokenClass(Class<?> cls) {
            mConfig.userTokenClass = cls;
            return this;
        }

        public ConfigBuilder userClass(Class<?> cls) {
            mConfig.userClass = cls;
            return this;
        }

        public ConfigBuilder context(Context applicationContext) {
            mConfig.context = applicationContext;
            return this;
        }

        public Config build() {
            return mConfig;
        }
    }

    private static Config sConfig;
    private static WeakReference<SessionManager> managerWeakReference;

    /** * 獲取默認的會話管理器,默認的爲cookie 管理器。 * 使用以前請使用{@link #initWithConfig(Config)} 來進行初始化配置。 */
    public static SessionManager getDefault() {
        if (sConfig == null) {
            Log.w("SessionManager", "session config from default");
            sConfig = new ConfigBuilder().tokenClass(SessionToken.class).userClass(SessionUserInfo.class).build();
        }

        if (managerWeakReference == null || managerWeakReference.get() == null) {
            synchronized (SessionManager.class) {
                if (managerWeakReference == null || managerWeakReference.get() == null) {
                    managerWeakReference = new WeakReference<SessionManager>(new PreferencesSessionManager(sConfig));
                }
            }
        }

        return managerWeakReference.get();
    }

    /** * 初始化會話管理器 */
    public static void initWithConfig(Config config) {
        if (sConfig != null) {
            sConfig = null;
            System.gc();
        }

        sConfig = config;
    }


    SessionManager() {
    }

    /** * 是否登陸 */
    public abstract boolean isLogin();


    /** * 清除會話信息,即退出登陸。 */
    public abstract void clear();

    /** * 獲取當前登陸的用戶信息,在調用該方法以前請先調用{@link #isLogin()}來判斷是否登陸 */
    public abstract <T> T getUser();

    /** * 設置當前用戶信息 */
    public abstract <T> void setUser(T user);

    /** * 設置用戶受權信息 * * @param token 受權信息 */
    public abstract <T> void setUserToken(T token);

    /** * 獲取用戶受權信息 */
    public abstract <T> T getUserToken();


}
複製代碼

本文結束,很是簡單的實現,可是卻很是實用!

開源:github.com/raedev/Andr…

相關文章
相關標籤/搜索