欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android數(shù)據(jù)存儲幾種方式講解

 更新時間:2022年12月26日 09:27:56   作者:落雪小軒韓  
在開發(fā)過程中,數(shù)據(jù)存取是較為頻繁的,今天我們來了解下android幾種常見的數(shù)據(jù)存取方式。在Android中,sharePreferences是一種輕量級的數(shù)據(jù)存儲方式,采用鍵值對的存儲方式,存儲少量數(shù)據(jù),支持基本類型的簡單數(shù)據(jù)存儲

一、文件存儲

特點:openFileInput()和openFileOutput()讀取設備上的文件。

優(yōu)點:適用于存儲大量的數(shù)據(jù),可以存儲圖片、視頻、文本等數(shù)據(jù)。

缺點:如果采用內(nèi)部存儲的方式,存儲過量的數(shù)據(jù)可能會導致內(nèi)存的不足;如果采用外部sdcard存儲的方式,刪除或者卸載應用,相關的數(shù)據(jù)需要手動進行刪除,比較麻煩。

默認位置:/data/data/<包>/files/.。

(一)內(nèi)部存儲

// 將數(shù)據(jù)存儲到指定的文件中
// name為文件名,mode為文件的操作模式
FileOutputStream fos = openFileOutput(String name,int mode);
// 讀取指定文件中的數(shù)據(jù)
FileInputStream  fis = openFileInput(String name);

mode的取值如下:

MODE_PRIVATE:該文件只能被當前程序讀寫 ;

MODE_APPEND:該文件的內(nèi)容可以追加;

MODE_WORLD_READABLE:該文件的內(nèi)容可以被其他程序讀;

MODE_WORLD_WRITEABLE:該文件的內(nèi)容可以被其他程序?qū)?/p>

注意:Android系統(tǒng)有一套自己的安全模型,默認情況下任何應用創(chuàng)建的文件都是私有的,其他程序無法訪問。

1.寫入文件步驟

String fileName = “data.txt”; // 文件名稱

String content = “helloworld”; // 保存數(shù)據(jù)

FileOutputStream fos = openFileOutput(fileName, MODE_PRIVATE);

fos.write(content.getBytes()); //將數(shù)據(jù)寫入文件中

fos.close(); //關閉輸出流

2.讀取文件步驟

String content = “”;

FileInputStream fis = null;

fis = openFileInput(“data.txt”); //獲得文件輸入流對象

byte[] buffer = new byte[fis.available()]; // 創(chuàng)建緩沖區(qū),并獲取文件長度

fis.read(buffer); // 將文件內(nèi)容讀取到buffer緩沖區(qū)

content = new String(buffer);//轉(zhuǎn)換成字符串

fis.close(); //關閉輸入流

3.實現(xiàn)存儲和讀取用戶名和密碼實例

創(chuàng)建UserInfoIO工具類,實現(xiàn)存儲數(shù)據(jù)方法(saveUserInfo)和讀取數(shù)據(jù)方法(getUserInfo)

