Android之数据存储

作者: 拨云见日aaa | 来源:发表于2019-09-28 20:25 被阅读0次

    一、简介

    1.文件存储
    2.sd卡存储
    3.sharepreferences存储
    4.序列化xml文件
    5.sqlite存储

    二、文件存储

    文件存储有两个主要的文件夹,一个是file文件夹,另一个是cache文件夹(这个文件夹放一些不重要的缓存文件或者配置文件)

    • 可以通过getFilesDir()方法获得file文件
    • 通过getCachesDir获取cache文件
    • 通过getAbsolutePath()获取绝对路径
    • 通过openFileOutout(文件名,模式)获取file的输出流
    • 通过openFileInput(文件名)获取file的输入流
      (注:这里的输入输出是相对程序自己的,不是file文件)

    代码示例:

    //布局文件就一个button
    //点击按钮把一句话存到file文件下
    //获取cache文件夹,只能用获取路径的方式
    public class MainActivity extends AppCompatActivity {
        OutputStream os=null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
        public void click(View v){
            try {
                //os=new FileOutputStream(getFilesDir().getAbsolutePath()+"/hello.txt");//通过获取路径的方式获取输出流
               os=openFileOutput("hello.txt",MODE_PRIVATE);//直接获取输出流
                os.write("这仅仅只是一个测试".getBytes());
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }catch(IOException e){
                e.printStackTrace();
            }finally{
                if(os!=null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    三、SD卡存储

    将文件存储的sd卡上

    • 通过getExternalFilesDir(null)获取mnt/sdcard/Android/data/< package name >/files路径(当参数传null的时候默认是files,当传文件名的时候是files子文件路径)
    • 通过getExternalStorageState()方法获取当前SD卡的状态
      (MEDIA_MOUNTED为SD卡正常状态)
    • 通过Envirionment.getExternalStorageDirectory()获取sd卡根路径
      (存储时不推荐用这个路径)
    • 通过根路径.getToalSpace()/getFreeSpace()分别获取总空间大小和剩余空间大小
    • 通过Formatter.formatFileSize(Content con,size)将空间大小格式化

    代码示例:

    //讲一句话存入sd卡mnt/sdcard/Android/data/< package name >/files路径下
    public class MainActivity extends AppCompatActivity {
        OutputStream os=null;
        TextView tv;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv=findViewById(R.id.tv);
        }
        public void click(View view){
            if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){   
                 //动态申请权限
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
            }else if(ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},2);
            }else{
                if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                    //判断sd卡状态,注意这里判断要用equals比较而不要用==判断
                    try {
                        File external=Environment.getExternalStorageDirectory();//获取根目录
                        long toalSpace=external.getTotalSpace();
                        long freeSpace=external.getFreeSpace(); 
                        //格式化空间大小
                        tv.setText("总空间:"+Formatter.formatFileSize(getApplicationContext(),toalSpace)+"剩余空间:"+Formatter.formatFileSize(getApplicationContext(),freeSpace));
                        //获取sd卡mnt/sdcard/Android/data/< package name >/files路径
                        File externlStorage = getExternalFilesDir(null);
                        Toast.makeText(this,externlStorage.getAbsolutePath(),Toast.LENGTH_LONG).show();
                        os = new FileOutputStream(externlStorage.getAbsolutePath() + "/hello.txt");
                        os.write("这仅仅只是个测试".getBytes());
                    }catch(FileNotFoundException e){
                        e.printStackTrace();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                }
    
            }
        }
    }
    

    四、SharedPreferences存储

    sharePreferences配置文件实质是一个xml文件,用来记录一些状态,类似记住用户名之类的

    • 通过getSharedPreferences()获取SharePreferences对象
      (这个对象只能用来读数据)
    • 通过SharedPreferences对象.edit()获得SharePreferences.Editor对象
      (这个对象用来向里写数据)
    • SharedPreferences对象.getXXX()方法读数据
    • Editor对象.putXXX()方法存数据
      (数据是键值对的形式存储,最后一定要掉Editor对象.commit()提交)

    代码示例:

    //布局是一个TextView和两个Button
    public class MainActivity extends AppCompatActivity {
    SharedPreferences sp=null;
    TextView tv;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv=findViewById(R.id.tv);
            sp=getSharedPreferences("hello", MODE_PRIVATE);//获取SharedPreferences对象
        }
        public void click(View view){
            SharedPreferences.Editor editor=sp.edit();//获取Editor对象
            editor.putString("hello","这仅仅只是一次测试");//写数据
            editor.commit();
        }
        public void click1(View view){
            tv.setText( sp.getString("hello",""));//读数据
        }
    }
    

    运行结果:

    运行结果

    五、xml文件的序列化和解析

    xml序列化通过XMLSerializer对象进行序列化,通过XmlPullParser进行pull解析

    (1)序列化
    • 通过Xml.newSerializer()获取XmlSerializer对象
    • setOutput(Writer writer)/setOutput(OutputStream os,String encoding)获取输出流
    • startDocument(String encoding,boolean Standalone)/endDocument()开始Document和结束Document
    • startTag(String nameSpace,String name)/endTag(String nameSpace,String name)开始和结束标签
    • text(String text)设置文本
    • setProperty(String name,Object value)设置属性
    (2)解析
    • Xml.newPullParser()获取XmlPullParser对象
    • setInput(InputStream is,String encoding)设置输入
    • getEventType()获取事件类型
    • next()进入下一个事件
      -getName()获取姓名

    代码示例:

    //序列化一个xml,然后解析出来
    public class MainActivity extends AppCompatActivity {
    TextView tv=null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv=findViewById(R.id.tv);
        }
        public void click(View view){
            XmlSerializer xml= Xml.newSerializer();//获取XmlSerializer对象
            OutputStream os=null;
            try {
                os=openFileOutput("hello.xml",MODE_PRIVATE);
                xml.setOutput(os,"utf-8");
                xml.startDocument("utf-8",true);//开始Document
                xml.startTag(null,"students");//开始标签
                xml.startTag(null,"student");
                xml.startTag(null,"name");
                xml.text("jty");//设置文本
                xml.endTag(null,"name");
                xml.startTag(null,"number");
                xml.text("1551654");
                xml.endTag(null,"number");//结束标签
                xml.endTag(null,"student");
                xml.startTag(null,"student");
                xml.startTag(null,"name");
                xml.text("zcf");
                xml.endTag(null,"name");
                xml.startTag(null,"number");
                xml.text("1551655");
                xml.endTag(null,"number");
                xml.endTag(null,"student");
                xml.endTag(null,"students");
                xml.endDocument();//结束Document
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(os!=null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        public void click1(View v){
            XmlPullParser pull=Xml.newPullParser();//获取XmlpullParser对象
            InputStream is=null;
            StringBuffer str=new StringBuffer();
            try {
                is=openFileInput("hello.xml");
                pull.setInput(is,"utf-8");
               int eventType=pull.getEventType();//获取事件类型
               while(eventType!=XmlPullParser.END_DOCUMENT){
                   switch (eventType){
                       case XmlPullParser.START_TAG:
                           if(pull.getName().equals("name")){//获取标签名
                               
                                str.append("name:"+pull.nextText()+" ");
                          }else if (pull.getName().equals("number")){
                               
                               str.append("number:"+pull.nextText()+" ");
                           }
                           break;
                   }
                         eventType=pull.next();//下一个事件并返回事件类型
               }
               tv.setText(str);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                if(is!=null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    六、Sqlite存储

    sqlite是Android自带的数据库十分轻量,跨平台,绿色解压就能用。

    • 首先继承SqliteOpenHelper,这个类有一个构造方法,里面的参数分别为上下文、数据库的名字、游标工厂(一般为null)、版本号,需要实现onCreate()方法和onUpgrade()方法
      (onCreate()数据库创建的时候会被调用,一般在这里面建表和初始化 ,onUpgrade()在版本升级的时候被调用,一般这里做表的修改和添加新的表等操作)
    • 通过 new SqliteOpenHelper()方法获取SqliteOpenHelper对象
    • SqlieOpenHelper对象.getReadableDatabase()/getWriteableDatabase获i取database对象
      (二者作用大部分时相同,都是打开或创建一个可读可写的数据库,当磁满的时候,第一个方法是返回一个可读的数据库第二个会失败)
    • 执行sql语句操作数据库,execsql用来执行增删改sql语句的,rawQuery执行查找操作sql语句查询的返回值为Cursor类型
    • 用api执行数据库操作insert(表名,备用列名,Values)(Content Values values=new ContentValues valuse.put(列名,值)) / delete(表名,条件(XXX=?),问号的参数值数组({xxx,xxx})) / updata(表名,Content Values,条件(写法同delete),条件值数组(写法同delete)) / query(表名,列名(数组),条件,条件值,groupby(sql里的分组),having(条件,分组后的行条件),limit(结果限定))分别为插入/删除/更新/查询
    • cursor操作通过moveToNext指向下一行/getXXX(列号)获取列号对应的值/getColumnIndex(键)获取键对应的列号
    • 用close()方法关闭数据库(注:用完要关闭数据库)

    代码示例:

    (1)继承SqliteOpenHelper的类
    public class MySqliteHelper extends SQLiteOpenHelper {//继承SqliteOpenHelper类
        public MySqliteHelper(Context context){
            super(context,"myDataBase",null,1);//构造方法
        }
        public void onCreate(SQLiteDatabase db){
          db.execSQL("create table information(user_id integer primary key autoincrement,user_name varchar,user_age integer)");
          //创建表,注意自增约束在sqlite为autoincrement,int类型要写integer
        }
        public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){
        //升级版本在这里操作,本代码就不演示了
        }
    }
    
    (2)Activity中的代码
    public class MainActivity extends AppCompatActivity {
    SQLiteDatabase db=null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            MySqliteHelper helper=new MySqliteHelper(this);//创建helper类
            db=helper.getReadableDatabase();//获取数据库
        }
        public void click1(View view){
            ContentValues values=new ContentValues();
            values.put("user_name","jty");
            values.put("user_age",10);
            db.insert("information","user_id",values);//插入
            ContentValues values1=new ContentValues();
            values.put("user_name","zcf");
            values.put("user_age",11);
            db.insert("information","user_id",values);
        }
        public void click2(View view){
            db.delete("information","user_name=?",new String[]{"jty"});//删除
        }
        public void click3(View view){
            ContentValues values=new ContentValues();
            values.put("user_age",15);
            db.update("information",values,"user_name=?",new String[]{"zcf"});//更新
        }
        public void click4(View view){
            Cursor cursor=db.query("information",new String[]{"user_id","user_name","user_age"},null,null,null,null,null);//
            查找
            while(cursor.moveToNext()){//指向下一条
                Log.i("output","user_id:"+cursor.getInt(cursor.getColumnIndex("user_id")));
                //获取值
                Log.i("output","user_name:"+cursor.getString(cursor.getColumnIndex("user_name")));
                Log.i("output","user_age:"+cursor.getInt(cursor.getColumnIndex("user_age")));
            }
        }
        public void onDestroy() {
            db.close();//在activity销毁时关闭数据库
            super.onDestroy();
        }
    }
    
    (3)扩展

    事务的应用

    db.beginTransaction();//开启事务
    try{
    //要做的事务
    db.setTransactionSuccessful();//如果没问题置成成功
    }finally{
    db.endTransaction();//结束事务时会检查是否成功,如果没成功回滚
    //其它操作
    }
    

    相关文章

      网友评论

        本文标题:Android之数据存储

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