Android數據持久化之記住密碼功能實現(附源碼)

效果演示:

源碼: https://github.com/junzaivip/SharePreferencesDemo

手機安裝演示鏈接: http://pan.baidu.com/s/1dFvbDdB 密碼:y8p8

其實我們在社交網絡上面所發出的任何信息, 都希望能夠保留下來. 那么如何實現呢?

數據持久化

數據持久化, 就是將內存中的瞬時數據保存在存儲設備中, 保證即便關機之后, 數據仍然存在.

保存在內存中的數據是瞬時數據, 保存在存儲設備中的數據就是處于持久狀態的.

持久化技術則是提供了一種機制可以讓數據在瞬時狀態和持久狀態之間進行轉換, Android系統中主要提供了3種方式用于簡單地實現數據持久化功能, 即文件存儲, SharePreference存儲, 以及數據庫存儲. 當然你也可以將數據保存在手機的SD卡中.

文件存儲

文件存儲是android中最基本的一種數據存儲方式, 它不對存儲的內容進行任何的格式化處理, 所有的數據都是原封不動地保存到文件當中, 因為他比較適合存儲一些簡單的文本數據或二進制數據. 如果你希望使用文件存儲的方式來保存一些較為復雜的的文本數據, 就需要定義一套自己的格式規范, 這樣可以方便之后將數據從文件中重新取出來.

將數據存儲在文件中

Context類中提供了一個openFileOutput()方法, 可以用于將數據存儲在指定的文件中. 這個方法接收兩個參數,

第一個參數是文件名, 在文件創建的時候使用的就是這個名稱, 注意這里指定的文件名不可以包含路徑的. 因為所有的文件都是默認存儲到/data/data/<package name>/files/目錄下.

第二個參數是文件的操作模式, 主要有兩種模式可以選, MODE_PRIVATE和MODE_APPEND. 其中MODE_PRIVATE是默認的操作模式, 表示當指定同樣文件名的時候, 所寫入的內容將會覆蓋原文件中的內容. 而MODE_APPEND則表示如果該文件已存在, 就往文件里面追加內容, 不存在就創建新文件.

openFileOutput()方法返回的是一個FileOutputStream對象, 得到了這個對象之后就可以使用java流的方式將數據寫入到文件中了.

public void save(){
        String data = "Data to save";
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            out = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(data);
        }catch (IOException e) {
            e.printStackTrace();
        } finally {
           try {
               if(writer!= null){
                   writer.close();
               }
           } catch (IOException e) {
               e.printStackTrace();
           }
        }
    }

說明: 通過openFileOutput()方法能夠得到一個FileOutputStream對象, 然后再借助它構建出一個OutputStreamWriter對象, 接著再使用OutputStreamWriter構建出一個BufferedWriter對象, 這樣就可以通過BufferedWriter來講文本內容寫入到文件中了.

下面我們來一個完整的例子來理解一下,當我們在退出程序之前, 將我們在文本框中輸入的內容儲存在文件中.

新建項目FilePersistenceDemo項目, 且修改activity_main.xml中的代碼.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
  >
    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

說明: 界面只有一個EditText文本框.

MainActivity.java文件:

