《第一行代码》读书笔记(六)----持久化(上)

简介

数据持久化是指将内存中的瞬时数据保存到存储设备中, 保证即使在手机或电脑关机的情况下数据也不会丢失.
Android系统中主要提供了三种持久化方式, 即文件存储, SharedPreferences 存储和数据库存储. 此外, 还可以将数据保存在SD卡中, 不过使用前面三种方式更简单也更安全.

文件存储

这种方式不会对存储的内容进行任何的格式化处理, 所有数据都原封不动保存到文件当中. 因而比较适合用于存储一些简单的文本数据或二进制数据.

将数据存储到文件中

Context 类中提供了一个openFileOutput()方法, 用于将数据存储到指定的文件中. 该方法接收两个参数, 第一个是文件名(不可以包含路径, 因为默认存储到/data/data/<packagename>/files/目录下), 第二个是文件的操作模式. MODE_PRIVATE(默认, 指定同名文件时, 所写内容将会覆盖原文件中的内容) 和 MODE_APPEND(如果该文件存在就往文件里追加内容, 不存在就创建文件).
openFileOutput()方法返回的是一个 FileOutputStream 对象, 得到这个对象后就可以用Java流的方式将数据写入到文件中了.

新建一个项目, 首先修改 activity_main , 定义一个 EditText .
然后修改 MainActivity :

public class MainActivity extends Activity {

    private EditText edit;

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

        edit = (EditText) findViewById(R.id.edit);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        String inputText = edit.getText().toString();
        save(inputText);
    }

    private 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();
            }
        }
    }
}

运行程序. 活动销毁时会自动将输入的数据保存到data文件中. 怎么查看? Android Studio 中在工具栏有一个 green robot, ADM.

从文件中读取数据

Context 类还提供了一个openFileInput()方法, 用于从文件中读取数据. 只接受一个参数, 即文件名. 系统会自动到/data/data/<packagename>/files/目录下去加载这个文件, 并返回一个 FileInputStream 对象, 再通过Java流的方式就可以将数据读取出来了.
使上一个程序启动时EditText能够保留上次输入的内容.
修改 MainActivity :

public class MainActivity extends Activity {

    private EditText edit;

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

        edit = (EditText) findViewById(R.id.edit);

        String inputText = load();
        //TextUtils.isEmpyty(): 传入字符等于null或者等于空串时, 返回true.
        if (!TextUtils.isEmpty(inputText)) {
            edit.setText(inputText);
            edit.setSelection(inputText.length());//将光标移动到文本末尾
            Toast.makeText(this, "Restoring succeeded", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        String inputText = edit.getText().toString();
        save(inputText);
    }

    private 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();
            }
        }
    }

    private String load() {
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder content = new StringBuilder();

        try {
            in = openFileInput("data");
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine()) != null) {
                content.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return content.toString();
    }
}

SharedPreferences 存储

不同于文件存储, SharedPreferences 使用键值对的形式来存储数据. 通过键可以把相应的值取出来. 文件以 XML 格式对数据进行管理, 存储到/data/data/<packagename>/shared_prefs/目录下.

将数据存储到 SharedPreferences 中

首先, 要获取到 SharedPreferences 对象. Android中主要有三种方法:
* Context类中的 getSharedPreferences() 方法.
* 该方法需要两个参数, 第一个是文件名, 第二个指定操作模式, 可选 MODE_PRIVATE(默认, 也可直接传入0, 表示只有当前程序才可以读取该文件)和 MODE_MULTI_PROCESS(一般用于会有多个进程中对同一个文件进行读写的情况).
* Activity类中的 getPreferences() 方法.
* 只接收一个参数, 即操作模式. 会自动将当前活动的类名作为文件名.
* PreferenceManager类中的 getDefaultSharedPreferences() 方法.
* 静态方法, 只接受一个Context参数, 使用当前程序的包名作为前缀来命名文件.

