開發實訓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<String, WkyModel> models = new HashMap<String, WkyModel>();  
    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<String, Object> params = new HashMap<String, Object>();  
下面我們來看註冊登錄的基類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的實現方式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章