开发实训10---Android---注册登录功能实现1

用户在观看完应用介绍页面之后,会点击进入应用按钮,这时由于用户是第一次运行,所以会弹出注册页面。如果是老用户,启动应用时,在Splash页面之后,如果应用记录着用户的登录信息,测直接进入主页面,如果从本地取不到用户登录信息,则将显示登录页面。


注册和登录功能看起来很简单,但是由于我们这里需要实现一个完整的应用支撑基础设施,因此需要分几个部分来进行。我们首先会讨论怎样创建并使用Activity中会用到的Model类,在这中间我们会采用Application对象作为中心信息仓库,每个Model类只是中心信息仓库的视图,便于对应的Activity类来使用;接着我们会讨论Activity类的基类,在其中包装诸如按回退键提示退出等功能;接着我们会讨论网络请求的实现,这里我们采用异步任务的方式来进行,协议采用Json Over Http,因此会顺便介绍Json的解析。


在进入正文之前,首先解释一个问题,我们什么时候检查版本更新。一般你可以在很多点来检查版本更新,我在这里采用进入主页面前检查版本更新,为什么这样做呢?因为在实际项目中,我们可能会有些小范围测试的版本,我们会采用灰度更新的机制,即只有一部分用户会收到更新通知,试用最新版本,如果反响很好,我们再向普通用户推出版本更新,因此检查版本更新放在了登录之后。


好了,我们先来看怎样实现MVC中的Model。我们首先在WkyLib工程中,定义Model的基类WkyModel,代码如下所示:


[java] view plaincopy
public class WkyModel {  
    public static WkyModel getInstance(String objectId, Class cls) {  
        if (models.containsKey(objectId)) {  
            return models.get(objectId);  
        }  
        WkyModel model = (WkyModel)WkyReflection.callPrivateConstructor(cls);  
        model.setObjectId(objectId);  
        Log.e("wky", "cls:" + cls.getCanonicalName() + "!");  
        if (null == model) {  
            model = new WkyModel();  
        }  
        models.put(objectId, model);  
        return model;  
    }  
      
    public static void removeObject(String objectId) {  
        models.remove(objectId);  
    }  
      
    public static void removeInstance(String objectId) {  
        models.remove(objectId);  
    }  
      
  
    /** 
     * 在Activity.onDestroy中调用,判断是否需要将实例从models中移除 
     * @return 
     * 【闫涛 2015.09.17】初始版本 
     */  
    public boolean isShared() {  
        return isShared;  
    }  
  
    /** 
     * 如果想要在多个界面中使用同一个Model对象,则需要调用此函数, 
     * 将isShared设置为true,这时在Activity.onDestroy中就不会将本实例从models中移除了 
     * @param isShared 
     * 【闫涛 2015.09.17】初始版本 
     */  
    public void setShared(boolean isShared) {  
        this.isShared = isShared;  
    }  
  
  
    public String getObjectId() {  
        return objectId;  
    }  
  
    public void setObjectId(String objectId) {  
        this.objectId = objectId;  
    }  
  
  
    private static HashMap models = new HashMap();  
    protected boolean isShared = false;  
    protected String objectId = null;  
}  
假设一个Activity有对应的Model类时,例如JysRegisgetrLoginActivity需要JysRegisterLoginModel类对象时,会通过调用getInstance方法来获取实例。每个Model类,可以同时存在多个实例,保存在models属性中。一般情况下,Activity在onCreate或在启动此Activity时,会生成一个Model类的实例,当该Activity退出时,在onDestroy回调函数中将该实例从models属性中移除。但是如果设置了isShared为ture时,则onDestroy方法中就不会移除此对象,就可以在不同的Activity实例中使用了。


在上面的代码中,我们用到了Java的反射机制,根据getInstance方法第二个参数的类,调用该类的私有无参数构造函数,生成该类的对象,我们引入了一个反射工具类WkyReflection,代码如下所示:


