android中的数据存储

来源:互联网 发布:数据库分组查询语句 编辑:程序博客网 时间:2024/06/02 01:06

android中主要有四种存储方式:

存储方式一:SharedPreferences:

             1、是一种轻型的数据存储方式

              2、本质是基于XML文件存储key-values键值对数据

              3、通常用来存储一些简单的配置信息

       是android自带的轻量级的存储类,一般用来保存比较常用的配置信息:如是否保存用户名,密码,保存壁纸。

       SharedPreferences 有权限设置:全局共享,私有,只读,可写。

       SharedPreferences对象本身只能获取数据而不支持数据的修改和存储。存储修改是通过Editor对象实现

       实现SharedPreferences存储的步骤如下:

       1、获得SharedPreferences对象

       2、获得SharedPreferences.Editor对象

       3、通过Editor接口的putXxx()方法保存key-values对(其中的Xxx表示不同的数据类型

       4、通过Editor接口的commit方法保存key-values对

       SharedPreferences   pref   =  getSharedPreferences("文件的名字",权限);

       编辑时使用Editor对象 Editor editor = pref.editor();

                                        editor.putString("name","admin");

                                        editor.commit();

      pref.getString("name","");第二个参数表示当获取name失败时name的默认值

         //删除name

         editor.remove("name");

         editor.commit();

   注:执行editor的操作时最后一定要记得editor.commit();这样才能保证任务得到执行,类似于数据库中的事务。


 demo代码:

package com.example.mhy.datasavemethod;import android.content.DialogInterface;import android.content.SharedPreferences;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.CheckBox;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private EditText user_et,pass_et;    private Button cancel_btn,sure_btn;    private CheckBox save_name_cb;    private SharedPreferences pref;    private SharedPreferences.Editor editor;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        user_et = (EditText) findViewById(R.id.user_name);        pass_et = (EditText) findViewById(R.id.user_pass);        cancel_btn = (Button) findViewById(R.id.cancel_btn);        sure_btn = (Button) findViewById(R.id.sure_btn);        save_name_cb = (CheckBox) findViewById(R.id.save_name);        pref = getSharedPreferences("saveName", MODE_PRIVATE);        //起用编辑        editor = pref.edit();        String name = pref.getString("name", "");        if(name.equals("")) {            save_name_cb.setChecked(true);        }else {            user_et.setText(name);        }        sure_btn.setOnClickListener(this);        cancel_btn.setOnClickListener(this);    }    @Override    public void onClick(View v) {        String userName = user_et.getText().toString();        String userPass = pass_et.getText().toString();        switch(v.getId()) {            case R.id.sure_btn:                if(userName.equals("admin") && userPass.equals("123456")) {                    if(save_name_cb.isChecked()) {                        editor.putString("name", "admin");                        editor.commit();                    }else {                        editor.remove("name");                        editor.commit();                    }                    Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_LONG).show();                }else {                    Toast.makeText(MainActivity.this, "登陆失败", Toast.LENGTH_LONG).show();                }                break;            case R.id.cancel_btn:                Toast.makeText(MainActivity.this, "取消登陆", Toast.LENGTH_LONG).show();                break;        }    }}
存储方式二:SQLite

        SQLite是D.Richard Hipp 用C语言编写的开源嵌入式数据库引擎,它支持大多数的SQL92标准,并且可以在所有主要的系统上运行。

        支持高达2TB大小的数据库

        每个数据库以单个文件形式存在

        以B-Tree的数据结构形式存储在磁盘

特点: 

       轻量级  一个动态库,单个文件

       独立性  没有依赖,无需安装

       隔离性  全部在一个文件夹中

       跨平台  支持众多操作系统

       多语言接口  支持众多编程语言

       安全性    事务

关于事务处理的安全性问题:

       通过数据库上的独占性和共享锁来实现独立事务处理。

       多个进程可以在同一时间从同一数据库读取数据,但只有一个可以写入数据。

SQLite的数据类型:

       NULL, INTEFGER  REAL  TEXT和BLOB数据类型

       空值       整型值         浮点型  字符串  二进制对象

SQLite数据类型为动态数据类型(弱引用)

使用须知:

       由于资源占用少,性能良好和管理成本,嵌入式数据库有了用武之地,例Android  IOS

       没有可用于SQLite的网络服务器,只能通过网络共享,可能存在文件锁或者性能问题

       只提供数据库级的锁定。

      没有用户账户概念,而是根据文件系统确定所有数据库的权限。

SQLiteDataBase  和 SQLiteOpenHelper  和 ContentValues

demo:

SQLiteDataBase的使用:

public class SQLiteDatabaseActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        SQLiteDatabase db = openOrCreateDatabase("demo.db", MODE_PRIVATE, null);        db.execSQL("create table stu(_id integer primary key autoincrement, " +                "name text not null, sex text not null, age integer not null)");        db.execSQL("insert into stu(name, sex, age) values('zhangsan', 'nan', 19)");        db.execSQL("insert into stu(name, sex, age) values('lisi', 'nan', 20)");        Cursor c = db.rawQuery("select * form stu",null);        if(c!=null) {            while(c.moveToNext()) {                Log.i("tag", c.getString(c.getColumnIndex("_id")));                Log.i("tag", c.getString(c.getColumnIndex("name")));                Log.i("tag", c.getString(c.getColumnIndex("sex")));                Log.i("tag", c.getInt(c.getColumnIndex("age"))+"");            }        }        //或者使用ContentValues执行相关操作 相当于hashMap        ContentValues values = new ContentValues();        values.put("name", "ss");        values.put("sex", "nan");        values.put("age", 19);        db.insert("stu", null, values);        values.clear();        values.put("name", "ss1");        values.put("sex", "nan");        values.put("age", 20);        db.insert("stu", null, values);        values.clear();        values.put("name", "ss2");        values.put("sex", "nan");        values.put("age", 21);        db.insert("stu", null, values);        values.clear();        values.put("name", "ss3");        values.put("sex", "nan");        values.put("age", 22);        db.insert("stu", null, values);        db.delete("stu", "name like ?", new String[]{"%s1%"});//删除名字中有s1的        values.clear();        values.put("sex", "nv");        db.update("stu", values, "_id > ?", new String[]{"3"});//更新_id>3的性别为nv        //使用SQLiteOpenHelper进行对数据库的操作        DBSQLiteOpenHelper dbHelper = new DBSQLiteOpenHelper(this, "demo1", null,MODE_PRIVATE);        SQLiteDatabase db1 = dbHelper.getWritableDatabase();        //剩下的操作同上。。。    }}
SQLiteOpenHelper的使用:

public class DBSQLiteOpenHelper extends SQLiteOpenHelper {    public DBSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,                              int version) {        super(context, name, factory, version);    }    //创建数据库时调用,系统自己调用,用户不可以调用    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL("create table user(_id integer primary key, name text not null, " +                "pass text not null)");        db.execSQL("insert into user(name, pass) values('sd', '123')");    }    //版本更新时调用,系统自己调用    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}

存储方式三:File
   当应用程序删除后一般情况下它的相关存储的信息也会被删除,手机里不会有残余垃圾

   android中文件存储的操作:

              Activity的openFileOutput()方法可以用于把数据输出到文件中

              创建的文件保存在/data/data/<package name>/files目录

              实现过程和java中保存数据到文件一样

demo:

file文件操作时的主要方法:

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //File file1 = new File("/mnt/extsdcard/test");//外置存储卡路径        File file = new File("/mnt/sdcard/test");//内置sd卡的路径        if (!file.exists()) {            try {                file.createNewFile();            } catch (IOException e) {                e.printStackTrace();            }        } else {            Toast.makeText(MainActivity.this, "the file is exists", 1000).show();        }//        //删除文件//        file.delete();//删除文件//        File file = this.getFilesDir();//这个目录是当前应用程序默认的数据存储目录//        File file = this.getCacheDir();//这个目录是当前应用程序默认的缓存文件存放的目录//        //把一些不是非常重要的文件在此处创建 使用//        //如果手机内存不足的时候 系统会自动删除App的Cache目录中的数据//        // /data/data/<包名>/app_imooc//        File file = this.getDir("imooc", MODE_PRIVATE);//        this.getExternalFilesDir("imooc");//        File file = this.getExternalCacheDir();//        //如果说开发者不遵守这样的规则 不把数据放入 data/data/<包名>/////mnt/sdcard/Android/data/<包名>////卸载之后数据将不会自动清除掉 将会造成所谓的数据垃圾    }}

使用文件存储的小例子:

public class FileActivity extends Activity {    private EditText input_et;    private Button button;    private TextView tv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        input_et = (EditText) findViewById(R.id.editText);        button = (Button) findViewById(R.id.button);        tv = (TextView) findViewById(R.id.textView);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                writeFiles(input_et.getText().toString());                tv.setText(readFiles());            }        });    }    //保存文件的内容    public void writeFiles(String content) {        FileOutputStream fos = null;        try {            fos = openFileOutput("a.txt", MODE_PRIVATE);            fos.write(content.getBytes());            fos.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        }  catch (IOException e) {            e.printStackTrace();        }    }    //读取文件的内容    public String readFiles() {        String content = null;        FileInputStream fis = null;        try {            fis = openFileInput("a.txt");            ByteArrayOutputStream baos = new ByteArrayOutputStream();            byte[] buffer = new byte[1024];            int len = 0;            while ((len = fis.read(buffer)) != -1) {                baos.write(buffer, 0, len);            }            content = baos.toString();            fis.close();            baos.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return content;    }}

