• Android数据存储三剑客——SharedPreferences、File、SQLite


     

      Android中常用的数据存储一般有三种方式:SharedPreferences、文件和SQLite数据库,用来保存需要长时间保存的数据。本文将通过几个具体的小实例来讲解这三种方式的具体实现。

     

    数据存储之SharedPreferences

    SharedPreferences位于android.content包中,用于存储少量简单数据。其特点有:

    1. 轻型的数据存储方式

    2. 基于xml文件的存储方式,以 键/值 对的形式存储数据

    3. 存储简单的配置信息,支持的存储类型有:Boolean、Float、Integer、Long、String等。

      SharedPreferences存储数据流程:

      1. 获取SharedPreferences对象:

      private  SharedPreferences  prefs;

      ①  //不指定存储文件名,使用默认的名称,即活动的类名称

      prefs = getPreferences(MODE_PRIVATE);

      ② /*

      *如果文件中的数据是Android应用程序中各个活动之间的共享数据,

      *每个活动都能访问,需要使用如下方式,获取SharedPreferences:

      * prefs = getSharedPreferences(“myPrefs”,MODE_PRIVATE);

      */

      ③ //也可以使用PreferenceManager

      //PreferenceManager.setDefaultValues(this,R.xml.preferences,false);

      //prefs = PreferenceManager.getDefaultPreferenceManagers(this);

      2. 存储数据(使用Editor对象,保存key-value值),读取数据:

      Editor editor = prefs.edit();

      //存储各种类型的数据

      editor.putString(“name”,”Zhangsan”);

      editor.putInt(“age”,18);

      editor.putLong(“time”,System.currentTimeMillis);

      //读取数据

      String name = prefs.getString(“name”);

      int age = prefs.getInt(“age“);

      3. 提交设置的数据,使数据保存到文件中:

      在第2步中使用editor对象设置好key-value值后,数据并未保存到文件中,要保存还需提交

      editor.commit();

      4. 删除保存的数据:

      SharedPreferences.Clear();

      说了这么多,可能还是有些朋友说SharedPreferences到底是个什么东东,下面个大家看看就明白了:

      图1.  SharedPreferences存储文件的内容

      这下知道了吧,<string name=”user”>Zhangsan</string>就是用editor.putString(“user”,”Zhangsan”)设置的内容。使用DDMS可查看该文件位置,该文件存放在:

      图2.  SharedPreferences文件位置

    数据存储之文件(File)存储

      使用SharedPreferences存储文件比较方便简单,但不能指定存储文件的位置,存储的内容也很少,使用文件存储既可存储到应用程序默认的放置文件的位置,也可存储到外部存储设备中,如外置SD卡中,可以减少占用手机内存,可以存储比较大的文件。

      文件的操作模式:

                                    表1.  文件操作模式及说明

    常量值

    说明

    MODE_PRIVATE

    文件只能让创建的应用程序访问

    MODE_WORLD_WRITEABLE

    文件可让其他应用程序写入

    MOED_WORLD_READABLE

    文件可让其他应用程序读取

    MODE_APPEND

    文件若已存在,则在文件末尾写入数据,不覆盖原来文件内容

      使用文件存储的步骤:

      1. 写入文件

      //以字符流的形式写数据到文件

      FileOutputStream out = openFileOutput(“out.txt”,MODE_PRIVATE);

      String data = “123456abcdef”;

      out.write(data);   //写数据到文件

      out.close();        //关闭文件输出流

      /*

      * 也可使用OutputStreamWriter以字节流的形式写入文件

      * OutputStreamWriter writer = new OutputStreamWriter(out);

      * writer.write(data);

      * writer.flush();  //输出流数据

      * writer.close();  //关闭流

      */

      2. 读取文件

      FileInputStream fis = openFileInput("input.txt");

      ByteArrayOutputStream out = new ByteArrayOutputStream();

      byte[] buffer = new byte[1024];

      int len = 0;

      while ((len=fis.read(buffer))!=-1) {

           out.write(buffer,o,len);

        }

     

    数据存储之SQLite

       Android使用SQLite数据库引擎,它是包含的、事务型的数据库引擎,无需单独的服务线程。SQLite数据库资源占用少、开源、功能强大,有以下特点:

      1. 轻量级,使用一个动态库,单个文件

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

      3. 隔离性,数据全在一个文件夹中

      4. 跨平台,支持多种操作系统

      5. 多语言接口,支持众多编程语言

      6. 安全性,支持事务处理。

      7. 独占性,使用共享锁实现独立事务处理,多个进程可同一时间从同意数据库读数据,但只有一个进程可写数据。

      SQLite支持的数据类型有:NULL、INTEGER、REAL、TEXT、BLOB类型。

      

      SQLite存储数据流程:

      1. 获取SQLiteDatabase数据库对象

      SQLiteDatabase db = openOrCreateDatabase(“user.db”,MODE_PRIVATE,null);

      2. 执行增删查改的数据操作语句

      //创建一张表

      db.execSQL(“create table if not exists contacts_tb(_id integer primary key autoincrement,name text not null,age integer not null)”); 

      //往数据库里插入一条数据

      db.execSQL(“insert into contacts_tb(name,age)values(‘abc’,20)”);

      db.execSQL(“insert into contacts_tb(name,age)values(‘cde’,18)”);

      //查询所有的数据,返回一个游标对象

      Cursor cursor = db.raw(“select * from contacts_tb”,null);

      /*

      * 也可使用ContentValues执行SQL操作

      * ContentValues values = new ContentValues();

      * values.put(“name”,”aaa”);

      * values.put(“age”,20);

      * db.insert(“contacts_tb”,null,values);  //插入数据

      * values.clear();

      * values.put(“age”,18);

      * //更新_id>2的数据项的属性值

      * db.update(“contactes_tb”,values,”_id>?”,new String[]{“2”});

      * //删除名字中含有’a’的项

      * db.delete(“contacts_tb”,”name like ?”,new String[]{“%a%”});

      * //查询_id>0的项,按名字排序

      * Cursor cursor = db.query(“contacts_tb”,null,”_id>?”,new String[]{“0”},null,null,name);

      */

      

      /*

      * 使用SQLiteOpenHelper对象创建和管理数据库

      * 新建一个类DBOHelper extends SQLiteOpenHelper

      * @override onCreate,onUpdate方法

      * 使用DBOHelper对象

      * DBOHelper helper = new DBOHelper(this,”user.db”);

      * //创建或打开只读数据库

      * SQLiteDatabase db = helper.getWriteableDatabase();

      * //SQLiteDatabase db = helper.getReadableDatabase();

      * 数据的操作和上边都一样

      */

      3.处理获取的结果

      String name[10] ;

      int age[10];

      int i=0;

      while(cursor.moveToNext()){

           name[i] = cursor.getString(cursor.getColumnIndex(“name”));

           age[i] = cursor.getInt(cursor.getColumnIndex(“age”));

           i++;

      }

      cursor.close();  //需手动关闭,否则会出现未知的异常

      db.close();       //数据库对象也要手动关闭

     

      下面来个具体的实例,简单实现下SQLite的数据存储,用到了ListView数据绑定:

    DBHelper.java文件
    public class DBHelper extends SQLiteOpenHelper{
    
    	public DBHelper(Context context, String name) {
    		super(context, name, null, 1);
    	}
    
    	@Override
    	public void onCreate(SQLiteDatabase db) {
    		
    	}
    
    	@Override
    	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    		
    	}
    }
    
    Contact.java文件
    public class Contact extends Activity{
    	
    	private ListView lists;
    	SimpleAdapter adapter;
    	List<Map<String, Object>> dataList;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.layout_contacts);
    		
    		lists = (ListView) findViewById(R.id.contacts_list);
    		All_Contacts();
    
    	}
    	
    
    	public void All_Contacts(){
    		dataList = new ArrayList<Map<String,Object>>();
    		adapter = new SimpleAdapter(Contact.this, dataList, R.layout.layout_contacts, new String[]{"_id","name","sex","phone" }, new int[]{R.id._id,R.id._name,R.id._sex,R.id._phone});
    		
    		DBHelper dbHelper = new DBHelper(Contact.this, "Contacts.db");
    		SQLiteDatabase db = dbHelper.getReadableDatabase();
    		Cursor cursor = db.rawQuery("select * from tb_persons", null);
    		cursor.moveToFirst();
    		
    		do {
    			
    			Map<String, Object> map = new HashMap<String, Object>();
    			map.put("_id", cursor.getInt(cursor.getColumnIndex("_id")));
    			map.put("name", cursor.getString(cursor.getColumnIndex("name")));
    			map.put("sex", cursor.getString(cursor.getColumnIndex("sex")));
    			map.put("phone", cursor.getString(cursor.getColumnIndex("phone")));
    			dataList.add(map);
    			
    		}while(cursor.moveToNext());
    		
    		cursor.close();
    		db.close();
    		
    		lists.setAdapter(adapter);
    	}
    }
    
    MainActivity.java文件
    public class MainActivity extends Activity {
    
    	private Button btn_Add;
    	private Button btn_OK;
    	private Button btn_Cancel;
    	
    	private EditText nameText;
    	private EditText sexText;
    	private EditText phoneText;
    	
    	private LinearLayout info_Layout;
    	private SQLiteDatabase db;
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		btn_Add = (Button) findViewById(R.id.btn_add);
    		btn_OK = (Button) findViewById(R.id.btn_OK);
    		btn_Cancel = (Button) findViewById(R.id.btn_Cancel);
    		
    		nameText = (EditText) findViewById(R.id.name);
    		sexText = (EditText) findViewById(R.id.sex);
    		phoneText = (EditText) findViewById(R.id.phone);
    		
    		info_Layout = (LinearLayout) findViewById(R.id.info_form);
    		
    		DBHandler();
    	}
    	//辅助方法,打开添加联系人信息区域
    	public void add_Contact(View v){
    		info_Layout.setVisibility(View.VISIBLE);
    		btn_Add.setEnabled(false);
    	}
    	//跳转到查询所有联系人页面
    	public void search_All(View v){
    		Intent intent = new Intent(MainActivity.this, Contact.class);
    		startActivity(intent);
    	}
    	//添加联系人信息区域
    	public void insert_Info(View v){
    		
    		long id =0 ;
    		
    		String name = nameText.getText().toString().trim();
    		String sex = sexText.getText().toString().trim();
    		String phone = phoneText.getText().toString().trim();
    		
    		ContentValues values = new ContentValues();
    		values.put("name", name);
    		values.put("sex", sex);
    		values.put("phone", phone);
    		
    		db = openOrCreateDatabase("Contacts.db", MODE_PRIVATE, null);
    				
    		id = db.insert("tb_persons", null, values);
    		values.clear();
    		db.close();
    
    		nameText.setText("");
    		sexText.setText("");
    		phoneText.setText("");
    		
    		info_Layout.setVisibility(View.INVISIBLE);
    		btn_Add.setEnabled(true);
    		if (id==-1) {
    			Toast.makeText(this, "联系人添加失败!", Toast.LENGTH_SHORT).show();
    			return ;
    		}
    		Toast.makeText(this, "联系人添加成功!", Toast.LENGTH_SHORT).show();
    	}
    	//清空添加信息框
    	public void cancel_Info(View v){
    		nameText.setText("");
    		sexText.setText("");
    		phoneText.setText("");
    		
    		info_Layout.setVisibility(View.INVISIBLE);
    		btn_Add.setEnabled(true);
    		Toast.makeText(this, "已取消添加!", Toast.LENGTH_SHORT).show();
    	}
    	
    //创建联系人数据库
    	private void DBHandler(){
    		//创建应用程序的数据库
    		db = openOrCreateDatabase("Contacts.db", MODE_PRIVATE, null);
    		db.execSQL("create table if not exists tb_persons(_id integer primary key autoincrement,name text not null,sex text not null,phone text not null)");
    	}
    }
    

                     应用程序结构图以及程序的运行效果:

           

      以上就是三种方式的原理,代码比较凌乱,有空再好好梳理下!相信分享的力量,坚持就是胜利!

    https://github.com/AcerWang
  • 相关阅读:
    【LeetCode题解】844_比较含退格的字符串(Backspace-String-Compare)
    【LeetCode题解】25_k个一组翻转链表(Reverse-Nodes-in-k-Group)
    【LeetCode题解】24_两两交换链表中的节点(Swap-Nodes-in-Pairs)
    【LeetCode题解】347_前K个高频元素(Top-K-Frequent-Elements)
    【LeetCode题解】19_删除链表的倒数第N个节点(Remove-Nth-Node-From-End-of-List)
    【LeetCode题解】61_旋转链表(Rotate-List)
    IdentityServer4密码模式接入现有用户数据表
    .Net Core Swagger:Actions require an explicit HttpMethod binding for Swagger 2.0
    ABP缓存
    ABP仓储
  • 原文地址:https://www.cnblogs.com/AcerWang/p/4102757.html
Copyright © 2020-2023  润新知