Android中的数据存储: SharedPreferences,内部存储,外部存储,数据库

本文详细介绍了Android中数据存储的多种方式,包括使用SharedPreferences存储简单数据,内部存储(files和cache)的读写操作,外部存储的使用,以及SQLite数据库的创建、插入、删除、更新和查询。示例代码展示了具体的操作步骤和注意事项,如权限声明和Xutils的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SharedPreferences

写入:

SharedPreferences可以存储一些简单的数据,数据存储在date——>data中对应的包中。
SharedPreferences是一个接口用getSharedPreferences(“preferenced_test”,MODE_PRIVATE)或getPreferences(MODE_PRIVATE)获得对应的实例。其中getSharedPreferences()的第一个参数为文件名,第二个为MODE。如果文件不存在就会创建。getPreferences()只有一个参数,文件名是默认的。
SharedPreferences的实例不能直接对文件写入数据,需要借助于SharedPreferences.Editor的实例。
而且这个实例必须写完数据必须提交。完整代码如下:

 SharedPreferences preferences=getSharedPreferences("preferenced_test",MODE_PRIVATE);
    //    SharedPreferences preferences = getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor editor=preferences.edit();
        editor.putString("test1",editText.getText().toString());
        editor.commit();//editor必须要提交

结果如下:
这里写图片描述

这里写图片描述

如图所示在data——>data的对应的包中已经建立了这个叫pp的文件。将文件导出打开可知是我们所写入的值。
###写出
将文件中的数据读出可以直接用preferences.getString()而不需要借助于editor。完整代码如下:

 SharedPreferences preferences =getSharedPreferences("preferenced_test",MODE_PRIVATE);//preferenced_test为文件名
        // SharedPreferences preferences =getPreferences(MODE_PRIVATE);//有一个默认的文件名MainActivity
        String content =preferences.getString("test1","我是默认值");//test1为键值,第二个值为默认值
        textView.setText(content);

将结果显示在TextView中的:
这里写图片描述
可知结果是正确的。

SharedPreferences的完整的代码如下:

public class MainActivity extends Activity implements View.OnClickListener {
   private Button button_writer;
    private Button button_read;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button_read= (Button) findViewById(R.id.read_button);
        button_writer= (Button) findViewById(R.id.writer_button);
        textView = (TextView) findViewById(R.id.text);
        button_writer.setOnClickListener(this);
        button_read.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.writer_button:
                shared_writer();
                break;
            case R.id.read_button:
                SharedPreferences preferences =getSharedPreferences("pp",MODE_PRIVATE);
                String content=preferences.getString("key", "我是默认值");
                textView.setText(content);
                break;
            default:
                break;
        }
    }

    private void shared_writer() {
        SharedPreferences preferences =getSharedPreferences("pp",MODE_PRIVATE);
        SharedPreferences.Editor editor =preferences.edit();
        editor.putString("key","hello word");
        editor.commit();
    }
}

内部存储

内部存储分为两种:1)将数据存储在files文件夹中;2)将数据存储在cache(缓存)文件夹中。
一般我们将一些比较重要的数据存储在files文件夹中,在系统中不会被轻易的删除。对于一些不重要的文件我们存储在cache文件夹中,在系统内存不足的时候这些数据会被删除。这里如果存在缓存中的话可以存储在外部存储的缓存中,利用getCacheDir()可以获得内部存储的缓存目录,用getExternalCacheDir()获得外部存储的缓存目录。他们的共同点是在app被卸载后数据会同时消失。不会存在数据的残留。

将数据存储在files中

存入:

将数据写入files的方法非常简单只需要用openFileOutput(“file_test”,MODE_PRIVATE);//file_test为文件名。
获得输出流,然后再用输出流的方式写入数据就可以了。完整的代码如下:

  FileOutputStream os = openFileOutput("file_test",MODE_PRIVATE);//file_test为文件名。
                    BufferedWriter writer =new BufferedWriter(new OutputStreamWriter(os));
                    writer.write("haha");
                    writer.flush();
                    writer.close();
                    os.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

结果如下:
这里写图片描述
这里写图片描述

从上面的结果可知:
在对应的包下产生了一个files的文件夹。在这个文件夹下存在我们建立的文件。打开文件可以看到是我们存的数据。

写出