得到 SharedPreferences 对象之后, 就可以向 SP 文件中存储数据了. 分为3步:
1, 调用 SharedPreferences 对象的 edit() 方法来获取一个 SharedPreferences.Editor 对象.
2, 向 SharedPreferences.Editor 对象添加数据. 利用put[Type]()方法.
3, 调用 commit() 方法将添加的数据提交, 完成存储操作.

新建一个项目, 在 activity_main.xml 文件中放置一个按钮.
然后修改 MainActivity 代码:

public class MainActivity extends Activity {

    private Button saveData;

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

        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", "Eric");
                editor.putInt("age", 23);
                editor.putBoolean("married", false);

                editor.commit();
            }
        });
    }
}

从 SharedPreferences 中读取数据

通过get[Type]()方法来读取数据. 这一系列方法接收两个参数, 第一个是键, 第二个是默认值, 即根据键找不到值时返回的值.
修改activity_main.xml, 再添加一个按钮, 用于读取数据.
然后修改 MainActivity 的代码, 为刚才定义的按钮添加点击事件:

restoreData.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SharedPreferences preferences = getSharedPreferences("data", MODE_PRIVATE);
        String name = preferences.getString("name", "");
        int age = preferences.getInt("age", 0);
        boolean married = preferences.getBoolean("married", false);

        Log.d("MainActivity", "name is " + name);
        Log.d("MainActivity", "age is " + age);
        Log.d("MainActivity", "married is " + married);
    }
});

实现记住密码功能

修改上一章 BroadcastBP 项目的代码.
修改login.xml:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:stretchColumns="1">

    <TableRow>

        <TextView
            android:layout_height="wrap_content"
            android:text="Account:" />

        <EditText
            android:id="@+id/account"
            android:layout_height="wrap_content"
            android:hint="Input your account" />
    </TableRow>

    <TableRow>

        <TextView
            android:layout_height="wrap_content"
            android:text="Password:" />

        <EditText
            android:id="@+id/password"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    </TableRow>

    <TableRow>

        <CheckBox
            android:id="@+id/remember_pass"
            android:layout_height="wrap_content" />

        <TextView
            android:layout_height="wrap_content"
            android:text="Remember password" />
    </TableRow>

    <TableRow>

        <Button
            android:id="@+id/login"
            android:layout_height="wrap_content"
            android:layout_span="2"
            android:text="Login" />
    </TableRow>

</TableLayout>

然后修改 MainActivity :

public class LoginActivity extends BaseActivity {

    private SharedPreferences pref;
    private SharedPreferences.Editor editor;

    private EditText accountEdit;
    private EditText passwordEdit;
    private Button login;
    private CheckBox rememberPass;

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

        pref = PreferenceManager.getDefaultSharedPreferences(this);

        accountEdit = (EditText) findViewById(R.id.account);
        passwordEdit = (EditText) findViewById(R.id.password);
        login = (Button) findViewById(R.id.login);
        rememberPass = (CheckBox) findViewById(R.id.remember_pass);

        boolean isRemember = pref.getBoolean("remember_password", false);

        if (isRemember) {
            //将账号和密码都设置到文本框中
            String account = pref.getString("account", "");
            String password = pref.getString("password", "");
            accountEdit.setText(account);
            passwordEdit.setText(password);
            rememberPass.setChecked(true);
        }

        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String account = accountEdit.getText().toString();
                String password = passwordEdit.getText().toString();

                if (account.equals("admin") && password.equals("123456")) {
                    editor = pref.edit();
                    if (rememberPass.isChecked()) {
                        editor.putBoolean("remember_password", true);
                        editor.putString("account", account);
                        editor.putString("password", password);
                    } else {
                        editor.clear();
                    }
                    editor.commit();

                    startActivity(new Intent(LoginActivity.this, MainActivity.class));
                    finish();
                } else {
                    Toast.makeText(LoginActivity.this,
                            "account or password is invalid", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值