Android 数据存储

Android 数据存储 

     于Android开发时涉及到的数据存储有好几种,在这里,我总结了四种在开发中常用的存储方法,有SQLite数据库存储,contentprovider,contentprovider,File存储。对于简单的sharedpreferences存储和File存储就简述,而SQLite数据库存储和contentprovider者详细记录

      学习前,需要明白几个名词,

    Cursor(游标):数据缓冲区,放查询记录,执行查询时,都会返回一个 Cursor来遍历表中的数据,提醒一点,在第一次读取Cursor对象中的数据时,一定要先移动游标,否则此游标的位置在第一条记录之前,会引发异常(moveToFirst())。

    contentvalues:类似于集合hashmap,是一种存储机制,存放的类型为基本数据,以键值对的形式存储。

        Uri:资源标识符,是字符串,可用来定位区域可用的资源,有点像JPS,URI一般由三部分组成:1 访问资源的命名机制。2 存放资源的主机名。资源自身的名称,由路径表示。它两好基友ContentUrisUriMatcher,ContentUris类用于操作Uri路径后面的ID部分,UriMatcher类用于匹配Uri。

第一种:SQLite数据库存储

   关键字轻量级,开源,面向源有限的设备(手机),新API,SQLiteOpenHelper 类,

                    data/< 项目文件夹 >/databases/ , execSQL() 

     作为Android数据存储中最流行的嵌入式数据库,它支持 SQL 查询,占用内存小,可以自由复制,所有东西都放在同一个文件,由于 JDBC 不适合手机这种内存受限设备,所以 Android 开发人员需要学习新的 API 来使用 SQLite,execSQL() 方法可以执行SQL语句,但要注意语句格式,还有很多关于SQLite是信息就不多说了,下面就进行数据库的创建与增删改查。

      创建数据库是需要借助继承SQLiteOpenHelper 类,实现几个方法然后实例化该类,当在程序中调用这个类的方法getWritableDatabase()和getReadableDatabase()进行写读操作的时候,如果当时没有数据库,那么Android系统会自动创建一个数据库。代码示例:

package com.example.shuju;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper{
	
	private static int version = 1;  
	/*这个方法需要四个参数:上下文环境(例如,一个 Activity),数据库名字,一个可选的游标工厂(通常是 Null),
	 * 一个代表你正在使用的数据库模型版本的整数*/
    public DatabaseHelper(Context context, String name,  
            CursorFactory factory, int version) {  
        super(context, name, factory, version);  
    }  

    public DatabaseHelper(Context context, String name) {  
        this(context, name, version);  
    }  

    public DatabaseHelper(Context context, String name, int version) {  
        this(context, name, null, version);  
    }  
    //在数据库第一次生成的时候会调用这个方法,一般我们在这个方法里生成数据表  
    @Override  
    public void onCreate(SQLiteDatabase db) {  
        // 创建数据库的SQL  
        
    }  
    //当数据库需要升级时,Android系统会自动调用这个方法,一般我们在这里写删除表并创建新表的操作  
    @Override  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
    }  
	

}

         建表与增加数据,表创建好之后,通过insert(String table, String nullColumnHack, ContentValues values)方法插入数据,