写出也是用openFileInput()方法,只不过是只有一个文件名的参数。获得输入流后,就容易写出了。代码如下:

 try {
                    FileInputStream in =openFileInput("file_test");
                    BufferedReader read= new BufferedReader( new InputStreamReader(in));
                   String line= read.readLine();
                    while(line!=null){
                        textView.setText(line);
                        line=read.readLine();
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

结果显示在TextView中:
这里写图片描述

将数据存储在cache文件夹中

写入:
在cache中建立文件需要先得到一个file的实例: File file =new File(getCacheDir(),”hello.txt”);其中getCacheDir()为cache的路径。将file放入建立输出流的构造器中可得到对应的输出流。完整代码如下:

 File file =new File(getCacheDir(),"hello.txt");
  if(!file.exists()){
            try {
                file.createNewFile();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
                try {
                    FileOutputStream os = new FileOutputStream(file);
                    BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(os));
                    writer.write("你好啊");
                    writer.flush();
                    writer.close();
                    os.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

结果如下:
这里写图片描述

这里写图片描述

可知在cache中出现了hello.txt文件。
读出:
代码如下:

File file = new File(getCacheDir(),"hello.txt");
                try {
                    FileInputStream in = new FileInputStream(file);
                    BufferedReader read = new BufferedReader( new InputStreamReader(in));
                    String line =read.readLine();
                    while (line !=null){
                        textView.setText(line);
                        line = read.readLine();
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

结果如下:
这里写图片描述

外部存储

外部存储于将数据存储在cache文件夹中的操作几乎没有区别,只不过1)路径不同;2)需要声明权限
将数据在mnt的sdcard中。代码如下:
写入:

 File file = new File(Environment.getExternalStorageDirectory(),"tt.txt");
                if (!file.exists()){
                    try {
                        file.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    FileOutputStream os = new FileOutputStream(file);
                    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
                    writer.write("是我啊");
                    writer.flush();
                    writer.close();
                    os.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

结果如下:

这里写图片描述
这里写图片描述

读出:

  File file = new File(Environment.getExternalStorageDirectory(),"tt.txt");
                try {
                    FileInputStream in = new FileInputStream(file);
                    BufferedReader read = new BufferedReader(new InputStreamReader(in));
                    String line =read.readLine();
                    while (line != null){
                        textView.setText(line);
                        line=read.readLine();
                    }

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

结果如下:
这里写图片描述
权限声明:

 <!-- 外部插拔式存储设备-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!-- 手机自带存储设备-->
    <uses-permission android:name="ANDROID.PERMISSION.WRITE_EXTERNAL_STORAGE"/>

这个权限是必须要声明的。

SQLite数据库

SQLite简介

SQLite是一种小型数据库。
注意:一般每个数据库都有自已的一个SQLite数据库,不会让别的app所访问。SQLite最大的存储为2T,完全可以满足我们的需要,而且没有管理成本,非常实用。
特点:这里写图片描述

支持的数据类型:
这里写图片描述
在android中对数据库的操作是用一个继承了SQLiteOpenHelper的类实现的。代码如下:

SQLite对象的建立

有两种方式:1)openOrCreateDatabase(String name,int mode,CursorFactory factory)//第一个参数为数据库的名称,第二个参数为 权限,是公有还是只读的等等。第三个参数一般为null(我也不知道怎么用)这样就会返回一个SQLiteDatabase类型的对象。这样就可以通过这个对象创建表格,并进行增删改查了。完整的代码如下:

 SQLiteDatabase db= openOrCreateDatabase("myDB",MODE_PRIVATE,null);

 db.execSQL("create table if not exists userb(_id integer primary k
y aut
increment,name 
 //插入                                             

 db.execSQL("insert into us
rb(name,age,sex)values('张三',18,'男')");                       
 db.

ecSQL
"insert into userb(name,age,sex)values('李四',19,'女')
);                       
 db.
xecSQL("insert into userb(name,age,sex)values('王五',20,'男')");  





 //更新   



 C
ntentValues contentValues = new ContentValues();                    

 contentValues.put("sex","女");            

 db.update("userb"
contentValues,"name =?",new String[]{"张三"});                  

 //删除            

还有第二种方法。这种方法是借助于SQLiteOpenHelper,通过继承这个类来实现数据库的建立,这种建立数据库的方法有个优点就是可以控制数据库的版本号。继承后必须实现两个方法:onCreate()和onUpgrade();onCreate()方法在第一次建立数据库的时候会调用,如果数据库已经存在就不会再调用这个方法。一般在这里执行数据库和表格的建立。
onUpgrade()是在更新的时候调用(我还没用过)。

public class SqlHelper extends SQLiteOpenHelper {
    public SqlHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);//version为版本号,name为数据库的名字,factory一般为null
    }
    public SqlHelper(Context context, String name ){
        this(context, name,null,1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建数据库的表格
        db.execSQL("create table if not exists user(id integer primary key  autoincrement,name varchar(20),password varchar(20))");
    }

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

    }
}

在主函数中:

 case R.id.sql_button:
 SqlHelper helper =new SqlHelper(getApplicationContext(),"MY_BASE.db");
        SQLiteDatabas db= helper.getWritableDatabase();//这一句必须写
                Toast.makeText(getApplication(),"创建成功",Toast.LENGTH_LONG).show();
                break;

这样数据库和其中的列表就创建完成了。

在data–>data对应的包中就建立了数据库:

这里写图片描述

插入数据:

插入数据可以不用SQL语句。代码如下:

 ContentValues values =new ContentValues();
                values.put("name","lisi");
                values.put("password","1234");
                db.insert("user",null,values);

这样先将数据放在values中然后再传入insert()中。
结果如下:

这里写图片描述

delete与update

数据库的删除与更新比较简单。先写下代码:

delete:

 SqlHelper helper =new SqlHelper(getApplicationContext(),"MY_BASE.db");
 db= helper.getWritableDatabase();//这一句必须写
 db.delete("user","name=?",new String[]{"lisi"});

用db去调用delete()方法。第一个参数为用户名,第二个为删除的条件。第三个为?的值。用String数组装入。
update:

ContentValues contentValues =new ContentValues();
 contentValues.put("password","abc");
 db.update("user",contentValues,"name=?",new String[]{"lisi"});

现将要更新的字段的值装入ContentValues实例中。然后db调用update()方法。第一个参数为表名,第二个参数为更新的值,第三个参数为更新的条件。

select搜索

搜索一般用两种方法:db.rawQuery()和db.query();
.rawQuery()中可以直接输入SQL语句。query()不需要。
代码如下:

//                Cursor cursor =db.rawQuery("select * from user",null);//在rawQuery()中直接输入SQL语句
                Cursor cursor =db.query("user",null,null,null,null,null,"id DESC","1,3");//DESC为降序 1为偏移量,3为数量
                cursor.moveToFirst();//移动到第一条
                //如果不是最后一条的下边
                while (!cursor.isAfterLast()){
                    String name = cursor.getString(cursor.getColumnIndex("name"));//cursor.getColumnIndex("name")为获得name的idex
                    String password = cursor.getString(cursor.getColumnIndex("password"));//cursor.getString()为获得相应的字符串
                    Log.d("cursor","用户名"+name+"密码"+password);
                    cursor.moveToNext();//下一条
                }

query( )有7个参数依次的顺序和意义为:

这里写图片描述

调用者两个方法都会返回一个Cursor类型的对象,这个对象调用各种方法就可以得到搜寻的数据。

用Xutils对数据库进行操作

Xutils可以自行建立数据库建表。具体操作见:
http://blog.youkuaiyun.com/jjwwmlp456/article/details/44084411

当数据库和表格已经存在时的操作:

1)建立一个包含表中所有字段的类,并在类名前面注解表明。在id字段前面也加上注解。代码如下:

@Table(name = "user")
public class WorkDaily {
    @Column(column = "id")
    private String id;
    private String name;
    private String password;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

2)导入Xutils包,并与数据库相关联。具体的增删改查如下:

public class TableOperator {


    public static <T> List<T> getList(String Tablename,Class<T> entityType ){
        SQLiteDatabase db = DBmanager.getInstenec().getDb();




        DbUtils utils = DbUtils.create(BaseApplication.getmContext(),"MY_BASE.db");

        try {
            List<T> list = (ArrayList<T>) utils.findAll(Selector.from(entityType));
            return list;
        } catch (DbException e) {
            e.printStackTrace();
        }



      return null;
    }

    //增
    public static void getInsert(Map map){
        SQLiteDatabase db = DBmanager.getInstenec().getDb();

        DbUtils utils = DbUtils.create(BaseApplication.getmContext(),"MY_BASE.db");
        WorkDaily workDaily2 = new WorkDaily();
//
            workDaily2.setName("pp");
            workDaily2.setPassword("111");//增加
        try {
            utils.save(workDaily2);
        } catch (DbException e) {
            e.printStackTrace();
        }

    }

    public static <T> void getDelete(Class<T> entityType){
        SQLiteDatabase db = DBmanager.getInstenec().getDb();
//        db.delete(tablename,"name = ?",new String[]{name});
        DbUtils utils = DbUtils.create(BaseApplication.getmContext(),"MY_BASE.db");


        try {
            utils.delete(entityType, WhereBuilder.b("name", "=","zhangsan"));

        } catch (DbException e) {
            e.printStackTrace();
        }


    }

    public static void getupdate(){
        SQLiteDatabase db = DBmanager.getInstenec().getDb();
//        db.delete(tablename,"name = ?",new String[]{name});
        DbUtils utils = DbUtils.create(BaseApplication.getmContext(),"MY_BASE.db");
        WorkDaily workDaily2 = new WorkDaily();
//
        workDaily2.setName("pp");

        try {
            utils.update(workDaily2, WhereBuilder.b("name", "=", "ppp"), "name");
        } catch (DbException e) {
            e.printStackTrace();
        }
    }



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值