android 手機(jī)號(hào)實(shí)現(xiàn)登錄功能

先看看效果


image.png

我的這個(gè)登錄功能是手機(jī)號(hào)和密碼都已經(jīng)在后臺(tái)數(shù)據(jù)庫有存儲(chǔ)的,所以是直接登錄。
重點(diǎn)有三個(gè):
1、賬號(hào)密碼的存儲(chǔ),實(shí)現(xiàn)自動(dòng)登錄;
2、網(wǎng)絡(luò)通信;
3、密碼一定要Md5加密之后再傳輸

先把布局放上來

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_login"
android:orientation="vertical"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/item_height_normal"
android:layout_marginLeft="@dimen/margin_large"
android:layout_marginRight="@dimen/margin_large"
android:layout_marginTop="@dimen/dp_300">

    <ImageView
        android:id="@+id/img_account"
        android:layout_width="@dimen/dp_19"
        android:layout_height="@dimen/dp_20"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="@dimen/margin_tiny"
        android:layout_marginLeft="@dimen/margin_tiny"
        android:scaleType="fitXY"
        android:src="@drawable/ic_login_account"/>

    <EditText
        android:id="@+id/et_account"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="center"
        android:layout_marginBottom="@dimen/margin_tiny"
        android:layout_marginLeft="@dimen/margin_normal"
        android:layout_toRightOf="@+id/img_account"
        android:background="@null"
        android:hint="@string/account"
        android:maxLines="1"
        android:textColor="@android:color/black"
        android:textColorHint="@color/tv_gray_deep"
        android:textSize="@dimen/text_size_normal"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/line_height"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="@dimen/margin_normal"
        android:layout_toRightOf="@+id/img_account"
        android:background="@color/line_new"/>
</RelativeLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_height_normal"
    android:layout_marginLeft="@dimen/margin_large"
    android:layout_marginRight="@dimen/margin_large">

    <ImageView
        android:id="@+id/img_pw"
        android:layout_width="@dimen/dp_18"
        android:layout_height="@dimen/dp_20"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="@dimen/margin_tiny"
        android:layout_marginLeft="@dimen/margin_tiny"
        android:scaleType="fitXY"
        android:src="@drawable/ic_login_pw"/>

    <EditText
        android:id="@+id/et_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="center"
        android:layout_marginBottom="@dimen/margin_tiny"
        android:layout_marginLeft="@dimen/margin_normal"
        android:layout_toRightOf="@+id/img_pw"
        android:background="@null"
        android:hint="@string/password"
        android:inputType="textPassword"
        android:maxLines="1"
        android:textColor="@android:color/black"
        android:textColorHint="@color/tv_gray_deep"
        android:textSize="@dimen/text_size_normal"/>
    <ImageView
        android:id="@+id/iv_see_password"
        android:layout_width="@dimen/image_width_litter"
        android:layout_height="@dimen/image_height_litter"
        android:src="@drawable/image_password_bg"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:scaleType="fitXY"
        />
    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/line_height"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="@dimen/margin_normal"
        android:layout_toRightOf="@+id/img_pw"
        android:background="@color/line_new"/>
</RelativeLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/margin_large"
    android:layout_marginRight="@dimen/margin_large"
    android:layout_marginTop="@dimen/margin_small"
    android:paddingBottom="@dimen/margin_small"
    android:paddingTop="@dimen/margin_small"
    android:orientation="horizontal"
    android:gravity="center"
    >
    <CheckBox
        android:id="@+id/checkBox_login"
        android:padding="@dimen/dp_10"
        android:textSize="@dimen/text_size_normal"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="@string/check_login"
        android:textColor="@color/top_bar_normal_bg" android:checked="false"/>
    <CheckBox
        android:id="@+id/checkBox_password"
        android:padding="@dimen/dp_10"
        android:textSize="@dimen/text_size_normal"
        android:layout_gravity="right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/check_password"
        android:textColor="@color/top_bar_normal_bg" android:checked="false"/>

