網站首頁 編程語言 正文
一、文件存儲
特點:openFileInput()和openFileOutput()讀取設備上的文件。
優點:適用于存儲大量的數據,可以存儲圖片、視頻、文本等數據。
缺點:如果采用內部存儲的方式,存儲過量的數據可能會導致內存的不足;如果采用外部sdcard存儲的方式,刪除或者卸載應用,相關的數據需要手動進行刪除,比較麻煩。
默認位置:/data/data/<包>/files/.。
(一)內部存儲
// 將數據存儲到指定的文件中 // name為文件名,mode為文件的操作模式 FileOutputStream fos = openFileOutput(String name,int mode); // 讀取指定文件中的數據 FileInputStream fis = openFileInput(String name);
mode的取值如下:
MODE_PRIVATE:該文件只能被當前程序讀寫 ;
MODE_APPEND:該文件的內容可以追加;
MODE_WORLD_READABLE:該文件的內容可以被其他程序讀;
MODE_WORLD_WRITEABLE:該文件的內容可以被其他程序寫
注意:Android系統有一套自己的安全模型,默認情況下任何應用創建的文件都是私有的,其他程序無法訪問。
1.寫入文件步驟
String fileName = “data.txt”; // 文件名稱
String content = “helloworld”; // 保存數據
FileOutputStream fos = openFileOutput(fileName, MODE_PRIVATE);
fos.write(content.getBytes()); //將數據寫入文件中
fos.close(); //關閉輸出流
2.讀取文件步驟
String content = “”;
FileInputStream fis = null;
fis = openFileInput(“data.txt”); //獲得文件輸入流對象
byte[] buffer = new byte[fis.available()]; // 創建緩沖區,并獲取文件長度
fis.read(buffer); // 將文件內容讀取到buffer緩沖區
content = new String(buffer);//轉換成字符串
fis.close(); //關閉輸入流
3.實現存儲和讀取用戶名和密碼實例
創建UserInfoIO工具類,實現存儲數據方法(saveUserInfo)和讀取數據方法(getUserInfo)
public class UserInfoIO { // 數據的寫入 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()將字符串轉換為字節流 fos.write(msg.getBytes()); return true; } catch (IOException e) { e.printStackTrace(); return false; } finally { try { fos.close(); // 流是系統中的稀缺資源,在使用完后要及時關閉 } catch (IOException e) { e.printStackTrace(); } } } // 用戶數據的讀取 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); // 字節轉換為字符串 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格式將數據存儲到設備。
優點:簡單、方便、輕量級、易理解。
缺點:適用于存儲少量的數據,并且數據的格式只能是基本的數據類型(int、float、long、boolean)、字符串類型(string),無法進行條件查詢等操作。
SharedPreferences是一個輕量級的存儲類,特別適合用于保存軟件配置參數,其背后是用xml文件存放數據,文件存放在/data/data//shared_prefs目錄下。
1.寫入文件步驟
SharedPreferences對象本身只能獲取數據而不支持存儲和修改,存儲修改是通過Editor對象實現。
SharedPreferences sp = getSharedPreferences(“data”,MODE_PRIVATE);//獲取
SharedPreferences對象
SharedPreferences.Editor editor = sp.edit(); // 獲取編輯器對象
editor.putString(“name”, “張三”); // 存入String類型數據
editor.putInt(“age”, 8); // 存入int類型數據
editor.commit(); // 提交數據
2.讀取文件步驟
SharedPreferences sp = getSharedPreferences(“data”,MODE_PRIVATE);
String data= sp.getString(“name”,“”);
3.刪除文件中數據
editor.remove(“name”); // 根據key刪除數據
editor.clear(); // 刪除所有數據
4. 實現存儲和讀取用戶名和密碼實例
創建UserInfoSharePre工具類,實現存儲數據方法(saveUserInfo)和讀取數據方法(getUserInfo)
public class UserInfoSharedPre { // 用戶數據的存儲 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(); // 通過編輯器進行數據的存儲 edit.putString("Uname",username); edit.putString("Pwd",password); edit.commit(); return true; } // 讀取用戶數據 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數據庫存儲
特點:運算速度快,占用資源少,還支持基本SQL語法。
優點:適合存儲結構化數據、輕量級、安全性、隔離性、獨立性。
缺點:并發的讀寫性能不好。
1. 創建數據庫步驟
(一)定義數據庫幫助類
SQLiteOpenHelper是SQLiteDatabase的一個幫助類,用來管理數據庫的創建和版本的更新
class MyDbHelper extends SQLiteOpenHelper { // 構造器的作用:(參數:上下文,數據庫文件的名稱,結果集工廠,版本號)定義數據庫 public MyDbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } // 數據庫初始化時創建的表,用于創建表或視圖文件 @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { sqLiteDatabase.execSQL("create table user(user_id integer primary key autoincrement,userName varchar(10),password varchar(10))"); } // 升級方法(當數據庫的版本號增加時調用) @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { } }
(二)創建數據庫和表
// 設置數據庫的相關參數,初始化數據庫 MyDbHelper myDbHelper = new MyDbHelper(SQLiteActivity.this,"MyDatabase.db",null,1); // 通過幫助類獲取到數據庫對象 SQLiteDatabase db = myDbHelper.getWritableDatabase();
通過數據庫對象可以執行如下方法:
1.插入方法insert
// 創建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"});
執行完之后
db.close();
2.查詢方法query
調用query
方法查詢數據庫中的數據,返回一個行數集合cursor
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
各參數說明:
各參數說明:
table:表名稱
colums:列名稱數組,返回那些字段,null表示所有字段
selection:查詢條件子句,相當于select語句where關鍵字后面的部分,在條件子句允許使用占位符“?” selectionArgs:對應于selection語句中占位符的值,值在數組中的位置與占位符在語句中的位置必須一致, 否則就會有異常。
groupBy:相當于select語句group by關鍵字后面的部分
having:相當于select語句having關鍵字后面的部分
orderBy:排序類
limit:分頁查詢的限制,指定偏移量和獲取的記錄數
Cursor:返回值,相當于結果集ResultSet
// Cursor: 結果集,內有游標指向結果集中的某一條記錄,初始時指向第一條 Cursor cursor = db.query("user", new String[]{"userName,password"}, null, null, null, null, null, null); cursor.moveToFirst(); while (cursor.moveToNext()) { // 移動游標指向下一行數據 showInfo.append("\n" + "用戶名" + cursor.getString(0) + ",密碼" + cursor.getString(1)); } cursor.close(); db.close();
對于cursor
也提供了一些方法如下:
3.刪除方法delete
返回刪除的記錄條數
public boolean deleteData(String deleteId) { int i = db.delete("user", "id=?", new String[]{deleteId}); return i > 0 ? true : false; }
4.修改方法update
返回更新的記錄條數
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主要用于不同應用程序之間共享數據,ContentProvider更好的提供了數據共享接口的統一性,使不同應用共享數據更規范和安全。
優點:能夠實現所有應用程序共享的一種數據存儲方式,可以存儲音頻,視頻,圖片和通訊錄等。
缺點:不能單獨使用,必須與其他存儲方式結合使用。
內容提供者(ContentProvider)是Android系統四大組件之一,它是不同應用程序之間進行數據共享的標準API,通過ContentResolver類可以訪問ContentProvider中共享的數據。
ContentProvider的工作原理如下:
常見的使用場景:QQ和微信中文件的相互轉發;安裝完某個app第一次啟動的時候獲取權限(聯系人、拍照、位置等)
ContentProvider 使用基于數據庫模型的簡單表格來提供需要共享的數據,在該表格中,每一行表示一條記錄,而每一列代表特定類型和含義的數據,并且其中每一條數據記錄都包含一個名為“_ID”的字段類標識每條數據,可以根據同一個ID查詢幾個相關表中的信息。知道各個字段對應的數據類型后,可根據Cursor對象提供的相關的方法,如,getInt()、getString()、getLong()等查詢字段對應的值。
簡單理解:A程序共享數據實際上就是共享一張表,B程序要去獲取數據實際上就是要去對表執行查詢操作。
問題:B程序如何精確地找到A程序所共享出來的表?
ContentResolver提供一系列增刪改查的方法對數據進行操作,并且這些方法以Uri的形式對外提供數據。
Uri為內容提供者中的數據建立了唯一標識符。它主要由三部分組成,scheme、authorities(主機名/域名)和path。
擴展:uri與url功能類似,通過uri可以指向安卓系統中唯一的某個資源。也就是說通過它可以指向共享出來的唯一的某個表文件
如下:
scheme部分,“content://”是一個標準的前綴。
authority(主機名/域名)部分,是在創建內容提供者時指定的authorities屬性值,通常采用程序包名的方式命名。
path部分,“/person”代表資源(或者數據),可以動態改變。
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); // #表示通配符,任意內容的意思
1.創建數據庫與表提供數據
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.創建內容提供者繼承ContentProvider父類
在程序包名處右擊選擇【New】—>【Other】—>【Content Provider】選項
輸入內容提供者的Class Name(類名稱)和URI Authorities(唯一標識,通常使用包名)
內容提供者創建完成后,Android Studio會自動在AndroidManifest.xml中對內容提供者進行注冊。
<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; // 靜態代碼塊,MyContentProvider對象沒有創建出來之前就已經存在 static { // 加載時為uri適配器添加匹配規則 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() { // 創建數據庫和初始化表的內容 myDBhelper = new MyDBhelper(getContext()); return false; } @Override // 未來會有另外一個app通過uri來調用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表中的數據并返回 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中給數據庫添加數據
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.創建第二個App作為訪問者
布局文件,通過點擊按鈕獲取第一個app的數據用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="獲取共享數據" /> </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: // 創建uri,通過uri來指向共享的數據文件 Uri uri = Uri.parse("content://cn.com.myapp/user"); // 獲取訪問對象(內容解析者) 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共享的值
五、網絡存儲
特點:通過網絡上提供的存儲空間來上傳(存儲)或下載(獲取)我們存儲在網絡空間中的數據信息
優點:無需考慮內存的影響。
缺點:受網絡的狀態的影響、需要耗費流量等成本。
原文鏈接:https://blog.csdn.net/m0_46613429/article/details/128038684
相關推薦
- 2022-04-27 bash?shell獲取當前腳本的絕對路徑(pwd/readlink)_linux shell
- 2022-09-26 C++繼承關系下的構造與析構
- 2021-12-25 常用時間處理方法:時間戳和格式化時間之間轉換;時間比大小
- 2022-11-16 一文搞懂阿里云服務器部署Redis并整合Spring?Boot_Redis
- 2022-10-24 UI?開源組件Flutter圖表范圍選擇器使用詳解_Android
- 2023-01-10 Go語言rune與字符串轉換的密切關系解析_Golang
- 2022-05-29 .NET?Core中的HttpClientFactory類用法詳解_實用技巧
- 2022-06-16 Linux中Redis安裝部署的操作步驟_Redis
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支