Android数据存储方案

文件存储

Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定文件中。
第一个参数是文件名
第二个参数是文件的操作模式

文件默认会存储到/data/data/package name/files/目录下

MainActivity.java

package com.zhoujian.persistentdata;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class MainActivity extends AppCompatActivity
{

    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 = loadData();
        if (!TextUtils.isEmpty(inputText))
        {
            edit.setText(inputText);
            edit.setSelection(inputText.length());
            Toast.makeText(this, "恢复数据成功", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        String inputText = edit.getText().toString();
        saveData(inputText);
    }

    public void saveData(String inputText)
    {
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try
        {
            //MODE_PRIVATE:默认模式,表示当指定同样文件名的时候,所写的内容将会覆盖原文件中的内容
            //MODE_APPEND:表示如果文件存在,就往文件里追加内容,不存在就创建
            out = openFileOutput("file", 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 loadData()
    {
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder sb = new StringBuilder();
        try
        {
            in = openFileInput("file");
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine()) != null)
            {
                sb.append(line);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (reader != null)
            {
                try
                {
                    reader.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}

Demo下载:https://github.com/zeke123/PersistentData

SharedPreferences 存储

SharedPreferences是采用键值对的方式存储数据的

点击CheckBox,用SharedPreferences存储数据,记住用户名和密码

LoginActivity.java


package com.zhoujian.sharedPreferences;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class LoginActivity extends BaseActivity
{

    private SharedPreferences pref;

    private SharedPreferences.Editor editor;

    private EditText mAccount;

    private EditText mPassword;

    private Button login;

    private CheckBox mCheckBox;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        pref = PreferenceManager.getDefaultSharedPreferences(this);
        mAccount = (EditText) findViewById(R.id.account);
        mPassword = (EditText) findViewById(R.id.password);
        mCheckBox = (CheckBox) findViewById(R.id.remember_pass);
        login = (Button) findViewById(R.id.login);
        boolean isRemember = pref.getBoolean("remember_password", false);
        if (isRemember) {
            // 将账号和密码都设置到文本框中
            String account = pref.getString("account", "");
            String password = pref.getString("password", "");
            mAccount.setText(account);
            mPassword.setText(password);
            mCheckBox.setChecked(true);
        }
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String account = mAccount.getText().toString();
                String password = mPassword.getText().toString();
                // 如果账号是123456且密码是123456,就认为登录成功
                if (account.equals("123456") && password.equals("123456")) {
                    editor = pref.edit();
                    if (mCheckBox.isChecked()) {
                        // 检查复选框是否被选中
                        editor.putBoolean("remember_password", true);
                        editor.putString("account", account);
                        editor.putString("password", password);
                    } else {
                        editor.clear();
                    }
                    editor.apply();
                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(LoginActivity.this, "账号或者密码错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

Demo下载:https://github.com/zeke123/SharedPreferences

SQLite数据库存储

创建数据库

在mac上查看数据库的工具:SQLPro for SQLite

数据库文件位于:/data/data/package name/databases/目录下

MyDatabaseHelper.java

package com.zhoujian.sqlitedemo;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

public class MyDatabaseHelper extends SQLiteOpenHelper {


    private Context mContext;

    //integer:表示整型
    //text:表示文本型
    //real:表示浮点型
    //blob:表示二进制类型

    public static final String CREATE_BOOK = "create table Book ("
            + "id integer primary key autoincrement, "
            + "author text, "
            + "price real, "
            + "pages integer, "
            + "name text)";

    public static final String CREATE_CATEGORY = "create table Category ("
            + "id integer primary key autoincrement, "
            + "category_name text, "
            + "category_code integer)";



    public MyDatabaseHelper(Context context, String name,
                            SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "创建数据库成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        //当数据库升级的时候,如果表存在,会先删除表,然后重新创建
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db);
    }

}

增删改查

MainActivity.java

package com.zhoujian.sqlitedemo;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity
{

    private MyDatabaseHelper dbHelper;
    private SQLiteDatabase mDb;
    private Button mCreateDatabase;
    private Button mAddData;
    private Button mQueryButton;
    private Button mDeleteButton;
    private Button mUpdateData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHelper = new MyDatabaseHelper(this, "Book.db", null, 1);
        initViews();
        clickEvents();
    }

    private void initViews()
    {
        mCreateDatabase = (Button) findViewById(R.id.create_database);
        mAddData = (Button) findViewById(R.id.add_data);
        mQueryButton = (Button) findViewById(R.id.query_data);
        mDeleteButton = (Button) findViewById(R.id.delete_data);
        mUpdateData = (Button) findViewById(R.id.update_data);
    }
    private void clickEvents()
    {
        mCreateDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //getReadableDatabase():如果磁盘已满,将以只读的方式打开数据库
                //getWritableDatabase():如果磁盘已满,将出现异常

                mDb = dbHelper.getWritableDatabase();
            }
        });

        mAddData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mDb!=null){
                    ContentValues values = new ContentValues();
                    // 插入第一条数据
                    values.put("name", "Android开发艺术探索");
                    values.put("author", "任玉刚");
                    values.put("pages", 494);
                    values.put("price", 65.5);
                    mDb.insert("Book", null, values);
                    values.clear();
                    // 插入第二条数据
                    values.put("name", "第一行代码");
                    values.put("author", "郭霖");
                    values.put("pages", 510);
                    values.put("price", 75);
                    mDb.insert("Book", null, values);
                    values.clear();
                    // 插入第三条数据
                    values.put("name", "疯狂Android讲义");
                    values.put("author", "李刚");
                    values.put("pages", 580);
                    values.put("price", 85);
                    mDb.insert("Book", null, values);


                    Toast.makeText(MainActivity.this, "添加数据成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this, "请先创建数据库", Toast.LENGTH_SHORT).show();
                }
            }
        });

        mUpdateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mDb!=null){

                    //把Android开发艺术探索这本书的价格改为70
                    ContentValues values = new ContentValues();
                    values.put("price", 70);
                    mDb.update("Book", values, "name = ?", new String[] { "Android开发艺术探索" });
                    Toast.makeText(MainActivity.this, "更新数据成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this, "请先创建数据库", Toast.LENGTH_SHORT).show();
                }
            }
        });

        mDeleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mDb!=null){
                    //删除页数大于500的书籍
                    mDb.delete("Book", "pages > ?", new String[] { "500" });
                    Toast.makeText(MainActivity.this, "删除数据成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this, "请先创建数据库", Toast.LENGTH_SHORT).show();
                }
            }
        });

        mQueryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(mDb!=null){

                    // 查询Book表中所有的数据
                    Cursor cursor = mDb.query("Book", null, null, null, null, null, null);
                    if (cursor.moveToFirst()) {
                        do {
                            // 遍历Cursor对象,取出数据并打印
                            String name = cursor.getString(cursor.getColumnIndex("name"));
                            String author = cursor.getString(cursor.getColumnIndex("author"));
                            int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                            double price = cursor.getDouble(cursor.getColumnIndex("price"));
                            Log.d("MainActivity", "书籍的名字: " + name);
                            Log.d("MainActivity", "书籍的作者: " + author);
                            Log.d("MainActivity", "书籍的页数: " + pages);
                            Log.d("MainActivity", "书籍的价格:" + price);
                        } while (cursor.moveToNext());
                    }
                    cursor.close();
                    Toast.makeText(MainActivity.this, "查询数据成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this, "请先创建数据库", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

Demo下载:https://github.com/zeke123/SqliteDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,085评论 2 44
  • 做梦的年龄里 我没有做过一个梦 写诗的年龄里 我没有写过一首诗 我以为 一切烦恼都出自自己 一切的痛苦 皆起自青春...
    湘中布衣秀才阅读 267评论 0 0
  • 我想要对你们这些有对象的男男女女们说些心:请不要再来问我XX节怎么过!虽然在过去的一年里我…… 但这是因为我对这些...
    葡萄动画阅读 165评论 0 0
  • 以Python内置的求绝对值的函数abs()为例 变量f现在已经指向了abs函数本身。直接调用abs()函数和调用...
    于连林520wcf阅读 278评论 0 1