参考:《第一行代码》
Android系统主要提供三种实现数据持久化功能的方法:
1、文件存储 2、SharedPreference存储 3、数据库存储
你还可以存储在手机的SD卡内,不过上面三个方法比较安全。


文件存储

向文件中写入数据

Context类提供了一个openFileOutput()方法,可以将数据存储到特定的文件,第一个参数是文件名,第二个参数是文件的操作模式MODE_PRIVATE表示当指定同样文件名的时候,所写入的内容将会覆盖元文件 还有MODE_APPEND表示如果在该文件,只是在后面追加就可以,不必创建新文件
下面是代码示例,实现当退出程序时,编辑的数据存储到文件中

public class FileSaveActivity extends Activity {
    private EditText edit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.file_save);
        edit = (EditText) findViewById(R.id.et_save);
    }

    @Override
    // 当退出程序,也就是销毁Activity的时候保存数据
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        String inputText = edit.getText().toString();
        save(inputText);
    }

    public void save(String inputText) {
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            // MODE_PRIVATE表示当指定同样文件名的时候,所写入的内容将会覆盖元文件
            // 还有MODE_APPEND表示如果在该文件,只是在后面追加就可以,不必创建新文件
            out = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);
        } catch (Exception e) {
            e.printStackTrace();

        } finally {

            try {
                if (writer != null)
                    writer.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

从文件中读取数据

Context类还提供一个openFileInput()方法,用于从文件中读取数据,只有一个参数,即是要读取的文件名,系统会自动到目录下加载该文件,并返回一个FileInputStream对象,得到该对象后在通过Java流的方式将文件读取出来

public 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 (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return content.toString();

    }

SharedPreferences存储

SharedPreferences是使用键值对的方式来存储数据,也就保存一条数据,需要给这个数据提供一个对应的key,然后在读取的时候就根据这个key。Android提供三种方法用于得到SharedPreferences对象
1、Context类中的getSharePreferences()方法
该方法有两个参数,第一个是指定SharedPreferences文件的名称,第二个是操作模式,MODE_PRIVATEMODE_MUTIL_PROCESSMODE_PRIVATE默认的操作模式,表示只有当前的应用程序才才可以对该SharedPreferences文件进行读取。MODE_MUTIL_PROCESS一般用于会多个进程中对同一SharedPreferences文件进行读取的情况。
2、Activity类的getPreferences()方法
和上面的方法差不多,不过只接收一个操作模式参数,自动将当前活动的类名作为SharedPreferences文件名
3、PreferenceManager类的getDefaultSharePreferences()方法
通过上面三个方法得到SharePreferences对象就可以操作了,主要三步
1、调用SharePreferences对象的edit()方法来获取SharePreferences.Editor对象
2、向SharePreferences.Editor对象中添加数据
3、调用commit()方法将添加的数据进行提交,从而完成数据存储操作

SharedPreferences存储实例,实现记住密码功能

public class LoginActivity extends BaseActivity{

    private EditText accountEdit;

    private EditText passwordEdit;

    private Button login;

    private SharedPreferences sp;

    private SharedPreferences.Editor editor;

    private CheckBox rememberPass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        init();
        myListener();
    }
    public void init()
    {
        accountEdit=(EditText) findViewById(R.id.account);
        passwordEdit=(EditText) findViewById(R.id.password);
        login=(Button) findViewById(R.id.login);

        sp=PreferenceManager.getDefaultSharedPreferences(this);
        rememberPass=(CheckBox)findViewById(R.id.remember_pass);
        //第二个参数:如果第一次getBoolean时,如果key值检索不到,直接获取defvalue的值
        boolean isRemember=sp.getBoolean("remember_password", false);

        if(isRemember){
            //将账号和密码都设置在文本框
            String account=sp.getString("account","");
            String password=sp.getString("password","");

            accountEdit.setText(account);
            passwordEdit.setText(password);
            rememberPass.setSelected(true);
        }
    }
    private void myListener() {
        login.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                String account=accountEdit.getText().toString();
                String password=passwordEdit.getText().toString();
                if(account.equals("csdn")&&password.equals("123"))
                {
                    editor=sp.edit();
                    if(rememberPass.isChecked()==true)
                    {
                        editor.putBoolean("remember_password", true);
                        editor.putString("account",account);
                        editor.putString("password",password);
                    }else
                    {
                        editor.clear();
                    }

                    editor.commit();

                    Intent intent=new Intent(LoginActivity.this,MainActivity.class);
                    startActivity(intent);
                    //关掉当前活动
                    finish();
                }else{
                    Toast.makeText(LoginActivity.this, 
                            "账号或者密码输入不正确,请再次输入!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

SQLite数据库存储

创建数据库

android为了让我们更好的管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助这个类可以对数据进行创建和升级。由于SQLiteOpenHelper是个抽象类,所以我们要自己创建一个帮助类去实现他,有必须重写的两个抽象方法onCreate()onUpgrade()分别是实现创建和升级数据库的逻辑。一般在onCreate() 内实现表的创建SQLiteOpenHelper还有两个重要的实例方法,getReadableDatabase()和getWritableDatabase(),用于创建数据库或者打开现有的数据库,返回一个可对数据库进行读写的对象。
代码示例:

public class MyDatabaseHelper extends SQLiteOpenHelper{


    public static final String TAB_NAME = "tab_contact";
    public static final String COL_NAME = "name";
    public static final String COL_HXID = "hxid";
    public static final String COL_NICK = "nick";
    public static final String COL_PHOTO = "photo";
    public static final String COL_IS_CONTACT = "is_contact";

    public static final String CREATE_TAB = "create table " + TAB_NAME + " ("
            + COL_HXID + " text primary key," + COL_NAME + " text," + COL_NICK
            + " text," + COL_IS_CONTACT + " integer," + COL_PHOTO + " text);";

    private Context mContext;

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        db.execSQL(CREATE_TAB);
        Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
    }
}
public class CreatDBActivity extends Activity{
    private MyDatabaseHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.database_button);

        dbHelper=new MyDatabaseHelper(this, "Contact.db", null, 1);
        Button createDatabase=(Button) findViewById(R.id.create_database);

        createDatabase.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 实例SQLiteOpenHelper,他会调用onCreate()实现数据库的创建
                dbHelper.getWritableDatabase();
            }
        });
    }
}

