• android 五种存储


    引用:http://www.2cto.com/kf/201204/125798.html

    Android提供的数据持久化存储方式有以下几种。

    1.Shared Preferences:以Key-Value形式存储数据


    2.Internal Storage:数据文件存储在内存卡


    3.External Storage:数据存储在外部设备,如SD卡等


    4.SQLite Databases:SQLite存储方式


    5.Network Connection:通过WebService等网络通信方式存储数据。

    一、Shared Preferences

    常用来存储应用中的用户偏好设置,例如应用的默认皮肤设置、记录用户上次登录信息等。数据的存储格式为Key-Value。

    下面通过案例,记录用户信息来了解如何使用Shared Preferences。

    介绍将使用到的Android SDK API:

    SharedPreferences类:提供了一批读取、遍历数据的API。

    Editor类:提供修改、保存数据API。
    getSharedPreferences(String name, int mode):指定存储文件的文件名,并设置访问权限


    getPreferences(int mode):如果你的Activity中只需要一个喜好文件,则可以不提供存储文件名,只需要设置访问权限


    更多介绍可以访问:http://android.toolib.net/guide/topics/data/data-storage.html#pref

    1、新建Android项目

    项目名称Shared Preferences,主Activity名称为MainActivity。

    2、设计主界面XML描述


    [html] <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
        android:orientation="vertical" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        > 
    <TextView   
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="@string/name" 
        /> 
      
    <EditText 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:id="@+id/name" 
        /> 
     
    <TextView 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/age"  
        /> 
         
    <EditText 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:id="@+id/age" 
        /> 
     
    <Button 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="@string/save"  
        android:onClick="save" 
        /> 
    </LinearLayout> 
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/name"
        />
     
    <EditText
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:id="@+id/name"
     />

    <TextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="@string/age"
     />
     
    <EditText
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:id="@+id/age"
     />

    <Button
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="@string/save"
     android:onClick="save"
     />
    </LinearLayout>界面效果:

    \" src=


     

    3、定义“保存”按钮的save事件处理方法


    [java] package mr.jin.shared; 
     
    import android.app.Activity; 
    import android.content.Context; 
    import android.content.SharedPreferences; 
    import android.content.SharedPreferences.Editor; 
    import android.os.Bundle; 
    import android.view.View; 
    import android.widget.EditText; 
    import android.widget.Toast; 
     
    public class MainActivity extends Activity { 
        private EditText nameEdit; 
        private EditText ageEdit; 
        private String USERINFO="userInfo"; 
         
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
             
            nameEdit = (EditText) findViewById(R.id.name);//应用打开后,即查找到姓名、年龄的文本框对象。  
            ageEdit = (EditText) findViewById(R.id.age); 
     
            init(); 
        } 
         
        public void save(View v){ 
            try{ 
                SharedPreferences perference = getSharedPreferences(USERINFO, Context.MODE_PRIVATE); 
                Editor editor = perference.edit(); 
                editor.putString("name", nameEdit.getText().toString()); 
                editor.putString("age", ageEdit.getText().toString()); 
                editor.commit();//未调用commit前,数据实际是没有存储进文件中的。 调用后,存储存储  
                 
                Toast.makeText(this, R.string.success, Toast.LENGTH_LONG).show(); 
                 
            }catch(Exception e){ 
                Toast.makeText(this, R.string.error, Toast.LENGTH_LONG).show(); 
            } 
        } 
         
        /*第一次打开应用时,读取本地用户信息设置*/ 
        public void init(){ 
            SharedPreferences perference = getSharedPreferences(USERINFO, Context.MODE_PRIVATE); 
            nameEdit.setText(perference.getString("name", "")); 
            ageEdit.setText(perference.getString("age", "")); 
        } 

    package mr.jin.shared;

    import android.app.Activity;
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.Toast;

    public class MainActivity extends Activity {
     private EditText nameEdit;
     private EditText ageEdit;
     private String USERINFO="userInfo";
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
           
            nameEdit = (EditText) findViewById(R.id.name);//应用打开后,即查找到姓名、年龄的文本框对象。
            ageEdit = (EditText) findViewById(R.id.age);

            init();
        }
       
        public void save(View v){
         try{
          SharedPreferences perference = getSharedPreferences(USERINFO, Context.MODE_PRIVATE);
          Editor editor = perference.edit();
          editor.putString("name", nameEdit.getText().toString());
          editor.putString("age", ageEdit.getText().toString());
          editor.commit();//未调用commit前,数据实际是没有存储进文件中的。 调用后,存储存储
          
          Toast.makeText(this, R.string.success, Toast.LENGTH_LONG).show();
             
         }catch(Exception e){
          Toast.makeText(this, R.string.error, Toast.LENGTH_LONG).show();
         }
        }
       
        /*第一次打开应用时,读取本地用户信息设置*/
        public void init(){
         SharedPreferences perference = getSharedPreferences(USERINFO, Context.MODE_PRIVATE);
         nameEdit.setText(perference.getString("name", ""));
         ageEdit.setText(perference.getString("age", ""));
        }
    }


    4、部署应用

    第一次打开应用,两个输入框都为空。在输入信息后,点击保存。退出应用,再次打开应用,将显示之前保存的用户信息。


    二、Internal Storage

    可以将文件存储在内部存储设备,默认文件访问权限是私有的,除了当前应用,其他应用无法访问。当用户卸载您的应用程序,这些文件将被删除。

    来看看Android SDK提供的文件存储权限:

    Context.MODE_APPEND;//追加方式存储
    Context.MODE_PRIVATE;//私有方式存储,其他应用无法访问
    Context.MODE_WORLD_READABLE;//允许其他应用读取数据
    Context.MODE_WORLD_WRITEABLE;//允许其他应用写入、读取数据


    1.建立项目

    项目名称InternalStorage,主Activity类名称MainActivity。

    2.定义界面及XML描述

    \" src=


     

    print?<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
        android:orientation="vertical" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        > 
    <TextView   
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="输入文字" 
        /> 
      
     <EditText 
        android:minLines="3" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:id="@+id/editText" 
        /> 
      
     <Button 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="保存" 
        android:onClick="save" 
        /> 
         
     <TextView 
        android:id="@+id/showText" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        /> 
         
     <Button 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="显示保存的数据" 
        android:onClick="showData" 
        /> 
    </LinearLayout> 
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="输入文字"
        />
     
     <EditText
      android:minLines="3"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:id="@+id/editText"
      />
     
     <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="保存"
      android:onClick="save"
      />
      
     <TextView
      android:id="@+id/showText"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      />
      
     <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="显示保存的数据"
      android:onClick="showData"
      />
    </LinearLayout>
    3.定义“保存”按钮的save、“显示保存的数据”按钮的事件处理


    [java] package mr.jin.internal; 
     
    import java.io.ByteArrayOutputStream; 
    import java.io.FileInputStream; 
    import java.io.FileOutputStream; 
     
    import android.app.Activity; 
    import android.content.Context; 
    import android.os.Bundle; 
    import android.view.View; 
    import android.widget.EditText; 
    import android.widget.TextView; 
    import android.widget.Toast; 
     
    public class MainActivity extends Activity { 
        private EditText editText; 
        private TextView showText; 
         
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
             
            editText = (EditText) findViewById(R.id.editText); 
            showText = (TextView) findViewById(R.id.showText); 
        } 
         
        public void save(View v){ 
            String content = editText.getText().toString(); 
             
            try { 
                FileOutputStream outfile = openFileOutput("current_file", Context.MODE_PRIVATE); 
                outfile.write(content.getBytes()); 
                outfile.close(); 
                Toast.makeText(this, "保存成功", 3000).show(); 
            } catch (Exception e) { 
                Toast.makeText(this, "保存失败", 3000).show(); 
                e.printStackTrace(); 
            } 
        } 
         
        public void showData(View v){ 
            try { 
                FileInputStream showfile = openFileInput("current_file"); 
                ByteArrayOutputStream out = new ByteArrayOutputStream(); 
                byte[] data = new byte[1024]; 
                int len = 0; 
                 
                while( (len=showfile.read(data))  != -1){ 
                    out.write(data, 0, len); 
                } 
                 
                String content = new String(out.toByteArray()); 
                 
                showText.setText(content); 
                 
                Toast.makeText(this, "显示成功", 3000).show(); 
            } catch (Exception e) { 
                Toast.makeText(this, "显示失败", 3000).show(); 
                e.printStackTrace(); 
            } 
        } 

    package mr.jin.internal;

    import java.io.ByteArrayOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;

    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;

    public class MainActivity extends Activity {
        private EditText editText;
        private TextView showText;
       
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
           
            editText = (EditText) findViewById(R.id.editText);
            showText = (TextView) findViewById(R.id.showText);
        }
       
        public void save(View v){
         String content = editText.getText().toString();
         
         try {
       FileOutputStream outfile = openFileOutput("current_file", Context.MODE_PRIVATE);
       outfile.write(content.getBytes());
       outfile.close();
       Toast.makeText(this, "保存成功", 3000).show();
      } catch (Exception e) {
       Toast.makeText(this, "保存失败", 3000).show();
       e.printStackTrace();
      }
        }
       
        public void showData(View v){
         try {
       FileInputStream showfile = openFileInput("current_file");
       ByteArrayOutputStream out = new ByteArrayOutputStream();
       byte[] data = new byte[1024];
       int len = 0;
       
       while( (len=showfile.read(data))  != -1){
        out.write(data, 0, len);
       }
       
       String content = new String(out.toByteArray());
       
       showText.setText(content);
       
       Toast.makeText(this, "显示成功", 3000).show();
      } catch (Exception e) {
       Toast.makeText(this, "显示失败", 3000).show();
       e.printStackTrace();
      }
        }
    }


    4.部署测试。

    三、External Storage

    扩展存储,例如常见扩展存储有SD卡,可以将大容量的数据存储在外部存储中。

    因为SD卡是可以由用户自由装载、卸载的,所以在使用SD卡上的文件之前,应该先检测设备是否已经装载成功。

    通过判断Environment.getExternalStorageState()的返回值,可以知道目前SD卡的状态。

    1、访问SD卡上文件

    a.如果使用API级别大于等于8,可以使用getExternalFilesDir(String type),参数要求提供一个子目录名称,若传递null即为根目录,返回指定目录路径的File对象。

    这里手册上建议使用有意义的子目录名称,便于Android媒体扫描器,正确的将文件分类。

    [java] public class Environment { 
        public static String DIRECTORY_MUSIC = "Music"; //音频文件  
        public static String DIRECTORY_PODCASTS = "Podcasts";   //广播  
        public static String DIRECTORY_RINGTONES = "Ringtones"; //铃声  
        public static String DIRECTORY_ALARMS = "Alarms";   //警报  
        public static String DIRECTORY_NOTIFICATIONS = "Notifications"; //通知  
        public static String DIRECTORY_PICTURES = "Pictures";   //图片  
        public static String DIRECTORY_MOVIES = "Movies";   //电影  
        public static String DIRECTORY_DOWNLOADS = "Download";  //下载  
        public static String DIRECTORY_DCIM = "DCIM";   //照片  
        //...不完整的Environment类内容  

    public class Environment {
     public static String DIRECTORY_MUSIC = "Music"; //音频文件
     public static String DIRECTORY_PODCASTS = "Podcasts"; //广播
     public static String DIRECTORY_RINGTONES = "Ringtones"; //铃声
     public static String DIRECTORY_ALARMS = "Alarms"; //警报
     public static String DIRECTORY_NOTIFICATIONS = "Notifications"; //通知
     public static String DIRECTORY_PICTURES = "Pictures"; //图片
     public static String DIRECTORY_MOVIES = "Movies"; //电影
     public static String DIRECTORY_DOWNLOADS = "Download"; //下载
     public static String DIRECTORY_DCIM = "DCIM"; //照片
     //...不完整的Environment类内容
    }


    b.API级别小于等于7,可以使用getExternalStorageDirectory(),将返回文件路径为/Android/data/<package_name>/files/的File对象,这里的<package_name>就是
    AndroidManifest.xml中<manifest>标签中定义package。


    这两种方法创建的文件,在应用被卸载时,文件也随之删除。


    2、如果不希望创建的文件在应用卸载后被删除,可以使用下面的方法

    以共享文件的方式存储,任何应用都将可以访问这些文件。

    a.API大于等于8,getExternalStoragePublicDirectory (String type),参数与getExternalFilesDir(String type)中的参数一样,指定子目录。

    b.API小于等于7,getExternalStorageDirectory(),返回外部存储的根目录的File对象。然后将文件存储在:

    Music/ - 媒体扫描仪划分为用户的音乐在这里发现的所有媒体。
    Podcasts/ - 媒体扫描仪的分类在这里找到一个podcast的所有媒体。
    Ringtones/ - 媒体扫描器分类作为铃声,在这里发现所有的媒体。
    Alarms/ - 媒体扫描仪发出报警声,这里发现的所有媒体分类。
    Notifications/ - 媒体扫描仪的分类作为通知的声音在这里发现的所有媒体。
    Pictures/ - 所有照片(不包括那些用相机拍摄)。
    Movies/ - 所有电影(不包括用摄像机拍摄的)。
    Download/ - 杂项下载。

    四、SQLite存储

    Android提供了对SQLite全面支持,无需考虑数据库连接、连接池等问题。

    只需要集成SQLiteOpenHelper类,它提供了访问数据库、事务等API。

    [java] package mr.jin.service; 
     
    import android.content.Context; 
    import android.database.sqlite.SQLiteDatabase; 
    import android.database.sqlite.SQLiteOpenHelper; 
     
    public class DBOpenHelper extends SQLiteOpenHelper { 
     
        public DBOpenHelper(Context context) { 
            //第一个参数:传递上下文对象  
            //第二个参数:数据库保存的文件名  
            //第三个参数:null使用默认的创建游标对象工厂  
            //第四个参数:最重要,表示数据库版本号,最小值1。每次运行应用前  
            //      会与当前应用的数据库版本做比较,如果大于当前版本号  
            //      将调用onUpgrade方法。  
            super(context, "dbfile.db", null, 1); 
        } 
     
        @Override 
        public void onCreate(SQLiteDatabase db) {//只在第一次运行应用时调用,这里可以运行创建数据库结构的代码  
            db.execSQL("CREATE TABLE person(personid integer primary key autoincrement, name varchar(20))"); 
        } 
     
        @Override 
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//只在数据库版本发生改变时调用  
            db.execSQL("ALTER TABLE person ADD amount integer NULL"); 
        } 
     

    package mr.jin.service;

    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;

    public class DBOpenHelper extends SQLiteOpenHelper {

     public DBOpenHelper(Context context) {
      //第一个参数:传递上下文对象
      //第二个参数:数据库保存的文件名
      //第三个参数:null使用默认的创建游标对象工厂
      //第四个参数:最重要,表示数据库版本号,最小值1。每次运行应用前
      //  会与当前应用的数据库版本做比较,如果大于当前版本号
      //  将调用onUpgrade方法。
      super(context, "dbfile.db", null, 1);
     }

     @Override
     public void onCreate(SQLiteDatabase db) {//只在第一次运行应用时调用,这里可以运行创建数据库结构的代码
      db.execSQL("CREATE TABLE person(personid integer primary key autoincrement, name varchar(20))");
     }

     @Override
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//只在数据库版本发生改变时调用
      db.execSQL("ALTER TABLE person ADD amount integer NULL");
     }

    }
    SQLiteOpenHelper提供了两个API来获得数据库连接对象SQLiteDatabase:


    getWritableDatabase():返回可读、写对象


    getReadableDatabase():返回可读、写对象。仅当无法写时,返回只读对象。


    具体一些操作数据库的方法,可以参看SQLiteDatabase API手册,提供的方法已经足够多了。http://android.toolib.net/reference/android/database/sqlite/SQLiteDatabase.html

  • 相关阅读:
    JZOJ5954.【NOIP2018模拟11.5A组】走向巅峰
    JZOJ5956.【NOIP2018模拟11.7A组】easy LCA
    JZOJ5957.【NOIP2018模拟11.7A组】scarborough fair
    JZOJ5959【NOIP2018模拟11.8A组】铁路运输
    NOIP2018游记
    Pycharm 解释器的快捷键
    计算机编程语言初识
    计算机初识
    Python之如何修改运行的快捷键
    [USACO09NOV]硬币的游戏A Coin Game
  • 原文地址:https://www.cnblogs.com/sode/p/2565683.html
Copyright © 2020-2023  润新知