public class UserInfoIO {
	// 數(shù)據(jù)的寫入
	public static boolean saveUserInfo(String username, String password, Context context){
	    // openFileOutput(要操作的文件名,文件訪問模式)
	    FileOutputStream fos = null;
	    String msg = null;
	    try { // 在操作文件的時候可能會報異常,需要進行捕獲
	        fos = context.openFileOutput("MyData.txt",Context.MODE_PRIVATE);
	        msg = username + ":" + password;
	        // getBytes()將字符串轉(zhuǎn)換為字節(jié)流
	        fos.write(msg.getBytes());
	        return true;
	    } catch (IOException e) {
	        e.printStackTrace();
	        return false;
	    }
	    finally {
	        try {
	            fos.close(); // 流是系統(tǒng)中的稀缺資源,在使用完后要及時關閉
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	}
}
// 用戶數(shù)據(jù)的讀取
public static Map<String,String> getUserInfo(Context context){
    // 獲取文件輸入流
    FileInputStream fis = null;
    try {
        fis = context.openFileInput("MyData.txt");
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        // 字節(jié)轉(zhuǎn)換為字符串
        String msg = new String(buffer);
        String[] userInfo = msg.split(":");
        Map<String,String> userMap = new HashMap<>();
        userMap.put("username",userInfo[0]);
        userMap.put("password",userInfo[1]);
        return userMap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    finally {
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
}

二、SharedPreferences存儲

特點:以XML格式將數(shù)據(jù)存儲到設備。

優(yōu)點:簡單、方便、輕量級、易理解。

缺點:適用于存儲少量的數(shù)據(jù),并且數(shù)據(jù)的格式只能是基本的數(shù)據(jù)類型(int、float、long、boolean)、字符串類型(string),無法進行條件查詢等操作。

SharedPreferences是一個輕量級的存儲類,特別適合用于保存軟件配置參數(shù),其背后是用xml文件存放數(shù)據(jù),文件存放在/data/data//shared_prefs目錄下。

1.寫入文件步驟

SharedPreferences對象本身只能獲取數(shù)據(jù)而不支持存儲和修改,存儲修改是通過Editor對象實現(xiàn)。

SharedPreferences sp = getSharedPreferences(“data”,MODE_PRIVATE);//獲取

SharedPreferences對象

SharedPreferences.Editor editor = sp.edit(); // 獲取編輯器對象

editor.putString(“name”, “張三”); // 存入String類型數(shù)據(jù)

editor.putInt(“age”, 8); // 存入int類型數(shù)據(jù)

editor.commit(); // 提交數(shù)據(jù)

2.讀取文件步驟

SharedPreferences sp = getSharedPreferences(“data”,MODE_PRIVATE);

String data= sp.getString(“name”,“”);

3.刪除文件中數(shù)據(jù)

editor.remove(“name”); // 根據(jù)key刪除數(shù)據(jù)

editor.clear(); // 刪除所有數(shù)據(jù)

4. 實現(xiàn)存儲和讀取用戶名和密碼實例

創(chuàng)建UserInfoSharePre工具類,實現(xiàn)存儲數(shù)據(jù)方法(saveUserInfo)和讀取數(shù)據(jù)方法(getUserInfo)

public class UserInfoSharedPre {
    // 用戶數(shù)據(jù)的存儲
    public static boolean saveUserInfo(String username, String password, Context context) {
        // 獲取SharedPreferences對象,同時指定文件名稱和訪問權限
        SharedPreferences sp = context.getSharedPreferences("MyData", Context.MODE_PRIVATE);
        // 獲取獲取SharedPreferences的編輯器對象
        SharedPreferences.Editor edit = sp.edit();
        // 通過編輯器進行數(shù)據(jù)的存儲
        edit.putString("Uname",username);
        edit.putString("Pwd",password);
        edit.commit();
        return true;
    }
   // 讀取用戶數(shù)據(jù)
   public static Map<String,String> getUserInfo(Context context) {
       // 獲取SharedPreferences對象,同時指定文件名稱和訪問權限
       SharedPreferences sp = context.getSharedPreferences("MyData", Context.MODE_PRIVATE);
       String username = sp.getString("Uname", "");
       String password = sp.getString("Pwd","");
       Map<String,String> userMap = new HashMap<>();
       userMap.put("username",username);
       userMap.put("password",password);
       return userMap;
   }
}

三、SQLite數(shù)據(jù)庫存儲

特點:運算速度快,占用資源少,還支持基本SQL語法。

優(yōu)點:適合存儲結(jié)構化數(shù)據(jù)、輕量級、安全性、隔離性、獨立性。

缺點:并發(fā)的讀寫性能不好。

1. 創(chuàng)建數(shù)據(jù)庫步驟

(一)定義數(shù)據(jù)庫幫助類

SQLiteOpenHelper是SQLiteDatabase的一個幫助類,用來管理數(shù)據(jù)庫的創(chuàng)建和版本的更新

class MyDbHelper extends SQLiteOpenHelper {
    // 構造器的作用:(參數(shù):上下文,數(shù)據(jù)庫文件的名稱,結(jié)果集工廠,版本號)定義數(shù)據(jù)庫
    public MyDbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }
    // 數(shù)據(jù)庫初始化時創(chuàng)建的表,用于創(chuàng)建表或視圖文件
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL("create table user(user_id integer primary key autoincrement,userName varchar(10),password varchar(10))");
    }
    // 升級方法(當數(shù)據(jù)庫的版本號增加時調(diào)用)
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }
}

(二)創(chuàng)建數(shù)據(jù)庫和表

// 設置數(shù)據(jù)庫的相關參數(shù),初始化數(shù)據(jù)庫
MyDbHelper myDbHelper = new MyDbHelper(SQLiteActivity.this,"MyDatabase.db",null,1);
// 通過幫助類獲取到數(shù)據(jù)庫對象
SQLiteDatabase db = myDbHelper.getWritableDatabase();

通過數(shù)據(jù)庫對象可以執(zhí)行如下方法:

1.插入方法insert

// 創(chuàng)建ContentValues對象用于存儲記錄的字段值(鍵值對方式:鍵對應字段名,值對應字段具體的值)
ContentValues contentValues = new ContentValues();
contentValues.put("userName","張三");
contentValues.put("password","123456");
db.insert("user",null,contentValues);

上面等同于

db.execSQL("insert into user(userName,password) values (?,?)",new Object[]{<!--{C}%3C!%2D%2D%20%2D%2D%3E-->"張三","123456"});

執(zhí)行完之后

db.close();

2.查詢方法query

調(diào)用query方法查詢數(shù)據(jù)庫中的數(shù)據(jù),返回一個行數(shù)集合cursor

public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

各參數(shù)說明:

各參數(shù)說明:
table:表名稱
colums:列名稱數(shù)組,返回那些字段,null表示所有字段
selection:查詢條件子句,相當于select語句where關鍵字后面的部分,在條件子句允許使用占位符“?” selectionArgs:對應于selection語句中占位符的值,值在數(shù)組中的位置與占位符在語句中的位置必須一致, 否則就會有異常。
groupBy:相當于select語句group by關鍵字后面的部分
having:相當于select語句having關鍵字后面的部分
orderBy:排序類
limit:分頁查詢的限制,指定偏移量和獲取的記錄數(shù)
Cursor:返回值,相當于結(jié)果集ResultSet

// Cursor: 結(jié)果集,內(nèi)有游標指向結(jié)果集中的某一條記錄,初始時指向第一條
Cursor cursor = db.query("user", new String[]{"userName,password"}, null, null, null, null, null, null);
cursor.moveToFirst();
while (cursor.moveToNext()) { // 移動游標指向下一行數(shù)據(jù)
	showInfo.append("\n" + "用戶名" + cursor.getString(0) + ",密碼" + 	cursor.getString(1));
}
cursor.close();
db.close();

對于cursor也提供了一些方法如下:

3.刪除方法delete

返回刪除的記錄條數(shù)

public boolean deleteData(String deleteId) {
	int i = db.delete("user", "id=?", new String[]{deleteId});
	return i > 0 ? true : false;
}

4.修改方法update

返回更新的記錄條數(shù)

ContentValues contentValues = new ContentValues();
contentValues.put("userName","李四");
contentValues.put("password","123123");
int i = db.update("user", contentValues, "id=?", new String[]{updateId});

等同于

db.execSQL("update user set userName=?,password=? where id=?",new Object[]{<!--{C}%3C!%2D%2D%20%2D%2D%3E-->username1,password1,id});

四、ContentProvider存儲

特點:ContentProvider主要用于不同應用程序之間共享數(shù)據(jù),ContentProvider更好的提供了數(shù)據(jù)共享接口的統(tǒng)一性,使不同應用共享數(shù)據(jù)更規(guī)范和安全。

優(yōu)點:能夠?qū)崿F(xiàn)所有應用程序共享的一種數(shù)據(jù)存儲方式,可以存儲音頻,視頻,圖片和通訊錄等。

