美文网首页
Android数据存储

Android数据存储

作者: shawXXQ | 来源:发表于2017-10-05 17:11 被阅读0次

    SharedPreferences存储

    采用键值对的方式将数据存储在一个XML文件中。
    用途:主要用于保存应用内用户的一些偏好设置,如应用的音量等等。

    数据存储过程

    存数据

    ①获取SharedPreferences对象,有三种方式:

            /**
             * 第一个参数为文件名称
             * 第二个参数为操作模式,常用的为MODE_PRIVATE,表示只有当前应用程序才可以对这个文件进行读写
             */
            sharedPreferences = getSharedPreferences("test", MODE_PRIVATE);
            
            /**
             * 只接收一个操作模式参数
             * 默认将当前活动的类名作为文件名
             */
            sharedPreferences = getPreferences(MODE_PRIVATE);
            
            /**
             * 参数为上下文对象
             * 使用当前应用程序的包名作为前缀来命名文件
             */
            sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    

    ②调用SharedPreferences对象的edit()方法得到SharedPreferences.Editor对象

            SharedPreferences.Editor editor = sharedPreferences.edit();
    

    ③向SharedPreferences.Editor对象采用键值对的形式添加数据

            editor.putString("name", "shaw");
            editor.putInt("age", 21);
            editor.putBoolean("student", true);
    

    前三步常用的写法为:

            SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
    

    ④调用apply()方法提交数据

            editor.apply();
    

    取数据

    ①获取SharedPreferences对象
    ②调用SharedPreferences对象的getString()、getInt()等方法读取数据

            /**
             * 第一个参数为对应的键
             * 第二个参数为找不到键对应的值时的默认返回值
             */
            sharedPreferences.getString("name", "");
            sharedPreferences.getInt("age", 0);
            sharedPreferences.getBoolean("student", false);
    

    文件存储

    内部存储

    内部存储即存储在应用程序内部,且文件默认是只能被当前应用所访问的,当卸载应用的时候,对应的内部存储的文件也会被删除。SharedPreferences和SQLite数据库都是存储在内部存储空间上的。

        /**
         * 保存内部存储中的内容
         * 内部存储不需要声明权限
         * 使用openFileOutput来打开一个输出流
         */
        public void saveInner() {
            FileOutputStream fos = null;
            String input = inner_et.getText().toString();
            try {
                fos = openFileOutput("inner.txt", MODE_PRIVATE);
                fos.write(input.getBytes());
                Toast.makeText(this, "保存到内部存储文件完成", Toast.LENGTH_SHORT).show();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fos != null) {
                    try {
                        //关闭流
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * 读取内部存储中的内容
         * 使用openFileInput来打开一个输入流
         */
        public void showInner() {
            FileInputStream fis = null;
            try {
                fis = openFileInput("inner.txt");
                int len = 0;
                byte[] buf = new byte[1024];
                //只要还没读到文件末尾就一直读取
                while ((len = fis.read(buf)) != -1) {
                    //将byte类型的数组转换为String类型显示
                    Toast.makeText(this, "读取到了" + new String(buf, 0, len), Toast.LENGTH_SHORT).show();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    

    执行效果

    GIF.gif

    外部存储

    外部存储并非特指sdcard,无论安卓手机上是否有可移动的sdcard,都存在着外部存储空间,因为访问可移动的sdcard或者手机的内置外部存储都是通过相同的api。当手机连接电脑时,电脑可识别的部分一定为外部存储空间。
    使用外部存储时要先检验存储介质是否可用

           //判断当前sdcard是否可用
           if (state.equals(Environment.MEDIA_MOUNTED)) {
               Log.i("tag", "当前sdcard可用");
           } else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
               Log.i("tag", "当前sdcard只有读取权限");
               flag = false;
           } else {
               Log.i("tag", "当前sdcard不可用");
               flag = false;
           }
    
       /**
         * 使用外部存储保存图片
         */
        public void saveImage() {
            BufferedOutputStream bos = null;
            BufferedInputStream bis = null;
            try {
                //获取sdcard根路径
                File sdPath = Environment.getExternalStorageDirectory();
                file = new File(sdPath, "test.jpg");
                //读取项目中的图片资源
                InputStream is = getResources().openRawResource(R.drawable.orange);
                OutputStream os = new FileOutputStream(file);
                //使用输入输出缓冲流进行读写操作
                bis = new BufferedInputStream(is);
                bos = new BufferedOutputStream(os);
                int len = 0;
                byte[] buf = new byte[1024];
                while ((len = bis.read(buf)) != -1) {
                    //从0开始写到len
                    bos.write(buf, 0, len);
                    //刷新操作
                    bos.flush();
                }
                Toast.makeText(this, "图片写入完成", Toast.LENGTH_SHORT).show();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //关闭流操作
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (bos != null) {
                    try {
                        bos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * 显示图片
         */
        public void showImage() {
            //从文件中读取图片
            Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
            out_image.setImageBitmap(bitmap);
        }
    

    对外部存储的操作需要添加权限

        <!--添加写入权限-->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    若运行在Android6.0(API 23)及以上的系统中,需要添加动态权限处理

            //申请向外部存储写数据的权限
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                }, 1);
    
    GIF.gif

    常用的缓存路径

            Log.d("tag", "路径1 " + this.getCacheDir());
            Log.d("tag", "路径2 " + this.getExternalCacheDir());
            Log.d("tag", "路径3 " + Environment.getDownloadCacheDirectory());
    
    图片.png

    路径1为内部存储缓存
    路径2位外部存储缓存
    路径3为根目录缓存


    SQLite数据库存储

    数据库创建

    继承SQLiteOpenHelper类并重写onCreate()和onUpgrade()方法

    public class MyDatabaseHelper extends SQLiteOpenHelper {
        private static final String CREATE_BOOK = "create table Book(" +
                "id integer primary key autoincrement," +
                "author text," +
                "price real," +
                "pages integer," +
                "name text)";
    
        private Context mContext;
    
        public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
            super(context, name, factory, version);
            mContext = context;
        }
    
        //数据库被创建时执行,只执行一次
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_BOOK);
            Toast.makeText(mContext, "Create succeed", Toast.LENGTH_SHORT).show();
        }
    
        //数据库版本更新时执行
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
    
    public class MainActivity extends AppCompatActivity {
        private MyDatabaseHelper dbHelper;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            /**
             * 第一个参数为context对象
             * 第二个参数为数据库名
             * 第三个参数为一个自定义的Cursor对象,一般都为null
             * 第四个参数为版本号
             * 实例化该对象后使用构造方法创建数据库
             */
            dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
            Button createDatabase = (Button) findViewById(R.id.create_database);
            Button addData = (Button) findViewById(R.id.add_data);
            //创建数据库
            createDatabase.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //数据库已存在则打开,否则创建
                    dbHelper.getWritableDatabase();
                }
            });
    

    插入数据

            /**
             * 向表中添加数据
             */
            addData.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    /**
                     * getWritableDatabase()返回一个可对数据库进行读写操作的对象,
                     * 当数据库不可写入时,将出现异常
                     *
                     * getReadableDatabase()返回一个可对数据库进行读写操作的对象,
                     * 当数据库不可写入时,返回的对象以只读的方式打开数据库
                     */
                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    ContentValues values = new ContentValues();
                    /**
                     * 开始装填第一条数据
                     */
                    values.put("name", "The Da Vinci Code");
                    values.put("author", "Dan Brown");
                    values.put("pages", 454);
                    values.put("price", 16.96);
                    db.insert("Book", null, values);
    

    更新数据

                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    ContentValues values = new ContentValues();
                    values.put("price", 10.99);
                    db.update("Book", values, "name=?", new String[]{"The Da Vinci Code"});
    

    删除数据

                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    db.delete("Book", "pages>?", new String[]{"500"});
    

    查询数据

                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    /**
                     * 第一个参数为表名
                     * 第二个参数指定查询的列名
                     * 第三个参数指定where约束条件
                     * 第四个参数为where中的占位符提供具体的值
                     * 第五个参数指定需要group by的列
                     * 第六个参数对group by后的结果进一步约束
                     * 第七个参数指定查询结果的排序方式,ASC由小到大,DESC由大到小
                     */
                    Cursor cursor = db.query("Book", null, null, null, null, null, null);
                    if (cursor.moveToFirst()) {
                        do {
                            //遍历Cursor对象
                            String name = cursor.getString(cursor.getColumnIndex("name"));
                            int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        } while (cursor.moveToNext());
                    }
                    cursor.close();
    

    也可以使用SQL语句完成CRUD操作

                    db.execSQL("insert into Book(name,author,pages,price) values(?,?,?,?)", new String[]{
                            "The Da Vinci Code", "Dan Browm", "454", "16.96"
                    });
                    db.execSQL("update Book set price=? where name=?", new String[]{
                            "10.99", "The Da Vinci Code"
                    });
                    db.execSQL("delete from Book where pages>?", new String[]{"500"});
                    db.rawQuery("select * from Book", null);
    

    即除了查询操作使用rawQuery()方法外,其他操作均使用execSQL()方法完成。


    Sqlite数据库事务管理
    为了保证数据库中的某些操作要么同时执行,要么同时不执行,需要添加数据库事务管理,

                    db.beginTransaction();
                    //具体的数据库操作逻辑
                    db.setTransactionSuccessful();
                    db.endTransaction();
    

    相关文章

      网友评论

          本文标题:Android数据存储

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