</LinearLayout>
<Button
    android:id="@+id/btn_login"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/margin_large"
    android:layout_marginRight="@dimen/margin_large"
    android:layout_marginTop="@dimen/margin_huge"
    android:paddingBottom="@dimen/margin_small"
    android:paddingTop="@dimen/margin_small"
    android:text="@string/login"
    android:background="@drawable/btn_orange_selector"
    android:textColor="@android:color/white"
    android:textSize="@dimen/text_size_normal"/>

</LinearLayout>

進(jìn)入正題,同理,先上源碼,再解釋關(guān)鍵的一些地方

public class LoginByPhone extends AppCompatActivity implements View.OnClickListener,CompoundButton.OnCheckedChangeListener{

private EditText etPhone;
private EditText etPassword;
private Button btn_login;
private CheckBox checkBox_password;
private CheckBox checkBox_login;
private ImageView iv_see_password;


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login_first);
    initView();
    initEvent();
    initData();
}

private void initEvent() {
    btn_login.setOnClickListener(this);
    checkBox_password.setOnCheckedChangeListener(this);
    checkBox_login.setOnCheckedChangeListener(this);
    iv_see_password.setOnClickListener(this);
}

private void initView() {
    etPassword = (EditText) findViewById(R.id.et_password);
    etPhone = (EditText) findViewById(R.id.et_account);
    checkBox_password = (CheckBox) findViewById(R.id.checkBox_password);
    checkBox_login = (CheckBox) findViewById(R.id.checkBox_login);
    iv_see_password = (ImageView) findViewById(R.id.iv_see_password);
    btn_login = findViewById(R.id.btn_login);
}

/**
 * 登錄
 */
private void login(){
    Log.i("etPhone",etPhone.getText().toString());
    if(TextUtils.isEmpty(etPhone.getText().toString() )){
        Toast.makeText(LoginByPhone.this,R.string.phone_num_can_not_be_empty,Toast.LENGTH_LONG).show();
        return;
    }
    if(TextUtils.isEmpty(etPassword.getText())){
        Toast.makeText(LoginByPhone.this,R.string.password_can_not_be_empty,Toast.LENGTH_LONG).show();
        return;
    }
    final ProgressDialog pd = ProgressDialog.show(LoginByPhone.this,getResources().getString(R.string.connecting),getResources().getString(R.string.connecting_to_server));

    Thread loginRunnable = new Thread(){
        @Override
        public void run() {
            super.run();
            setLoginBtnClickable(false);
            new baichuang.callmonitor.Net.Login(etPhone.getText().toString(), Md5.md5(etPassword.getText().toString()),new baichuang.callmonitor.Net.Login.SuccessCallback(){
                @Override
                public void onSuccess(String token){
                    Config.cachedToken(LoginByPhone.this,token);
                    Config.cachedPhoneNum(LoginByPhone.this,etPhone.getText().toString());
                    pd.dismiss();

                    loadCheckBoxState();//記錄下當(dāng)前用戶記住密碼和自動(dòng)登錄的狀態(tài);
                    Intent i = new Intent(LoginByPhone.this,Call_Monitor.class);
                    i.putExtra(Config.KEY_TOKEN,token);
                    i.putExtra(Config.KEY_PHONE_NUM, etPhone.getText().toString());
                    startActivity(i);
                    finish();
                }
            }, new Login.FailCallback(){
                @Override
                public void onFail(){
                    setLoginBtnClickable(true);  //這里解放登錄按鈕,設(shè)置為可以點(diǎn)擊
                    pd.dismiss();
                    Toast.makeText(LoginByPhone.this,R.string.fail_to_login,Toast.LENGTH_LONG).show();
                }
            });

        }
    };
    loginRunnable.start();
}

/**
 * 保存用戶選擇“記住密碼”和“自動(dòng)登陸”的狀態(tài)
 */
private void loadCheckBoxState() {
    loadCheckBoxState(checkBox_password, checkBox_login);
}

/**
 * 保存按鈕的狀態(tài)值
 */