缺點:不能單獨使用,必須與其他存儲方式結(jié)合使用。

內(nèi)容提供者(ContentProvider)是Android系統(tǒng)四大組件之一,它是不同應用程序之間進行數(shù)據(jù)共享的標準API,通過ContentResolver類可以訪問ContentProvider中共享的數(shù)據(jù)。

ContentProvider的工作原理如下:

常見的使用場景:QQ和微信中文件的相互轉(zhuǎn)發(fā);安裝完某個app第一次啟動的時候獲取權限(聯(lián)系人、拍照、位置等)

ContentProvider 使用基于數(shù)據(jù)庫模型的簡單表格來提供需要共享的數(shù)據(jù),在該表格中,每一行表示一條記錄,而每一列代表特定類型和含義的數(shù)據(jù),并且其中每一條數(shù)據(jù)記錄都包含一個名為“_ID”的字段類標識每條數(shù)據(jù),可以根據(jù)同一個ID查詢幾個相關表中的信息。知道各個字段對應的數(shù)據(jù)類型后,可根據(jù)Cursor對象提供的相關的方法,如,getInt()、getString()、getLong()等查詢字段對應的值。

簡單理解:A程序共享數(shù)據(jù)實際上就是共享一張表,B程序要去獲取數(shù)據(jù)實際上就是要去對表執(zhí)行查詢操作。

