Android学习笔记之数据存储

2018-10-21  本文已影响0人  sssssss_

Android中有5种数据存储方式,分别为文件存储、SQLite数据库、SharedPreferences、ContentProvider、网络。每种存储方式的特点如下:

1、File文件存储/SD卡

文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供openFileInput()和openFileOutput()方法来读取设备上的文件。

将数据存储到文件中:

String data = "data to save";
FileOutputStream out = openFileOutput("文件名", 覆盖:MODE_PRIVATE 追加:MODE_APPEND);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(data);
writer.close();

从文件中读取数据:

FileInputStream in = openFileInput("文件名");
BufferedReader reader = new BufferedReader(new InputStreamReader());
StringBuffer content = new StringBuffer();
String line = "";
while ((line.reader.readLine()) != null) {
    content.append(line);
}
reader.close();
return content.toString();

将数据存储到手机内存中

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
private void saveTosdcard() {
        String str = "data to save";
        //文件输出流
        FileOutputStream fos = null;
        //设置文件路径 ,第一个参数是文件保存的路径,null放在根目录下,第二个参数是文件名
        File file = new File(getExternalFilesDir(null), "/data666.txt");
        try {
            //传入参数第一是file,第二可以传boolean表示是否追加
            fos = new FileOutputStream(file,true);
            fos.write(str.getBytes());
            Toast.makeText(MainActivity.this, "保存到SD卡成功!", Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    // 关闭输入流
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
删除getExternalFilesDir路径文件
private void deleteSocket() {
    try {
        // 找到文件所在的路径并删除该文件
        File file = new File(getExternalFilesDir(null), "/dataSocketHiMate.txt");
        if (file.exists()) {
            file.delete();
        } else {
            Toast.makeText(MainActivity.this, "没有文件可以删除", Toast.LENGTH_SHORT).show();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

2、SharedPreferences

SharePreferences是一种轻型的数据存储方式,常用来存储一些简单的配置信息,如int、string、boolean、float和long。它的本质是基于XML文件存储key-value键值对数据。

将数据存储到SharedPreferences

SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
editor.remove("married");
editor.commit();

从SharedPreferences中读取数据

SharedPreferences pref  = getSharedPreferences("data",MODE_PRIVATE);
String name = pref.getString("name","默认值");
int age = pref.getInt("age",0);
boolean married = pref.getBoolean("married",false);

3、SQLite数据库

SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,在存储大量复杂的关系型数据的时可以使用,比前面学过的只适用于存储简单数据的两种存储方式要好很多。

创建数据库

自定义帮助类并继承SQLiteOpenHelper,并重写两个方法:onCreate()和 onUpgrade(),分别在这两个方法中去实现创建、升级数据库的逻辑。还需要一个构造方法,这里用含有四个参数的构造方法就可以

public class MyDatabaseHelper extends SQLiteOpenHelper {
    private Context mContext;
    public static final String CREATE_BOOK = "create table Book(" +
            "id integer primary key autoincrement," +
            "author text," +
            "price readl," +
            "price integer," +
            "name text)";
    public MyDatabaseHelper(Context context, String name,
                            SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //升级数据库的话先修改版本号
        //drop删除表,delete是删除数据
        db.execSQL("drop table if exists Book");
        onCreate(db);
    }
}

数据库进行增删改查的操作

public class Main2Activity extends AppCompatActivity {
    private MyDatabaseHelper dbHepler;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        dbHepler = new MyDatabaseHelper(this, "BookStore.db", null, 1);
        //都是打开和创建,区别在于空间满的情况w是出现异常,R是只读
        //dbHepler.getWritableDatabase();
        dbHepler.getReadableDatabase();
        SQLiteDatabase db = dbHepler.getWritableDatabase();

        //添加
        ContentValues values = new ContentValues();
        values.put("name", "tom");
        values.put("pages", 464);
        values.put("price", 14.23);
        db.insert("Book", null, values);
        values.clear();
        //更新
        ContentValues values = new ContentValues();
        values.put("name", "HHH");
        db.update("Book", values, "price>?", new String[]{"10"});
        //删除
        db.delete("Book",  "price>?", new String[]{"10"});
        //查询
        Cursor c = db.query("Book",null,null,null,null,null,null);
        String s = c.getString(c.getColumnIndex("name"));
        c.close();
    }
}

sqlite数据导出到csv、txt

String sql = "select * from location";
Cursor cursor = db.rawQuery(sql, null);
//如果要其他格式的话,只需修改文件后缀名即可
ExportToCSV(cursor, "test666.csv");

核心代码块ExportToCSV()

private void ExportToCSV(Cursor c, String fileName) {
        int rowCount = 0;
        int colCount = 0;
        FileWriter fw;
        BufferedWriter bfw;
        //获取SD卡路径
        File sdCardDir = Environment.getExternalStorageDirectory();
        File saveFile = new File(sdCardDir, fileName);
        try {
            rowCount = c.getCount();
            colCount = c.getColumnCount();
            fw = new FileWriter(saveFile);
            bfw = new BufferedWriter(fw);
            if (rowCount > 0) {
                c.moveToFirst();
                // 写入表头
                for (int i = 0; i < colCount; i++) {
                    if (i != colCount - 1)
                        bfw.write(c.getColumnName(i) + ',');
                    else
                        bfw.write(c.getColumnName(i));
                }

                // 写好表头后换行
                bfw.newLine();
                // 写入数据
                for (int i = 0; i < rowCount; i++) {
                    c.moveToPosition(i);
                    Log.d(TAG, "正在导出第" + (i + 1) + "条");
                    for (int j = 0; j < colCount; j++) {
                        if (j != colCount - 1) {
                            bfw.write(c.getString(j) + ',');
                        } else
                            bfw.write(c.getString(j));
                    }
                    // 写好每条记录后换行
                    bfw.newLine();
                }
            }
            // 将缓存数据写入文件
            bfw.flush();
            Log.d(TAG, "ExportToCSV: " + bfw.toString());
            // 释放缓存
            bfw.close();
            Log.d(TAG, "导出完毕!");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            c.close();
        }
    }

4、ContentProvider

并不能用户存储数据。主要用于不同应用程序之间共享数据,只是为我们存储以及添加数据制定统一的接口而已。

5、网络存储数据

通过网络上提供的存储空间来上传(存储)或下载(获取)我们存储在网络空间中的数据信息

6、共享数据的方式

1.File, 2.Sqlite,3.Content Provider,4.Service,5.Broadcast Receiver,6.Intent

7、了解SQLite中的事务处理吗?是如何做的?

使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。多用于大量数据操作时,能明显减少耗时。

 SQLiteDatabase db = dbHepler.getWritableDatabase();
 db.beginTransaction();//开始事务
 try{    
     db.execSQL(...);  
     db.execSQL(...); 
     //调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务  
     db.setTransactionSuccessful(); 
} finally{ 
    //由事务的标志决定是提交事务,还是回滚事务  
    db.endTransaction();
} 
db.close();

8、事务的属性

9、使用SQLite做批量操作有什么好的方法吗?

即使用事务处理进行优化,默认SQLite的数据库插入操作,如果没有采用事务的话,它每次写入提交,就会触发一次事务操作,而这样几千条的数据,就会触发几千个事务的操作,这就是时间耗费的根源

10、如果现在要删除SQLite中表的一个字段如何做?

SQLite数据库只允许增加表字段而不允许修改和删除表字段,只能采取复制表思想,即创建一个新表保留原表想要的字段、再将原表删除。

11、使用SQLite时会有哪些优化操作?

  1. 使用事务做批量操作:具体操作见上。
  2. 及时关闭Cursor,避免内存泄漏。
  3. 耗时操作异步化:数据库的操作属于本地IO,通常比较耗时,建议将这些耗时操作放入异步线程中处理。
  4. ContentValues的容量调整:ContentValues内部采用HashMap来存储Key-Value数据,ContentValues初始容量为8,扩容时翻倍。因此建议对ContentValues填入的内容进行估量,设置合理的初始化容量,减少不必要的内部扩容操作
  5. 使用索引加快检索速度:对于查询操作量级较大、业务对要求查询要求较高的推荐使用索引

12、Android 中有哪几种解析xml的类,官方推荐哪种?以及它们的原理和区别。

Android 提供了三种解析XML的方式:SAX(Simple API XML)DOM(Document Object Model)Pull解析

本文参考资料:

上一篇下一篇

猜你喜欢

热点阅读