[java] view plaincopy
public class WkyReflection {  
    /** 
     * 调用类的私有无参数构造函数,生成该类对象并返回该对角 
     * 例子: 
     * WkyRegisterLoginModel model = (WkyRegisterLoginModel)WkyReflection.callPrivateConstructor(WkyRegisterLoginModel.class); 
     * @param cls 
     * @return 
     * 【闫涛 2015.09.17】初始版本 
     */  
    public static Object callPrivateConstructor(Class cls) {  
        Constructor[] constructor = cls.getDeclaredConstructors();  
        constructor[0].setAccessible(true);  
        Object rst = null;  
        try {  
            rst = constructor[0].newInstance();  
        } catch (InstantiationException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalArgumentException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (InvocationTargetException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        return rst;   
    }  
}  
在本节开头我们就提到,我们的信息保存在应用的中心信息仓库中,每个Model里保存的,只是其中的一部分,在Android平台下,我们可以利用Application子类来作为中心信息仓库,代码如下所示:


[java] view plaincopy
/** 
     * model类将所有信息均保存在HashMap中,这样信息可以在Model之间共用 
     * @param key 
     * @param val 
     * 【闫涛 2015.09.17】初始版本 
     */  
    public static void putObject(String key, Object val) {  
        params.put(key, val);  
    }  
      
    /** 
     * 从HashMap中取出相应的信息,调用者需要将其转化为正确的类 
     * @param key 
     * @return 
     * 【闫涛 2015.09.17】初始版本 
     */  
    public static Object getObject(String key) {  
        return params.get(key);  
    }  
      
    public void exitApp() {  
        System.exit(1);  
    }  
      
    public static WkyApplication instance = null;  
    private static HashMap params = new HashMap();  
下面我们来看注册登录的基类WkyRegisterLoginModel类的实现:


[java] view plaincopy
public class WkyRegisterLoginModel extends WkyModel {  
      
    protected WkyRegisterLoginModel() {  
        WkyApplication.putObject(WkyConstants.ROLE_ID, Integer.valueOf(WkyConstants.ROLE_JYS));  
        WkyApplication.putObject(WkyConstants.REGISTER_LOGIN_STATE, Integer.valueOf(STATE_LOGIN));  
        roleId = (Integer)WkyApplication.getObject(WkyConstants.ROLE_ID);  
        state = (Integer)WkyApplication.getObject(WkyConstants.REGISTER_LOGIN_STATE);  
    }  
      
      
    public int getState() {  
        return state;  
    }  
    public void setState(int state) {  
        this.state = state;  
    }  
  
  
    public int getRoleId() {  
        return roleId;  
    }  
  
    public void setRoleId(int roleId) {  
        this.roleId = roleId;  
    }  
  
  
    public final static int STATE_REGISTER = 1;  
    public final static int STATE_LOGIN = 2;  
    public final static int STATE_FORGET_PWD = 3;  
    public final static int STATE_ACTIVATE = 4;  
  
    private int state = STATE_LOGIN;  
    private int roleId = WkyConstants.ROLE_JYS;  
}  
在上面的代码中,里面有两个属性比较重要,第一个state代表注册登录Activity所处的状态,一共有四种:注册、登录、忘记密码、激活,第二个属性roleId代表用户的角色,可以是基因师也可以是大众。需要注意的是,在构造函数中,这两个属性的值是存到中心信息仓库中的。
下面看具体应用WkgJys中,怎样定义具体的Model类JysRegisterLoginModel:


[java] view plaincopy
public class JysRegisterLoginModel extends WkyRegisterLoginModel {  
    protected JysRegisterLoginModel() {  
        super();  
        isShared = false;  
    }  
}  
在这里,由于没有特别的需要,没有定义新的属性,因此代码很简单。但是需要注意的是isShared = false,意味着在onDestroy方法中,这个实例将被移除,不会被共享。
好了,有了上述代码,Model体系就创建完成了。在下一节中,我们将讲到怎样实现MVC中的C,即Activity的实现方式。

你可能感兴趣的:(开发实训10---Android---注册登录功能实现1)