数据存储三:ContentProvider

     数据存储方式Shared Preferences  文件存储  SQLite 网络存储等 都只是在单独的一个应用程序之中达到一个数据共享       

       

 

如何实现ContentProvider

     1、继承抽象类ContentProvider实现一系类针对数据的增、删、该、查等方法

      2 、需在AndroidMainfest.xml中完成对ContentProvider的注册

       <provider

                    android:name="com.immoc.MusicProvider"

                     androi:authorities="com.provider.music">

         </provider>

        注:注册的authorities属性值是全局唯一的

UriMatcher类

   UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

        .UriMatcher.NO_MATCH 表示不匹配任何路径的返回码

    matcher.addURI("com.imooc.provider","music",1);

        .往UriMatcher类里添加一个拼凑的Uri

        .UriMatcher为一个Uri的容器,容器里面包含着我们即将可能要操作的Uri

        .如果通过match()方法匹配成功就返回code值   这里的code=1

    matcher.match(uri)

         .首先与通过addURI()  方法添加进来的Uri匹配

          .匹配成功则返回设置的code值,反之,返回一个UriMatcher.NO_MATCH常量(-1)


ContentResolver:

             使用ContentResolver操作ContentProvider中的数据:

                     .当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用                                       ContentResolver类来实现

                    .使用Activity提供的getContentResolver()方法获取ContentResolver对象

                    .ContentResolver类提供了与ContentProvider类相同签名的四个方法

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中获取数据

