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…

相关文章
相关标签/搜索