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