問題:B程序如何精確地找到A程序所共享出來的表?

ContentResolver提供一系列增刪改查的方法對數(shù)據(jù)進行操作,并且這些方法以Uri的形式對外提供數(shù)據(jù)。

Uri為內(nèi)容提供者中的數(shù)據(jù)建立了唯一標識符。它主要由三部分組成,scheme、authorities(主機名/域名)和path。

擴展:uri與url功能類似,通過uri可以指向安卓系統(tǒng)中唯一的某個資源。也就是說通過它可以指向共享出來的唯一的某個表文件

如下:

scheme部分,“content://”是一個標準的前綴。

authority(主機名/域名)部分,是在創(chuàng)建內(nèi)容提供者時指定的authorities屬性值,通常采用程序包名的方式命名。

path部分,“/person”代表資源(或者數(shù)據(jù)),可以動態(tài)改變。

UriMatcher類:用于對ContentProvider中的Uri進行匹配

1、初始化UriMatcher

 UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
 // 常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼(-1)

2、將Uri注冊到UriMatcher中

matcher.addURI("cn.itcast.contentprovider", "people", 1);  
// 添加需要匹配uri,如果匹配就會返回匹配碼"1"
matcher.addURI("cn.itcast.contentprovider", "person/#", 2);
// #表示通配符,任意內(nèi)容的意思

1.創(chuàng)建數(shù)據(jù)庫與表提供數(shù)據(jù)

public class MyDBhelper extends SQLiteOpenHelper {
    public MyDBhelper(Context context) {
        super(context, "person.db", null, 1);
    }
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL("create table user(id integer primary key autoincrement,userName varchar(10),phone varchar(10))");
    }
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }
}

2.創(chuàng)建內(nèi)容提供者繼承ContentProvider父類

在程序包名處右擊選擇【New】—>【Other】—>【Content Provider】選項

輸入內(nèi)容提供者的Class Name(類名稱)和URI Authorities(唯一標識,通常使用包名)

內(nèi)容提供者創(chuàng)建完成后,Android Studio會自動在AndroidManifest.xml中對內(nèi)容提供者進行注冊。

<application ......>
    ......	
    <provider
        android:name=".MyContentProvider"
        android:authorities="cn.com.myapp"
        android:enabled="true"
        android:exported="true" >
   </provider>
</application>

屬性含義如下:

(1)android:name:該屬性是一個類的全名稱

(2)android:authorities:列出一個或者多個由content provider的提供的URI的authorities,多個authorities由分號隔開(自定義)。

(3)android:enabled:該屬性表明了該content provider是否可以被實例化,默認情況下該屬性值是true。

