下面详细解释这四大方式的特点
第一种:文件存储数据
核心原理: Context提供了两个方法来打开数据文件里的文件IO流 FileInputStream openFileInput(String name); FileOutputStream(String name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。具体有以下值可选:
MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可 以使用Context.MODE_APPEND
MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;
MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
除此之外,Context还提供了如下几个重要的方法:
getDir(String name , int mode):在应用程序的数据文件夹下获取或者创建name对应的子目录
File getFilesDir():获取该应用程序的数据文件夹得绝对路径
String[] fileList():返回该应用数据文件夹的全部文件
实例:
核心代码:
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"
android:id="@+id/name"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:id="@+id/pwd"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:onClick="mybtn1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="读取"
android:onClick="mybtn2"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:textSize="35sp"
android:id="@+id/tv"/>
</LinearLayout>
activity中:
filename:
private String filename="info.txt";
保存:
public void mybtn1(View view) {
// TODO Auto-generated method stub
String Name=name.getText().toString();
String Pwd=pwd.getText().toString();
try {
//字节文件输出流是用于将数据写入到File
FileOutputStream fos=openFileOutput(filename, MODE_APPEND);
PrintWriter out=new PrintWriter(fos);
out.println(Name);
out.println(Pwd);
out.flush();
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.close();
name.setText("");
pwd.setText("");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
读取:
public void mybtn2(View view) {
// TODO Auto-generated method stub
try {
FileInputStream fis=openFileInput(filename);
//字节转换成字符流,再转换为缓冲字符流
BufferedReader br=new BufferedReader(new InputStreamReader(fis));
String line=null;
StringBuilder sb=new StringBuilder();
try {
while((line=br.readLine())!=null){
sb.append(line+"\n");
tv.setText(sb.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
效果图:
第二种:SD卡存储数据
其中读写步骤按如下进行:
1、调用Environment的getExternalStorageState()方法判断手机上是否插了sd卡,且应用程序具有读写SD卡的权限,如下代码将返回true
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
2、调用Environment.getExternalStorageDirectory()方法来获取外部存储器,也就是SD卡的目录,或者使用"/mnt/sdcard/"目录
3、使用IO流操作SD卡上的文件
注意点:手机应该已插入SD卡,对于模拟器而言,可通过mksdcard命令来创建虚拟存储卡
必须在AndroidManifest.xml上配置读写SD卡的权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
private String filename="my.txt";
保存:
public void mybtn1(View view) {
// TODO Auto-generated method stub
String Name=name.getText().toString();
String Pwd=pwd.getText().toString();
//1.判断SD可用否
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//2.获取路径
String path=Environment.getExternalStorageDirectory().getAbsolutePath();
//3.获取流对象进行读写操作
try {
PrintWriter out=new PrintWriter(new FileOutputStream(path+"/"+filename));
out.println(Name);
out.println(Pwd);
out.flush();
name.setText("");
pwd.setText("");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Toast.makeText(this, "SD卡不可用", 0).show();
}
}
读取:
public void mybtn2(View view) {
// TODO Auto-generated method stub
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//2.
String path=Environment.getExternalStorageDirectory().getAbsolutePath();
//3.
try {
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(path+"/"+filename)));
String line=null;
StringBuilder sb=new StringBuilder();
try {
while((line=br.readLine())!=null){
sb.append(line+"\n");
tv.setText(sb.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
name.setText("");
pwd.setText("");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
Toast.makeText(this, "SD卡不可用", 0).show();
}
}
效果图:
适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型、基本类型的值。比如应用程序的各种配置信息(如是否打开音效、是否使用震动效果、小游戏的玩家积分等),解锁口 令密码等
核心原理:保存基于XML文件存储的key-value键值对数据,通常用来存储一些简单的配置信息。通过DDMS的File Explorer面板,展开文件浏览树,很明显SharedPreferences数据总是存储在/data/data/<package name>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.edit()获取的内部接口Editor对象实现。 SharedPreferences本身是一 个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(String name, int mode)方法来获取SharedPreferences实例,该方法中name表示要操作的xml文件名,第二个参数具体如下:
Context.MODE_PRIVATE: 指定该SharedPreferences数据只能被本应用程序读、写。
Context.MODE_WORLD_READABLE: 指定该SharedPreferences数据能被其他应用程序读,但不能写。
Context.MODE_WORLD_WRITEABLE: 指定该SharedPreferences数据能被其他应用程序读,写
Editor有如下主要重要方法:
SharedPreferences.Editor clear():清空SharedPreferences里所有数据
SharedPreferences.Editor putXxx(String key , xxx value): 向SharedPreferences存入指定key对应的数据,其中xxx 可以是boolean,float,int等各种基本类型据
SharedPreferences.Editor remove(): 删除SharedPreferences中指定key对应的数据项
boolean commit(): 当Editor编辑完成后,使用该方法提交修改
实例:public void mybtn1(View view){
String Name=name.getText().toString();
String Pwd=pwd.getText().toString();
editor.putString("name", Name);
editor.putString("pwd", Pwd);
editor.putInt("count", 100);
editor.putBoolean("sound", true);
//提供修改之后的数据
editor.commit();
name.setText("");
pwd.setText("");
}
读取:
public void mybtn2(View view){
String n=sp.getString("name", "");
String p=sp.getString("pwd", "");
int c=sp.getInt("count", 0);
boolean b=sp.getBoolean("sound", false);
tv.setText("姓名:"+n+"\n"+"密码:"+p+"\n"+"次数:"+c+"\n"+"sound:"+b+"\n");
}
效果图:
SQLite是轻量级嵌入式数据库引擎,它支持 SQL 语言,并且只利用很少的内存就有很好的性能。现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧
SQLiteDatabase类为我们提供了很多种方法,上面的代码中基本上囊括了大部分的数据库操作,现在我写了数据库帮助类实现了数据库的创建和更新
实例:
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"
android:id="@+id/name"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:id="@+id/pwd"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:onClick="mybtn1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="读取"
android:onClick="mybtn2"/>
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lv"/>
</LinearLayout>
activity:
package com.example.fileapp;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class FourActivity extends Activity {
private EditText nameEt,pwdEt;
private ListView lv;
private MyOpenHelper helper;
//代表数据库对象
private SQLiteDatabase db;
public void mybtn1(View view){
String name=nameEt.getText().toString();
String pwd=pwdEt.getText().toString();
//try {
insert(db,name,pwd);
//} catch (Exception e) {
// create(db);
// insert(db,name,pwd);
//}
}
private void create(SQLiteDatabase db) {
String sql="create table s_user(_id integer primary key autoincrement,name text,pwd text)";
db.execSQL(sql);
}
public void insert(SQLiteDatabase db,String name,String pwd){
/*String sql="insert into s_user("+"name,pwd)values(?,?)";
db.execSQL(sql,new String[]{name,pwd});*/
//使用特定的方法:insert
ContentValues values=new ContentValues();
//key是字段名,value是插入的名字
values.put("name", name);
values.put("pwd", pwd);
db.insert("s_user", null, values);
nameEt.setText("");
pwdEt.setText("");
}
public void mybtn2(View view){
/*String sql="select * from s_user";
Cursor cursor=db.rawQuery(sql, null);
*/
//使用特定的方法
//
Cursor cursor=db.query("s_user", null,null,null,null,null,null);
refresh(cursor);
}
private void refresh(Cursor cursor){
SimpleCursorAdapter adapter=new SimpleCursorAdapter(
this,
R.layout.activity_item,
cursor, new String[]{"_id","name","pwd"},
new int[]{R.id.id,R.id.name,R.id.pwd},
SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
lv.setAdapter(adapter);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_four);
nameEt=(EditText)findViewById(R.id.name);
pwdEt=(EditText)findViewById(R.id.pwd);
lv=(ListView)findViewById(R.id.lv);
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
TextView tv=(TextView) view.findViewById(R.id.id);
String pid=tv.getText().toString();
/*String sql= "delete from s_user where _id="+pid;
db.execSQL(sql);*/
//使用特定方法
db.delete("s_user", "_id=?", new String[]{pid});
refresh(db.rawQuery("select *from s_user", null));
return true;
}
});
//第一种方式:获取数据库对象
//第一个参数:数据库文件的路径
//第二个参数:游标的工厂对象
//db=SQLiteDatabase.openOrCreateDatabase(getFilesDir()+"/my.db", null);
//第二种方式:获取数据库对象(方式更好)
helper=new MyOpenHelper(this, "user.db", null, 1);
db=helper.getReadableDatabase();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//关闭数据库
helper.close();
}
}
帮助类MyOpenHelper:
package com.example.fileapp;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
//数据库的帮助类:创建数据库表和数据库的更新
public class MyOpenHelper extends SQLiteOpenHelper{
//定义该程序中每张表的建表语句
private String sql1="create table s_user(_id integer primary key autoincrement,name,pwd)";
//第二个参数是数据库的名字,第三个是游标工厂对象,第四个是参数当前数据库使用版本号
public MyOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
//用于创建数据库表,第一次创建数据库文件时被回调
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(sql1);
}
//用于数据库的更新,旧版本号和新版本号不一致会被回调
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
}
效果图:
链接下载代码