public void loadCheckBoxState(CheckBox checkBox_password, CheckBox checkBox_login) {

    //獲取SharedPreferences對象,使用自定義類的方法來獲取對象
    SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");

    //如果設(shè)置自動(dòng)登錄
    if (checkBox_login.isChecked()) {
        //創(chuàng)建記住密碼和自動(dòng)登錄是都選擇,保存密碼數(shù)據(jù)
        helper.putValues(
                new SharedPreferencesUtils.ContentValue("remenberPassword", true),
                new SharedPreferencesUtils.ContentValue("autoLogin", true),
                new SharedPreferencesUtils.ContentValue("password", Base64Utils.encryptBASE64(getPassword())));

    } else if (!checkBox_password.isChecked()) { //如果沒有保存密碼,那么自動(dòng)登錄也是不選的
        //創(chuàng)建記住密碼和自動(dòng)登錄是默認(rèn)不選,密碼為空
        helper.putValues(
                new SharedPreferencesUtils.ContentValue("remenberPassword", false),
                new SharedPreferencesUtils.ContentValue("autoLogin", false),
                new SharedPreferencesUtils.ContentValue("password", ""));
    } else if (checkBox_password.isChecked()) {   //如果保存密碼,沒有自動(dòng)登錄
        //創(chuàng)建記住密碼為選中和自動(dòng)登錄是默認(rèn)不選,保存密碼數(shù)據(jù)
        helper.putValues(
                new SharedPreferencesUtils.ContentValue("remenberPassword", true),
                new SharedPreferencesUtils.ContentValue("autoLogin", false),
                new SharedPreferencesUtils.ContentValue("password", Base64Utils.encryptBASE64(getPassword())));
    }
}

/**
 * 是否可以點(diǎn)擊登錄按鈕
 *
 * @param clickable
 */
public void setLoginBtnClickable(boolean clickable) {
    btn_login.setClickable(clickable);
}
/**
 * 獲取密碼
 */
public String getPassword() {
    return etPassword.getText().toString().trim();//去掉空格
}



private void initData() {
    //判斷用戶第一次登陸
    if (firstLogin()) {
        checkBox_password.setChecked(false);//取消記住密碼的復(fù)選框
        checkBox_login.setChecked(false);//取消自動(dòng)登錄的復(fù)選框
    }
    //判斷是否記住密碼
    if (remenberPassword()) {
        checkBox_password.setChecked(true);//勾選記住密碼
        setTextNameAndPassword();//把密碼和賬號(hào)輸入到輸入框中
    } else {
        setTextName();//把用戶賬號(hào)放到輸入賬號(hào)的輸入框中
    }

    //判斷是否自動(dòng)登錄
    if (autoLogin()) {
        checkBox_login.setChecked(true);
        login();//去登錄就可以
    }
}

/**
 * 設(shè)置數(shù)據(jù)到輸入框中
 */
public void setTextName() {
    etPhone.setText("" + getLocalName());
}

/**
 * 把本地保存的數(shù)據(jù)設(shè)置數(shù)據(jù)到輸入框中
 */
public void setTextNameAndPassword() {
    etPhone.setText("" + getLocalName());
    etPassword.setText("" + getLocalPassword());
}


/**
 * 獲得保存在本地的用戶名
 */
public String getLocalName() {
    //獲取SharedPreferences對象,使用自定義類的方法來獲取對象
    SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
    String name = helper.getString("name");
    return name;
}

/**
 * 獲得保存在本地的密碼
 */
public String getLocalPassword() {
    //獲取SharedPreferences對象,使用自定義類的方法來獲取對象
    SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
    String password = helper.getString("password");
    return Base64Utils.decryptBASE64(password);   //解碼一下
}


/**
 * 判斷是否是第一次登陸
 */
private boolean firstLogin() {
    //獲取SharedPreferences對象,使用自定義類的方法來獲取對象
    SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
    boolean first = helper.getBoolean("first", true);
    if (first) {
        //創(chuàng)建一個(gè)ContentVa對象(自定義的)設(shè)置不是第一次登錄,,并創(chuàng)建記住密碼和自動(dòng)登錄是默認(rèn)不選,創(chuàng)建賬號(hào)和密碼為空
        helper.putValues(new SharedPreferencesUtils.ContentValue("first", false),
                new SharedPreferencesUtils.ContentValue("remenberPassword", false),
                new SharedPreferencesUtils.ContentValue("autoLogin", false),
                new SharedPreferencesUtils.ContentValue("name", ""),
                new SharedPreferencesUtils.ContentValue("password", ""));
        return true;
    }
    return false;
}
/**
 * 判斷是否自動(dòng)登錄
 */