db.execSQL("create table tab(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
  ContentValues values = new ContentValues();
    for(int i=0;i<10;i++){
        values.put("name", "test" + i);
        db.insert("tab", "_id", values);
    }
        修改数据,方法update(String table, ContentValues values, String whereClause,

                        String[] whereArgs)参数的具体含义代码里有,代码示例

ContentValues args = new ContentValues();  
                args.put("body", "修改后啦!");  
                String[] title = new String[] { "第二条数据" };  
                DatabaseHelper helper = new DatabaseHelper(SQLiteActivity.this,  
                        "dbk");  
                // 定义写数据库操作  
                SQLiteDatabase db = helper.getWritableDatabase();  
                /* 
                 * 修改数据库 第一个参数是:数据库表名 第二个参数是:要修改的字段和要更新的内容 
                 * 第三个参数是:条件,相当于SQL中的where部分 
                 * 第四个参数是:如果在第三个参数中有“?”符号,那么第四个参数的字串符会代替第三个的“?”部分 
                 */  
                db.update("dbk", args, "title=?", title);  
                db.close();  

       删除数据,delete(String table, String whereClause, String[] whereArgs),代码示例:

            try {  
  
                    DatabaseHelper helper = new DatabaseHelper(  
                            SQLiteActivity.this, "dbk");  
                    // 定义写数据库操作  
                    SQLiteDatabase db = helper.getWritableDatabase();  
                    /* 
                     * 删除操作 第一个参数是:数据库表名 第二个参数是:条件,相当于SQL中的where部分 
                     * 第三个参数是:如果在第三个参数中有“?”符号,那么第四个参数的字串符会代替第三个的“?”部分 
                     */  
                    db.delete("dbk", "title='第二条数据'", null);  
                    setTitle("删除title为第二条数据的记录");  
                    db.close();  
                } catch (Exception e) {  
                } 

      查询数据,android提供的query()和rawQuery()方法执行查询,代码示例:

                DatabaseHelper helper = new DatabaseHelper(SQLiteActivity.this,  
                        "dbk");  
                // 定义读数据库操作  
                SQLiteDatabase db = helper.getReadableDatabase();  
                String col[] = { "title", "body" };  
                /* 
                 * 执行数据库查询功能 第一个参数:表名 第二个参数:要查询的列的信息 
                 * 第三个参数:条件,相当于SQL中的where部分,如果想查询所以则为null 
                 * 第四个参数:如果在第三个参数中有“?”符号,那么第四个参数的字串符会代替第三个的“?”部分 
                 * 第五个参数:定义查询出来的数据是否分组,相当于SQL的GROUP BY,null为不分组 
                 * 第六个参数:相当于SQL的having部分 第七个参数:相当于SQL的ORDEY BY来描述是否排序,为null则不排序 
                 */  
                Cursor cusor = db.query("dbk", col, null, null, null, null,  
                        null);  
                if (cusor.moveToNext()) {  
                    String title = cusor.getString(cusor  
                            .getColumnIndex("title"));  
                    String body = cusor.getString(cusor.getColumnIndex("body"));  
                    final Integer num = cusor.getCount();  
                    setTitle(title);  
                    // 弹出一个对话框,来显示第一条数据  
                    dialog(SQLiteActivity.this, title, body, num).show();  
                } else {  
                    // 如果数据库中没有数据则提示  
                    new AlertDialog.Builder(SQLiteActivity.this)  
                            .setTitle("数据库中没有数据")  
                            .setPositiveButton("确定",  
                                    new DialogInterface.OnClickListener() {  
                                        @Override  
                                        public void onClick(  
                                                DialogInterface dialog,  
                                                int which) {  
                                        }  
                                    }).create().show();  
                }  
                db.close(); 

第二种:contentprovider

   关键字:对外共享数据,统一了数据的访问方式,四大组件之一

     在处处可见“云”的今天,程序间的数据交互需求令ContentProvider存储机制变成必不可少的一部分。而它也是最复杂的一种存储方式,作为四大组件之一,重要性可想而知,他的用处我拿一个比喻来形容,就是应用程序之间的桥梁,有了一定的权限,可以在程序间共享数据。

   下面通过是代码示例,演示一下如何在应用之间相互获取数据。

   首先在AndroidManifest.xml声明ContentProvider:其中authorities属性定义了此ContentProvider的Uri标识

<provider android:name=".MyProvider" android:authorities="com.test.MyProvider"/>
     在应用程序A中,继承ContProvider类,并重写其中方法

public class MyProvider extends ContentProvider{
 2     @Override
 3     public int delete(Uri uri, String selection, String[] selectionArgs) {
 4         // TODO Auto-generated method stub
 5         return 0;
 6     }
 7 
 8     @Override
 9     public String getType(Uri uri) {
10         // TODO Auto-generated method stub
11         return null;
12     }
13 
14     @Override
15     public Uri insert(Uri uri, ContentValues values) {
16         return null;
17     }
18 
19     //在Create中初始化一个数据库
20     @Override
21     public boolean onCreate() {
22         SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);
23         db.execSQL("create table tab(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
24         ContentValues values = new ContentValues();
25         values.put("name", "test");
26         db.insert("tab", "_id", values);
27         db.close();
28         return true;
29     }
30 
31     //实现query方法
32     @Override
33     public Cursor query(Uri uri, String[] projection, String selection,
34             String[] selectionArgs, String sortOrder) {
35         SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);
36         Cursor c = db.query("tab", null, null, null, null, null,null);
37         return c;
38     }
39 
40     @Override
41     public int update(Uri uri, ContentValues values, String selection,
42             String[] selectionArgs) {
43         // TODO Auto-generated method stub
44         return 0;
45     }
46 }

    当外部应用需要对ContentProvider中的数据进行添加、 删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法。
