标签:
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) { } }
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; } }
数据存储方式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
标签:
原文地址:http://blog.csdn.net/ydxzmhy/article/details/51331951