升级数据库

因为之前已经存在表了,所以先让onUpgrade()方法执行,若存在表就删掉,这样就不报错

@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists tab_contact")
    }

要想让onUpgrade()方法执行,就要传入比以前数据库版本号大的树,比如前面是1,我们可以改为2

dbHelper=new MyDatabaseHelper(this, "Contact.db", null, 2);

增删改查

SQLite的增删改查不需要去编写SQL语句,前面调用SQLiteOpenHelper的getReadableDatabase()或getWriteDatabase()方法会返回一个SQLiteDatabase对象,我们可以使用这个对象进行增删改查。

* (一)insert()*里面需要传入三个参数,分别是1、表名,2、用于未指定添加数据的情况下给某些可为空的列自动赋值NULL,3、一个ContentValues对象,ContentValue类似List,将数据put进去,然后把对象传入

SQLiteDatabase db=dbHelper.getWritableDatabase();
ContentValues values=new ContentValues();
value.put("name","cdsn");
value.put("nick","zaiyunduan");
value.put("photo","apple");
db.insert("Contact.db",null,values);

然后要插入第二条数据,先values.clear( )清除掉,再添加
(二)update()四个参数分别,1、表名 2、一个ContentValues对象 3和4用于去约束某一行或几行的数据,不指定的话默认更新所有行

db.update("Contact.db",null,values,"name=?",new String[]{"csdn"});

意思是更新name为csdn这一行的数据
(三)delete()三个参数分别,1、表名 2和3用于去约束某一行或几行的数据,不指定的话默认删除所有行

db.update("Contact.db",null,values,"pages>?",new String[]{"500"});

(四)query()

android数据持久化存储方式 android 数据持久化_数据存储

List<InvationInfo> invitations=new ArrayList<>() ;

        SQLiteDatabase db = mHelper.getReadableDatabase();

        String sql="select * from "+InviteTable.TAB_NAME;

        Cursor cursor = db.rawQuery(sql, null);

        while (cursor.moveToNext()){

            InvationInfo invationInfo = new InvationInfo();

            invationInfo.setReason(cursor.getString(cursor.getColumnIndex(InviteTable.COL_REASON)));
            invationInfo.setStatus(intTOinvationStatus(cursor.getInt(cursor.getColumnIndex(InviteTable.COL_STATUS))));

            String groupId = cursor.getString(cursor.getColumnIndex(InviteTable.COL_GROUP_HXID));

                UserInfo userInfo = new UserInfo();

                userInfo.setHxid(cursor.getString(cursor.getColumnIndex(InviteTable.COL_USER_HXID)));
                userInfo.setName(cursor.getString(cursor.getColumnIndex(InviteTable.COL_USER_NAME)));
                userInfo.setNick(cursor.getString(cursor.getColumnIndex(InviteTable.COL_USER_NAME)));

                invationInfo.setUser(userInfo);