参考:《第一行代码》
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_PRIVATE和MODE_MUTIL_PROCESS。MODE_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()
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);