private boolean autoLogin() {
    //獲取SharedPreferences對象,使用自定義類的方法來獲取對象
    SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
    boolean autoLogin = helper.getBoolean("autoLogin", false);
    return autoLogin;
}

/**
 * 判斷是否記住密碼
 */
private boolean remenberPassword() {
    //獲取SharedPreferences對象,使用自定義類的方法來獲取對象
    SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
    boolean remenberPassword = helper.getBoolean("remenberPassword", false);
    return remenberPassword;
}

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.btn_login:
            loadUserName();    //無論如何保存一下用戶名
            login(); //登陸
            break;
        case R.id.iv_see_password:
            setPasswordVisibility();    //改變圖片并設(shè)置輸入框的文本可見或不可見
            break;

    }
}

/**
 * 保存用戶賬號(hào)
 */
public void loadUserName() {
    if (!getAccount().equals("") || !getAccount().equals("請輸入登錄賬號(hào)")) {
        SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");
        helper.putValues(new SharedPreferencesUtils.ContentValue("name", getAccount()));
    }
}


/**
 * 設(shè)置密碼可見和不可見的相互轉(zhuǎn)換
 */
private void setPasswordVisibility() {
    if (iv_see_password.isSelected()) {
        iv_see_password.setSelected(false);
        //密碼不可見
        etPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
    } else {
        iv_see_password.setSelected(true);
        //密碼可見
        etPassword.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
    }
}

/**
 * 獲取賬號(hào)
 */
public String getAccount() {
    return etPhone.getText().toString().trim();//去掉空格
}


@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
    if (compoundButton == checkBox_password) {  //記住密碼選框發(fā)生改變時(shí)
        if (!isChecked) {   //如果取消“記住密碼”,那么同樣取消自動(dòng)登陸
            checkBox_login.setChecked(false);
        }
    } else if (compoundButton == checkBox_login) {   //自動(dòng)登陸選框發(fā)生改變時(shí)
        if (isChecked) {   //如果選擇“自動(dòng)登錄”,那么同樣選中“記住密碼”
            checkBox_password.setChecked(true);
        }
    }
}

}

基本的initView(),initData()就不啰嗦了。
先看login()這個(gè)函數(shù)
/**
* 登錄
*/

private void login(){
    Log.i("etPhone",etPhone.getText().toString());
    if(TextUtils.isEmpty(etPhone.getText().toString() )){
        Toast.makeText(LoginByPhone.this,R.string.phone_num_can_not_be_empty,Toast.LENGTH_LONG).show();
        return;
    }
    if(TextUtils.isEmpty(etPassword.getText())){
        Toast.makeText(LoginByPhone.this,R.string.password_can_not_be_empty,Toast.LENGTH_LONG).show();
        return;
    }
    final ProgressDialog pd =     ProgressDialog.show(LoginByPhone.this,getResources().getString(R.string.connecting),getResources().getString(R.string.connecting_to_server));

    Thread loginRunnable = new Thread(){
        @Override
        public void run() {
            super.run();
            setLoginBtnClickable(false);
            new baichuang.callmonitor.Net.Login(etPhone.getText().toString(), Md5.md5(etPassword.getText().toString()),new baichuang.callmonitor.Net.Login.SuccessCallback(){
                @Override
                public void onSuccess(String token){
                    Config.cachedToken(LoginByPhone.this,token);
                    Config.cachedPhoneNum(LoginByPhone.this,etPhone.getText().toString());
                    pd.dismiss();

                    loadCheckBoxState();//記錄下當(dāng)前用戶記住密碼和自動(dòng)登錄的狀態(tài);
                    Intent i = new Intent(LoginByPhone.this,Call_Monitor.class);
                    i.putExtra(Config.KEY_TOKEN,token);
                    i.putExtra(Config.KEY_PHONE_NUM, etPhone.getText().toString());
                    startActivity(i);
                    finish();
                }
            }, new Login.FailCallback(){
                @Override
                public void onFail(){
                    setLoginBtnClickable(true);  //這里解放登錄按鈕,設(shè)置為可以點(diǎn)擊
                    pd.dismiss();
                    Toast.makeText(LoginByPhone.this,R.string.fail_to_login,Toast.LENGTH_LONG).show();
                }
            });

        }
    };
    loginRunnable.start();
}