public class MainActivity extends AppCompatActivity {
    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //獲取editText實例
        editText = (EditText)findViewById(R.id.edit);
    }

    // 重寫onDestroy(), 可以保證活動銷毀之前一定會調用這個方法.
    @Override
    protected void onDestroy() {
        super.onDestroy();
        String inputText = editText.getText().toString();
        save(inputText);
    }

    public void save (String inputText){
        FileOutputStream out = null;
        BufferedWriter writer = null;

        try {
            out = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                  if(writer!= null) {
                      writer.close();
                  }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

那么我們運行程序, 我們輸入的內容就會保存在文件中. 如果您的手機已經Root了, 可以直接在 應用程序的包名/files目錄就可以發現.

從文件中讀取數據

核心代碼:

public String load (){
        FileInputStream in = null;
        BufferedReader reader =  null;
        StringBuilder content = new StringBuilder();
        try {
            //獲取FileInputStream對象
            in = openFileInput("data");
            //借助FileInputStream對象, 構建出一個BufferedReader對象
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            //通過BufferedReader對象進行一行行的讀取, 把文件中的所有內容全部讀取出來
            // 并存放在StringBuilder對象中
            while ((line = reader.readLine())!= null){
                content.append(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //最后將讀取到的內容返回
        return  content.toString();
    }

修改我們MainActivity中的代碼:

public class MainActivity extends AppCompatActivity {
    private EditText editText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //獲取editText實例
        editText = (EditText)findViewById(R.id.edit);
        String inputText = load();
//TextUtils.isEmpty()可以一次性判斷兩種非空判斷 傳入null或者空, 都返回true
        if(!TextUtils.isEmpty((inputText))){
            editText.setText(inputText);
            //setSelection()表示將光標移動在文本框的末尾位置, 以便繼續輸入
            editText.setSelection(inputText.length());
            //彈出Toast, 給出一個提示, 表示讀取數據成功
            Toast.makeText(this, "讀取數據成功!", Toast.LENGTH_SHORT).show();
        }
    }

    // 重寫onDestroy(), 可以保證活動銷毀之前一定會調用這個方法.
    @Override
    protected void onDestroy() {
        super.onDestroy();
        String inputText = editText.getText().toString();
        save(inputText);
    }

    public void save (String inputText){
        FileOutputStream out = null;
        BufferedWriter writer = null;

        try {
            out = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                  if(writer!= null) {
                      writer.close();
                  }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    public String load (){
        FileInputStream in = null;
        BufferedReader reader =  null;
        StringBuilder content = new StringBuilder();
        try {
            //獲取FileInputStream對象
            in = openFileInput("data");
            //借助FileInputStream對象, 構建出一個BufferedReader對象
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            //通過BufferedReader對象進行一行行的讀取, 把文件中的所有內容全部讀取出來
            // 并存放在StringBuilder對象中
            while ((line = reader.readLine())!= null){
                content.append(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //最后將讀取到的內容返回
        return  content.toString();
    }
}

效果演示

源碼: https://github.com/junzaivip/FilePersistenceDemo

SharedPreferences存儲

不同于文件的存儲方式, haredPreferences是使用鍵值對的方式來存儲數據的. 而且支持多種不同的數據類型存儲, 如果存儲的是整型, 那么讀取出來也是整型. 如果存儲的是字符串, 那么讀取出來也是字符串.

將數據存儲到SharedPreferences中

如果希望使用SharePreferences來存儲數據, 首先需要獲取到SharePreferences對象.Android中提供了三種方法來獲取SharePreferences對象.

Context類中getSharePreferences()方法

此方法接收兩個參數, 第一個參數用于指定SharedPreferences文件的名稱, 如果指定的文件不存在則會創建一個.SharePreferences文件都是存放在/data/data/<package name>/shared_prefs/

第二個參數用于指定操作模式, 目前只可以使用MODE_PRIVATE這一種模式, 和直接傳入0效果是相同的. 表示只有當前的應用程序才可以對這個SharePreferences文件進行讀寫.

Activity類中getSharePreferences()方法

這個方法和Context中的getSharePreferences()方法很相似, 它只接收一個操作模式參數, 因為使用這個方法時, 會自動將當前活動的類名作為SharePreferences的文件名.

PreferenceManager類中的getDefaultSharePreferences()方法

這是一個靜態方法, 它接收一個Context參數, 并自動使用當前應用程序的包名作為前綴來命名SharePreferences文件. 得到SharePreferences對象之后, 就開始向SharedPreferences文件中存儲數據了.

  1. 調用SharePreferences對象的edit()方法來獲取一個SharePreferences.Editor對象

  2. 想SharedPreferences.Editor對象中添加數據, 比如添加一個布爾型數據就可以使用putBoolean()方法, 添加一個字符串使用putString()方法等

  3. 調用apply()方法將添加的數據提交, 從而完成數據存儲操作.

現在開始新建一個SharePreferencesDemo項目, 然后修改activity_main.xml中的代碼.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/save_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save Data"/>
</LinearLayout>

MainActivity中的代碼:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button saveData = (Button)findViewById(R.id.save_data);
        saveData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
                editor.putString("name","junzai");
                editor.putInt("age",18);
                editor.putBoolean("married", false);
                editor.apply();
            }
        });
    }
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/save_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save Data"/>
    <Button
        android:id="@+id/restore_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="restore data"/>
</LinearLayout>
Button restoreData = (Button) findViewById(R.id.restore_data);
        restoreData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences pref = getSharedPreferences("jun_zai",MODE_PRIVATE);
                String name = pref.getString("name","");
                int age = pref.getInt("age",0);
                boolean married = pref.getBoolean("married", false);
                Log.d("MainActivity","name is " + name);
                Log.d("MainActivity","age is " + age);
                Log.d("MainActivity","married is " + married);
            }
        });

運行效果:

成功將數據取出.

下面實現記住密碼的功能:

Login.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:text="User Name"
            android:textSize="18sp"
            android:layout_gravity="center_vertical"/>
        <EditText
            android:id="@+id/account"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
           />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:text="Password"
            android:textSize="18sp"
            android:layout_gravity="center_vertical"/>
        <EditText
            android:id="@+id/password"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:inputType="textPassword"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <CheckBox
            android:id="@+id/remember_pass"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:textSize="18sp"
            android:text="Remember Password"/>
   </LinearLayout>

    <Button
        android:id="@+id/login"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="Login"/>
</LinearLayout>

LoginActivity中的代碼:

public class LoginActivity  extends BaseActivity implements View.OnClickListener{
    private EditText userName;
    private EditText passWord;
    private Button login;
    private SharedPreferences pref;
    private SharedPreferences.Editor editor;
    private CheckBox remberPass;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //獲取SharedPreferences對象
        pref = PreferenceManager.getDefaultSharedPreferences(this);
        userName = (EditText)findViewById(R.id.account);
        passWord = (EditText)findViewById(R.id.password);
        login = (Button) findViewById(R.id.login);
        login.setOnClickListener(this);

        //調用getBoolean()方法去獲取remember_password這個鍵對應的值, 如果不存在默認的值, 就是用的是false
        boolean isRemember = pref.getBoolean("remember_password", false);
        remberPass = (CheckBox)findViewById(R.id.remember_pass);

        if(isRemember){
            //賬號和密碼都設置到文本框
            String username = pref.getString("username","");
            String password = pref.getString("password","");

            userName.setText(username);
            passWord.setText(password);
            remberPass.setChecked(true);

        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.login:
                String username = userName.getText().toString();
                String password = passWord.getText().toString();
                if(username.equals("admin") && password.equals("123")){
                    // 將數據存儲在SharedPreferences當中
                    editor = pref.edit();
                    if(remberPass.isChecked()){ // 檢驗復選框是否被選中
                        // 如果被選中, remember_password的值改為True
                        editor.putBoolean("remember_password", true);
                        editor.putString("username",username);
                        editor.putString("password", password);
                    } else{
                        editor.clear();
                    }
                    editor.apply();

                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                    startActivity(intent);
                    finish();

                } else{
                    Toast.makeText(this, "賬號或者密碼錯誤", Toast.LENGTH_SHORT).show();
                }

        }

    }
}

效果演示:

Android數據持久化之記住密碼功能實現(附源碼)

 

 

來自:http://www.jianshu.com/p/396bdbf55449

 

 本文由用戶 AliMacdonel 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!