public Uri insert(Uri uri, ContentValues values):该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):该方法用于从ContentProvider中获取数据。

这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,

         在应用程序B中,通过ContentResolver获取程序A的ContentProvider中的数据。

 public class MainActivity extends Activity {
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
          
          //获取上下文
          Context ctx = MainActivity.this;
          //获取ContentResolver对象
         ContentResolver resolver = ctx.getContentResolver();
         //获取Uri对象
         Uri uri = Uri.parse("content://com.test.MyProvider");
         //获取数据
         Cursor c = resolver.query(uri, null, null, null, null);
         c.moveToFirst();
         for(int i=0; i<c.getCount(); i++){
             int index = c.getColumnIndexOrThrow("name");
             String src = c.getString(index);
             Log.d("", src);
             c.moveToNext();
         }
     }
 }


第三种:Sharedpreferences

  关键字轻量级,一些配置信息,简洁,键值对,最容易理解和使用,存储基本数据类型,无查询

            data/data/包名 /shared_prefs/,xml存储

   sharedpreferences可以将数据保存着应用软件的私有存储区,这些存储区的数据只能被写入这些数据的软件读取,

这类存储比较简单,就简述实现过程,

获取SharedPreferences对象的方法

SharedPreferences sharedPreferences = getSharedPreferences("ljq", Context.MODE_PRIVATE);

第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上。方法的第二个参数指定文件的操作模式

使用SharedPreferences存取数据

Editor editor = sharedPreferences.edit();//获取编辑器

editor.putString("name", "林计钦");

editor.putInt("age", 24);

editor.commit();//提交修改

生成的ljq.xml文件内容如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>

<map>

   <string name="name">林计钦</string>

   <int name="age" value="24" />

</map>


第四种:File存储

   关键词大量数据,文本图片音频,权限,openFileInput,openFileOutput,

             /data/data/<包>/files/***,SDCard

     file存储可以存储大量数据,比如说图片音频。所以就会与内存卡关联,存储在本机上就注意openFileInput,openFileOutput

两方法,openFileOutput()方法的第一参数用于指定文件名称,第二参数用于指定操作模式,有四种模式,分别为:

Context.MODE_PRIVATE = 0(默认,,只能被应用本身访问)

Context.MODE_APPEND = 32768(检查文件是否存在,存在就往文件追加内容,否则就创建新文件。)

Context.MODE_WORLD_READABLE = 1(当前文件可以被其他应用读取;)

Context.MODE_WORLD_WRITEABLE = 2(当前文件可以被其他应用写入。)

最常用的还是存储在外置内存卡上,要往SDCard存放文件,程序必须先判断手机是否装有SDCard,并且可以进行读写

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ 
	File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录         
	File saveFile = new File(sdCardDir, “a.txt”);

        FileOutputStream outStream = new FileOutputStream(saveFile);

        outStream.write("test".getBytes());

        outStream.close();


}


在AndroidManifest.xml中加入访问SDCard的权限如下:

    <!-- 在SDCard中创建与删除文件权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
 
    <!-- 往SDCard写入数据权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值