ProgressDialog可設(shè)可不設(shè),但是考慮到有些人的網(wǎng)絡(luò)情況不好,所以給用戶點(diǎn)友好體驗(yàn)還是蠻重要的。所以還是加上吧。
new一個(gè)Thread(),在其中實(shí)現(xiàn)網(wǎng)絡(luò)請求將用戶名和密碼傳輸給后臺(tái)并獲取結(jié)果。
這個(gè)網(wǎng)絡(luò)封裝類用的是HttpUrlConnection,自己寫一個(gè)NetConnection封裝好基本網(wǎng)絡(luò)請求,這樣之后關(guān)于字符串和json的網(wǎng)絡(luò)請求就不用每次都這樣重新寫了。

public class NetConnection {

private static String TAG="netConnection: ";

public NetConnection(final String url,final HttpMethod method,final SuccessCallback successCallback,final FailCallback failCallback,final String...kvs ){

    new AsyncTask<Void, Void, String>(){
        @Override
        protected String doInBackground(Void... voids) {

            StringBuffer paramsStr = new StringBuffer();

            for (int i = 0; i <kvs.length ; i+=2) {
                paramsStr.append(kvs[i]).append("=").append(kvs[i+1]).append("&");
            }

            try{
                HttpURLConnection uc;

                switch (method){
                    case POST:
                        uc = (HttpURLConnection)new URL(url).openConnection();
                        System.out.println(uc);
                        // 顯示開啟請求體
                        uc.setDoInput(true);
                        uc.setDoOutput(true);

                        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(uc.getOutputStream(), Config.CHARSET));
                        bw.write(paramsStr.toString());
                        bw.flush();
                        bw.close();
                        break;
                    default:
                        uc = (HttpURLConnection) new URL(url+"?"+ paramsStr.toString()).openConnection();
                        break;
                }

                BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream(),Config.CHARSET));

                if(uc.getResponseCode() == 200){
                    String line = null;
                    StringBuffer result = new StringBuffer();
                    while((line=br.readLine())!=null){
                        result.append(line);
                    }
                    return result.toString();
                } else if( uc.getResponseCode() == 404){
                    Log.i(TAG,"404訪問服務(wù)器失敗");
                } else if( uc.getResponseCode() == 500 ){
                    Log.i(TAG,"500服務(wù)器拒絕訪問");
                }

            } catch (MalformedURLException e){
                e.printStackTrace();
            } catch (IOException e){
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {

            if (result!= null) {
                successCallback.onSuccess(result);
            } else {
                if(failCallback!=null){
                    failCallback.onFail();
                }
            }

            super.onPostExecute(result);
        }

    }.execute();
}

public static interface SuccessCallback{
    void onSuccess(String result);
}

public static interface FailCallback{
    void onFail();
}

}
兩個(gè)接口記得寫哦。
Login網(wǎng)絡(luò)請求類如下

public class Login {
public Login(String phone, String password, final SuccessCallback successCallback, final FailCallback failCallback){
new NetConnection(Config.SVERVICE_URL, HttpMethod.POST, new NetConnection.SuccessCallback() {
@Override
public void onSuccess(String result) {
try {
JSONObject obj = new JSONObject(result);
switch (obj.getInt(Config.KEY_STATUS)){
case Config.RESULT_STATUS_SUCCESS:
System.out.println(successCallback);
if(successCallback!=null){
successCallback.onSuccess(obj.getString(Config.KEY_TOKEN));
}
break;
default:
if(failCallback!=null){
failCallback.onFail();
}
break;
}

            } catch (JSONException e) {
                e.printStackTrace();
                if(failCallback!=null){
                    failCallback.onFail();
                }
            }
        }
    }, new NetConnection.FailCallback() {
        @Override
        public void onFail() {
            if(failCallback!=null){
                failCallback.onFail();
            }
        }
    },Config.PHONE_NUM,phone,Config.PASS_WORD,password);
}

public static interface SuccessCallback{
    void onSuccess(String token);
}

public static interface FailCallback{
    void onFail();
}

}
這樣其實(shí)登錄基本功能就好了。其他的都是關(guān)于記住密碼啊之類的了。
本地保存密碼用到的是SharedPreferences, 我自己封裝的如下:

