美文网首页安卓开发那点事
Android_7_数据存数方式

Android_7_数据存数方式

作者: icechao | 来源:发表于2017-11-23 15:24 被阅读0次

    Android_7_数据存数方式

    使用SharedPreferences存储数据

    • 获取SharedPreferences对象

      1. 调用Context对象的getSharedPreferences()方法

      2. 调用Activity对象的getPreferences()方

        调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享.
        调用Activity对象的getPreferences()方法获得的SharedPreferences对象只能在该Activity中使用.       
        Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
        Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件.
        Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件.
        MODE_WORLD_READABLE:表示当前文件可以被其他应用读取.
        MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入
        
    • SharedPreferences存储数据

      SharedPreferences只支持基本数据类型

            public static boolean getBoolean(Context context, String key) {
            if (sp == null) {
            sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
            }
             return sp.getBoolean(key, false);
            }
      
      封装过的使用SharedPreferences存储一个bool值对象,同理可以使用putInt,putString等方法保存其他类型的数据

    文件存储数据

    文件存储就是通过流的方式,把数据写到文件中,使用Context,Environment获得路径

    Context常用方法目录:
    
    方法:getFilesDir 
    释义:返回通过Context.openFileOutput()创建和存储的文件系统的绝对路径,应用程序文件,这些文件会在程序被卸载的时候全部删掉。
     /data/data/package_name/files
    
    方法:getDir
    释义:这是一个可以存放你自己应用程序自定义的文件,你可以通过该方法返回的File实例来创建或者访问这个目录,注意该目录下的文件只有你自己的程序可以访问。
    getDir("test", Context.MODE_WORLD_WRITEABLE)
    /data/data/package_name/app_test
    
    方法:getCacheDir
    释义:返回应用程序指定的缓存目录,这些文件在设备内存不足时会优先被删除掉,所以存放在这里的文件是没有任何保障的,可能会随时丢掉。
    /data/data/package_name/cache
    
    方法:getExternalFilesDir
    释义:使用这个方法需要写外部存储的权限“”,这个目录是与应用程序相关的外部文件系统,这些文件只属于你的应用,不能被其它人访问。同样,这个目录下的文件在程序被卸载时也会被一同删除。该方法也可以指定返回某一资源类型,这些类型可以是:
     Environment#DIRECTORY_MUSIC 音乐
     Environment#DIRECTORY_PODCASTS 音频
     Environment#DIRECTORY_RINGTONES 铃声
     Environment#DIRECTORY_ALARMS 闹铃
     Environment#DIRECTORY_NOTIFICATIONS 通知铃声
     Environment#DIRECTORY_PICTURES 图片
     Environment#DIRECTORY_MOVIES 视频
    getExternalFilesDir( "/" )
    /storage/sdcard0/Android/data/package_name/files
    getExternalFilesDir( Environment.DIRECTORY_PICTURES )
    /storage/sdcard0/Android/data/package_name/files/Pictures
    方法:getExternalCacheDir
    使用这个方法需要写外部存储的权限“”,调用该方法会返回应用程序的外部文件系统(Environment.getExternalStorageDirectory())目录的绝对路径,它是用来存放应用的缓存文件,它和getCacheDir目录一样,目录下的文件都会在程序被卸载的时候被清除掉。  
    /storage/sdcard0/Android/data/package_name/cache
    方法:getDatabasePath
    释义:保存通过Context.openOrCreateDatabase 创建的数据库文件
    getDatabasePath("DATABASE_NAME") )
    /data/data/package_name/databases/DATABASE_NAME
    
    方法:getPackageCodePath
    释义:返回android 安装包的完整路径,这个包是一个zip的压缩文件,它包括应用程序的代码和assets文件。
    /data/app/package_name-2.apk
    
    方法:getPackageResourcePath
    释义:返回android 安装包的完整路径,这个包是一个ZIP的要锁文件,它包括应用程序的私有资源。
    /data/app/package_name-2.apk
    
    方法:getObbDir
    释义:返回应用程序的OBB文件目录(如果有的话),注意如果该应用程序没有任何OBB文件,这个目录是不存在的。
    /storage/sdcard0/Android/obb/package_name
    
    Environment
    Environment类去获取外部存储目录,在访问外部存储之前一定要先判断外部存储是否已经是可使用(已挂载&可使用)状态。并且需要在AndroidManifest.xml文件中添加外部存储读和写的权限。
    Environment类中提供了几个静态常量用于标识外部存储的状态,这些状态都是String类型
    MEDIA_BAD_REMOVAL 在没有挂载前存储媒体已经被移除。
    MEDIA_CHECKING 正在检查存储媒体。
    MEDIA_MOUNTED 存储媒体已经挂载,并且挂载点可读/写。
    MEDIA_MOUNTED_READ_ONLY 存储媒体已经挂载,挂载点只读。
    MEDIA_NOFS 存储媒体是空白或是不支持的文件系统。
    MEDIA_REMOVED 存储媒体被移除。
    MEDIA_SHARED 存储媒体正在通过USB共享。
    MEDIA_UNMOUNTABLE 存储媒体无法挂载。
    MEDIA_UNMOUNTED 存储媒体没有挂载。
    可以通过静态方法getExternalStorageState()来获取外部存储的状态,如果程序需要在外部存储里面读写数据,必须要先判断。
    

    SQLite数据库存储数据

    • SQLite是一款开源的、嵌入式关系型数据库,没有独立运行的进程,与所服务的应用程序在应用程序 进程空间内共生共存。它的代码与应用程序代码也是在一起的,或者说嵌入其中,作为托管它的程序 的一部分。因此不存在数据库的客户端和服务器,使用SQLite一般只需要带上它的一个动态库,就可 以享受它的全部功能。

    • SQLite支持的数据类型

          SQLite采用动态数据存储类型,会根据存入的值自动进行判断。SQLite支持以下5种数据类型:
        
          (1)NULL:空值
        
          (2)INTEGER:带符号的整型
        
          (3)REAL:浮点型
        
          (4)TEXT:字符串文本
        
          (5)BLOB:二进制对象
      
    • 创建SQLite数据库

      创建类继承自SQLiteOpenHelper,并复写其onCreate(),onUpgrade(),onDeleteDB()方法,其中onCreate()方法会在创建数据库后调用,在这里使用sql语句建表,在onUpgrade()方法中,是数据库升级时对比版本对表或数据进行修改,onDeleteDb()是数据库被删除时回调的方法

            public class AndroidSQLiteOpenHelper extends SQLiteOpenHelper {  
          
            // 数据库名称  
            public static final String DBNAME = "android.db";  
            // 数据库版本  
            public static final int VERSION = 2;  
            // 建表语句,大小写不敏感  
            private static final String CREATETABLE = "create table "  
                    + Person.TABLENAME  
                    + "(id string, name string, gender int, age int)";  
          
            public AndroidSQLiteOpenHelper(Context context) {  
                super(context, DBNAME, null, VERSION);  
            }  
          
            // 创建表  
            @Override  
            public void onCreate(SQLiteDatabase db) {  
                db.execSQL(CREATETABLE);  
            }  
          
            // 更新表  
            @Override  
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
                this.deleteDB(db);  
                this.onCreate(db);  
            }  
          
            // 删除表  
            private void deleteDB(SQLiteDatabase db) {  
                db.execSQL("drop table if exists " + Person.TABLENAME);  
            }  
        }  
      
    • 使用SQLite中的数据

      实例化上一步中定义的SQLiteOpenHelper子类对象,调用getWritableDatabase()方法可以获得SQLiteDataBase对象,使用SQLiteDataBase对象就可以直接对数据库进行操作了

        public DatabaseManager(Context context) {  
            dbHelper = new AndroidSQLiteOpenHelper(context);  
        }  
      
        // 插入记录  
        public int insert(Person person) {  
            Log.e("SQLite", "----insert----");  
            SQLiteDatabase db = dbHelper.getWritableDatabase();  
            db.beginTransaction();  
            try {  
                db.execSQL("insert into " + Person.TABLENAME  
                         + " values(?, ?, ?, ?)", new Object[] { person.id,  
                        person.name, person.gender, person.age });  
                db.setTransactionSuccessful();  
            } catch (Exception e) {  
                return 0;  
            } finally {  
                db.endTransaction();  
            }  
            db.close();  
            return 1;  
        }  
      
        // 删除记录  
        public int delete(Person person) {  
            Log.e("SQLite", "----delete----");  
            SQLiteDatabase db = dbHelper.getWritableDatabase();  
            db.beginTransaction();  
            try {  
                db.execSQL("delete from " + Person.TABLENAME + " where id = ?",  
                        new Object[] { person.id });  
                db.setTransactionSuccessful();  
            } catch (Exception e) {  
                return 0;  
            } finally {  
                db.endTransaction();  
            }  
            db.close();  
            return 1;  
        }  
      
        // 更新记录  
        public int update(Person person) {  
            Log.e("SQLite", "----update----");  
            SQLiteDatabase db = dbHelper.getWritableDatabase();  
            db.beginTransaction();  
            try {  
                db.execSQL("update " + Person.TABLENAME  
                            + " set name=?, gender=?, age=? where id=?", new Object[] {  
                        person.name, person.gender, person.age, person.id });  
                db.setTransactionSuccessful();  
            } catch (Exception e) {  
                return 0;  
            } finally {  
                db.endTransaction();  
            }  
            db.close();  
            return 1;  
        }  
      
        // 查询记录  
        public ArrayList<Person> query(String id) {  
            Log.e("SQLite", "----query----");  
            SQLiteDatabase db = dbHelper.getReadableDatabase();  
            Cursor cursor;  
            Person person;  
            ArrayList<Person> list = new ArrayList<Person>();  
            // 若fileId为null或""则查询所有记录  
            if (id == null || id.equals("")) {  
                cursor = db.rawQuery("select * from " + Person.TABLENAME, null);  
            } else {  
                cursor = db.rawQuery("select * from " + Person.TABLENAME  
                            + " where id=?", new String[] { id });  
            }  
            while (cursor.moveToNext()) {  
                person = new Person();  
                person.id = cursor.getString(cursor.getColumnIndex("id"));  
                person.name = cursor.getString(cursor.getColumnIndex("name"));  
                person.gender = cursor.getString(cursor.getColumnIndex("gender"));  
                person.age = cursor.getInt(cursor.getColumnIndex("age"));  
                Log.e("SQLite", person.toString());  
                list.add(person);  
            }  
            cursor.close();  
            db.close();  
            if (list.size() == 0) {  
                Log.e("SQLite", "****表中无数据****");  
            }  
            return list;  
            }
        }
      

    网络存储数据

    所谓网络存储就是把数据存储到服务器上,这个过程需要使用网络请求 
    

    使用ContentProvider存储数据

    • ContentProvider作为Android四大组件之一,一般自己很少定义ContentProvider,现多用在访问系统提供的数据上,ContentProvider可以实现在应用程序之间共享数据.

        1、ContentProvider使用表的形式来组织数据,无论数据的来源是什么,ContentProvider都会认为是一种表,然后把数据组织成表格
        2、ContentProvider提供的方法
        query:查询
        insert:插入
        update:更新
        delete:删除
        getType:得到数据类型
        onCreate:创建数据时调用的回调函数
      
    • 使用步骤

      1、 定义一个CONTENT_URI常量(里面的字符串必须是唯一)

          Public static final Uri CONTENT_URI = Uri.parse("content://com.MyContentprovider");
          如果有子表,URI为:
          Public static final Uri CONTENT_URI = Uri.parse("content://com.MyContentProvider/users");
      

      2、 定义一个类,继承ContentProvider

          Public class MyContentProvider extends ContentProvider
      

      3、实现ContentProvider的所有方法(query、insert、update、delete、getType、onCreate)

          public class MyContentProvider extends ContentProvider {
           //访问表的所有列
           public static final int INCOMING_USER_COLLECTION = 1;
           //访问单独的列
           public static final int INCOMING_USER_SINGLE = 2;
           //操作URI的类
           public static final UriMatcher uriMatcher;
           //为UriMatcher添加自定义的URI
           static{
           uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
           uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user",
           INCOMING_USER_COLLECTION);
           uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user/#",
           INCOMING_USER_SINGLE);
          
           }
           private DatabaseHelp dh;
           //为数据库表字段起别名
           public static HashMap userProjectionMap;
           static
           {
           userProjectionMap = new HashMap();
           userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID);
           userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
           }
           /**
           * 删除表数据
           */
           @Override
           public int delete(Uri uri, String selection, String[] selectionArgs) {
           System.out.println("delete");
           //得到一个可写的数据库
           SQLiteDatabase db = dh.getWritableDatabase();
           //执行删除,得到删除的行数
           int count = db.delete(UserTableMetaData.TABLE_NAME, selection, selectionArgs);
           return count;
           }
           /**
           * 数据库访问类型
           */
           @Override
           public String getType(Uri uri) {
           System.out.println("getType");
           //根据用户请求,得到数据类型
           switch (uriMatcher.match(uri)) {
           case INCOMING_USER_COLLECTION:
           return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE;
           case INCOMING_USER_SINGLE:
           return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE_ITEM;
           default:
           throw new IllegalArgumentException("UnKnown URI"+uri);
           }
           }
           /**
           * 插入数据
           */
           @Override
           public Uri insert(Uri uri, ContentValues values) {
           //得到一个可写的数据库
           SQLiteDatabase db = dh.getWritableDatabase();
           //向指定的表插入数据,得到返回的Id
           long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
           if(rowId > 0){//判断插入是否执行成功
           //如果添加成功,利用新添加的Id和
           Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
           //通知监听器,数据已经改变
           getContext().getContentResolver().notifyChange(insertedUserUri, null);
           return insertedUserUri;
           }
           return uri;
           }
           /**
           * 创建ContentProvider时调用的回调函数
           */
           @Override
           public boolean onCreate() {
           System.out.println("onCreate");
           //得到数据库帮助类
           dh = new DatabaseHelp(getContext(),MyContentProviderMetaData.DATABASE_NAME);
           return false;
           }
           /**
           * 查询数据库
           */
           @Override
           public Cursor query(Uri uri, String[] projection, String selection,
           String[] selectionArgs, String sortOrder) {
           //创建一个执行查询的Sqlite
           SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
           //判断用户请求,查询所有还是单个
           switch(uriMatcher.match(uri)){
           case INCOMING_USER_COLLECTION:
           //设置要查询的表名
           qb.setTables(UserTableMetaData.TABLE_NAME);
           //设置表字段的别名
           qb.setProjectionMap(userProjectionMap);
           break;
           case INCOMING_USER_SINGLE:
           qb.setTables(UserTableMetaData.TABLE_NAME);
           qb.setProjectionMap(userProjectionMap);
           //追加条件,getPathSegments()得到用户请求的Uri地址截取的数组,get(1)得到去掉地址中/以后的第二个元素
           qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1));
           break;
           }
           //设置排序
           String orderBy;
           if(TextUtils.isEmpty(sortOrder)){
           orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;
           }
           else{
           orderBy = sortOrder;
           }
           //得到一个可读的数据库
           SQLiteDatabase db = dh.getReadableDatabase();
           //执行查询,把输入传入
           Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
           //设置监听
           c.setNotificationUri(getContext().getContentResolver(), uri);
           return c;
          
           }
           /**
           * 更新数据库
           */
           @Override
           public int update(Uri uri, ContentValues values, String selection,
           String[] selectionArgs) {
           System.out.println("update");
           //得到一个可写的数据库
           SQLiteDatabase db = dh.getWritableDatabase();
           //执行更新语句,得到更新的条数
           int count = db.update(UserTableMetaData.TABLE_NAME, values, selection, selectionArgs);
           return count;
           }
          
          }
      

      4、在AndroidMinifest.xml中进行声明

        <provider   
              android:name=".cp.MyContentProvider"  
              android:authorities="com.cp.MyContentProvider"  
              android:exported="true" >  
        </provider>  
    
    • 这样一个ContentProvider就定义完成了,可以在另一个程序使用ContentResolver进行在应该间互相使用数据了

    相关文章

      网友评论

        本文标题:Android_7_数据存数方式

        本文链接:https://www.haomeiwen.com/subject/tncblxtx.html