(4)android:exported:該屬性指示了content provider是否可以被其他應用程序使用。

public class MyContentProvider extends ContentProvider {
    private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    private static final int SUCCESS = 1;
    private MyDBhelper myDBhelper;
    // 靜態(tài)代碼塊,MyContentProvider對象沒有創(chuàng)建出來之前就已經(jīng)存在
    static {
        // 加載時為uri適配器添加匹配規(guī)則
        uriMatcher.addURI("cn.com.myapp","user",SUCCESS);
        // 查詢表中的某條記錄
        uriMatcher.addURI("cn.com.myapp","user/#",2);
    }
    public MyContentProvider() {
    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // Implement this to handle requests to delete one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public String getType(Uri uri) {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO: Implement this to handle requests to insert a new row.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public boolean onCreate() {
        // 創(chuàng)建數(shù)據(jù)庫和初始化表的內(nèi)容
        myDBhelper = new MyDBhelper(getContext());
        return false;
    }
    @Override
    // 未來會有另外一個app通過uri來調(diào)用query方法
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO: Implement this to handle query requests from clients.
        // 匹配傳入的uri,如果匹配得上再做相應的查詢
        int match = uriMatcher.match(uri);
        if(match == 1) {
            // 查詢user表中的數(shù)據(jù)并返回
            SQLiteDatabase db = myDBhelper.getWritableDatabase();
            return db.query("user",projection,selection,selectionArgs,null,null,sortOrder);
        } else if(match == 2) {
            // 查詢表中的某條記錄
        } else {
            return null;
        }
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO: Implement this to handle requests to update one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

3.在第一個app的Activity中給數(shù)據(jù)庫添加數(shù)據(jù)

public class firstApplicationActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first_application);
        MyDBhelper myDBhelper = new MyDBhelper(firstApplicationActivity.this);
        SQLiteDatabase db = myDBhelper.getWritableDatabase();
        db.execSQL("insert into user(userName,phone) values ('tom','8888')");
        db.execSQL("insert into user(userName,phone) values ('jeny','18888')");
        db.execSQL("insert into user(userName,phone) values ('jack','38888')");
    }
}

4.創(chuàng)建第二個App作為訪問者

布局文件,通過點擊按鈕獲取第一個app的數(shù)據(jù)用TextView展示出來

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".secondApplicationActivity"
    android:orientation="vertical"
    >
    <TextView
        android:id="@+id/show"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9"/>
    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="獲取共享數(shù)據(jù)"
        />
</LinearLayout>

java文件

public class secondApplicationActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn;
private TextView tv_show;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second_application);
        initViews();
        setListener();
    }
    protected void initViews() {
        btn = findViewById(R.id.btn);
        tv_show = findViewById(R.id.show);
    }
    protected void setListener() {
        btn.setOnClickListener(this);
    }
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn:
                // 創(chuàng)建uri,通過uri來指向共享的數(shù)據(jù)文件
                Uri uri = Uri.parse("content://cn.com.myapp/user");
                // 獲取訪問對象(內(nèi)容解析者)
                ContentResolver contentResolver = getContentResolver();
                Cursor cursor = contentResolver.query(uri, new String[]{"userName", "phone"}, null, null, null);
                while (cursor.moveToNext()) {
                    tv_show.append("用戶名:" + cursor.getString(0) + "----:" + cursor.getString(1) + "\n");
                }
        }
    }
}

最后,兩個app都啟動,點擊第二個app的按鈕拿到了第一個app共享的值

五、網(wǎng)絡存儲

特點:通過網(wǎng)絡上提供的存儲空間來上傳(存儲)或下載(獲取)我們存儲在網(wǎng)絡空間中的數(shù)據(jù)信息

優(yōu)點:無需考慮內(nèi)存的影響。

缺點:受網(wǎng)絡的狀態(tài)的影響、需要耗費流量等成本。

到此這篇關于Android數(shù)據(jù)存儲幾種方式講解的文章就介紹到這了,更多相關Android數(shù)據(jù)存儲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論