public class SharedPreferencesUtils {
//定義一個(gè)SharePreference對象
SharedPreferences sharedPreferences;
//定義一個(gè)上下文對象

//創(chuàng)建SharePreference對象時(shí)要上下文和存儲(chǔ)的模式
//通過構(gòu)造方法傳入一個(gè)上下文
public SharedPreferencesUtils(Context context, String fileName) {
    //實(shí)例化SharePreference對象,使用的是get方法,而不是new創(chuàng)建
    //第一個(gè)參數(shù)是文件的名字
    //第二個(gè)參數(shù)是存儲(chǔ)的模式,一般都是使用私有方式:Context.MODE_PRIVATE
    sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
}

/**
 * 存儲(chǔ)數(shù)據(jù)
 * 這里要對存儲(chǔ)的數(shù)據(jù)進(jìn)行判斷在存儲(chǔ)
 * 只能存儲(chǔ)簡單的幾種數(shù)據(jù)
 * 這里使用的是自定義的ContentValue類,來進(jìn)行對多個(gè)數(shù)據(jù)的處理
 */
//創(chuàng)建一個(gè)內(nèi)部類使用,里面有key和value這兩個(gè)值
public static class ContentValue {
    String key;
    Object value;

    //通過構(gòu)造方法來傳入key和value
    public ContentValue(String key, Object value) {
        this.key = key;
        this.value = value;
    }
}

//一次可以傳入多個(gè)ContentValue對象的值
public void putValues(ContentValue... contentValues) {
    //獲取SharePreference對象的編輯對象,才能進(jìn)行數(shù)據(jù)的存儲(chǔ)
    SharedPreferences.Editor editor = sharedPreferences.edit();
    //數(shù)據(jù)分類和存儲(chǔ)
    for (ContentValue contentValue : contentValues) {
        //如果是字符型類型
        if (contentValue.value instanceof String) {
            editor.putString(contentValue.key, contentValue.value.toString()).commit();
        }
        //如果是int類型
        if (contentValue.value instanceof Integer) {
            editor.putInt(contentValue.key, Integer.parseInt(contentValue.value.toString())).commit();
        }
        //如果是Long類型
        if (contentValue.value instanceof Long) {
            editor.putLong(contentValue.key, Long.parseLong(contentValue.value.toString())).commit();
        }
        //如果是布爾類型
        if (contentValue.value instanceof Boolean) {
            editor.putBoolean(contentValue.key, Boolean.parseBoolean(contentValue.value.toString())).commit();
        }

    }
}


//獲取數(shù)據(jù)的方法
public String getString(String key) {
    return sharedPreferences.getString(key, null);
}

public boolean getBoolean(String key, Boolean b) {
    return sharedPreferences.getBoolean(key, b);
}

public int getInt(String key) {
    return sharedPreferences.getInt(key, -1);
}

public long getLong(String key) {
    return sharedPreferences.getLong(key, -1);
}

//清除當(dāng)前文件的所有的數(shù)據(jù)
public void clear() {
    sharedPreferences.edit().clear().commit();
}

}

其他好像沒啥可講的了,都在代碼中。大家有想要了解的,可以私我。

服務(wù)器端:
controllers/android/login.js


image.png

models/android/login.js


image.png

順便講一下服務(wù)器端的路由邏輯,
main.js中聲明路由路徑是根目錄到controllers


image.png

在controllers/android.js中再配置一次controllers里面路由的路徑


image.png

沒什么難的。大家不懂私我吧~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容