使用系统提供的ContentProvider  查询联系人   增加联系人

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        /**         * 访问系统通讯录时,要注意在注册文件中加入读取联系人的权限         * <uses-permission android:name="android.permission.READ_CONTACTS"/>         */        //调用系统提供的        ContentResolver cr = getContentResolver();        Cursor c = cr.query(Contacts.CONTENT_URI, new String[] {                Contacts._ID, Contacts.DISPLAY_NAME }, null, null, null);        if (c != null) {            while (c.moveToNext()) {                int id = c.getInt(c.getColumnIndex("_id"));                Log.i("infor","_id:" + id);                Log.i("infor",                        "name:" + c.getString(c.getColumnIndex("display_name")));                Cursor c1 = cr.query(Phone.CONTENT_URI, new String[] {                        Phone.NUMBER, Phone.TYPE},                        Phone.CONTACT_ID + "=" + id, null, null);                //根据联系人ID查询出联系人电话号码                if (c1 != null) {                    while (c1.moveToNext()) {                        int type = c1.getInt(c1.getColumnIndex(Phone.TYPE));                        if (type == Phone.TYPE_HOME) {                            Log.i("infor",                                    "家庭电话:" + c1.getString(c1.getColumnIndex(Phone.NUMBER)));                        } else if (type == Phone.TYPE_MOBILE) {                            Log.i("infor",                                    "手机:" + c1.getString(c1.getColumnIndex(Phone.NUMBER)));                        }                    }                     c1.close();                }                //根据联系人的ID去查询出联系人的邮箱地址  Email.ADDRESS 和 Email.DATA都表示邮箱的地址                //API文档 :                // http://www.android-doc.com/reference/android/provider/ContactsContract.CommonDataKinds.Email.html                Cursor c2 = cr.query(Email.CONTENT_URI, new String[] {                        Email.ADDRESS, Email.TYPE}, Email.CONTACT_ID + "=" + id,                        null, null);                if (c2 != null) {                    while (c2.moveToNext()) {                        int type = c2.getInt(c2.getColumnIndex(Email.TYPE));                        if (type == Email.TYPE_HOME) {                            Log.i("infor",                                    "家用邮箱:" + c2.getString(c2.getColumnIndex(Email.ADDRESS)));                        }                    }                    c2.close();                }            }            c.close();        }        //向联系人中插入一条记录        //不要忘记注册权限        //<uses-permission android:name="android.permission.WRITE_CONTACTS"/>        ContentValues values = new ContentValues();        Uri uri = cr.insert(RawContacts.CONTENT_URI, values);        Long raw_contact_id = ContentUris.parseId(uri);        values.clear();        //插入人名        values.put(StructuredName.RAW_CONTACT_ID, raw_contact_id);        values.put(StructuredName.DISPLAY_NAME, "张三");        values.put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);        uri = cr.insert(Data.CONTENT_URI, values);        //插入电话信息        values.clear();        values.put(Phone.RAW_CONTACT_ID, raw_contact_id);        values.put(Phone.NUMBER, "18865550581");        values.put(Phone.MIMETYPE, Phone.CONTENT_ITEM_TYPE);        uri = cr.insert(Data.CONTENT_URI, values);    }}
1、使用系统提供的ContentProvider

      查询联系人    增加联系人   短信的读取    通话记录  多媒体 (图片 视频 音频)

2、使用自己定义的ContentProvider

0 0