Android常用数据存储方式有SharedPreferences存储数据(虽然还是属于内部存储)、文件存储(内部,外部)、SQLite数据库存储、ContentProvider存储数据、网络存储数据等几种。本篇博客主要是介绍Shared Preference的原理与使用,区分内部与外部文件存储,以及它们的使用方式。那就从清除缓存与清除数据到底清除了什么这个问题开始吧!

内部存储 InternalStorage

在Android开发中,内存 Memory、内部存储 InternalStorage、外部存储 ExternalStorage这三者有啥区别呢? 在我们打开手机设置 -> 应用管理,随便选择一个软件,然后会看到一个是清除缓存的按钮,一个清除数据的按钮,那么当点击清除缓存的时候清除的是哪里的数据?当点击清除数据的时候又是清除的哪里的数据呢? 打开Device File Explorer会看到如下目录结构:

其实在使用SharedPreferenced的时候,将数据持久化存储于本地,其实就是存在这个文件中的xml文件里,App里边的数据库文件就存储于databases文件夹中,还有我们的普通数据存储在files中,缓存文件存储在cache文件夹中,存储在这里的文件我们都称之为内部存储。

下面来说说使用内部存储的代表——SharedPreferences,SharedPreferences也是在开发中使用的比较多的一种方案,用于存放一些类似登录的配置等信息。

SharedPreferences

1、用于存放一些类似登录的配置信息 2、本质上是一个xml文件,是通过类似键值对的方式存放信息 3、位于程序私有目录中,即data/data/[packageName]/shared_prefs

SharedPreferences的操作模式 1、MODE_APPEND:追加方式存储 2、MODE_PRIVATE:私有方式存储,其他应用无法访问 3、MODE_WORLD_READABLE:可被其他应用读取 4、MODE_WORLD_WRITEABLE:可被其他应用写入

SharedPreferences使用方式:

// 取数据
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);etUserName = findViewById(R.id.et_username);etPassword = findViewById(R.id.et_password);SharedPreferences login_info = getSharedPreferences("login_info", MODE_PRIVATE);// 第一个参数为Key,第二个是默认值etUserName.setText(login_info.getString("user_name", ""));etPassword.setText(login_info.getString("password", ""));
}
​
​
// 存储据
public void userLogin(View view) {String userName = etUserName.getText().toString();String password = etPassword.getText().toString();if(TextUtils.isEmpty(userName) || TextUtils.isEmpty(password)){Toast.makeText(MainActivity.this, "输入不完整", Toast.LENGTH_SHORT).show();}
​// 存储输入的信息// 1、拿到SharedPreference对象SharedPreferences loginInfoSP = getSharedPreferences("login_info", MODE_PRIVATE);// 2、获取Editor对象SharedPreferences.Editor editor = loginInfoSP.edit();// 3、通过Editor存储数据editor.putString("user_name", userName);editor.putString("password", password);// 3、调用提交方法boolean commit = editor.commit();Log.i(TAG, "userLogin: commitRet = " + commit);
​// 校验登录结果if(!("admin".equals(userName) && "123456".equals(password))){Toast.makeText(MainActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();}else {Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();// TODO ...}
}

所以其实不难发现,SharedPreference存取数据非常简单,存数据只需要四步,取数据只要两步。

通过查看设备上的文件也可以发现,SharedPreference本质上就是一个xml文件而已,是通过类似键值对的方式存放信息。

获得内部存储目录

Context.getFileDir(),获取/data/data/包名/files Context.getCacheDir(),获取/data/data/包名/cache,下面通过代码演示一下:

public void saveToFileDir() {File filesDir = MainActivity.this.getFilesDir();File myFileTxt = new File(filesDir, "myFile.txt");try (BufferedWriter writer = new BufferedWriter(new FileWriter(myFileTxt))){writer.write("这是内部存储文件目录的文件内容!");} catch (IOException e) {e.printStackTrace();}
}
​
public void saveToCacheDir() {File cacheDir = MainActivity.this.getCacheDir();File myCacheTxt = new File(cacheDir, "myCache.txt");try (BufferedWriter writer = new BufferedWriter(new FileWriter(myCacheTxt))){writer.write("这是内部存储缓存文件内容!");} catch (IOException e) {e.printStackTrace();}
}

外部存储ExternalStorage

ExternalStorage是我们平时操作最多的,外部存储一般就是我们上面看到的storage或者mnt文件夹,不同厂家有可能不一样,请见下图:

一般来说,在storage文件夹中有一个sdcard文件夹,这个文件夹中的文件又分为两类,一类是公有目录,还有一类是私有目录,其中的公有目录有九大类,比如DCIM、DOWNLOAD等这种系统为我们创建的文件夹,私有目录就是Android这个文件夹,这个文件夹打开之后里边有一个data文件夹,打开这个data文件夹,里面有许多应用包名组成的文件夹,那些就是对应的应用程序的私有外部存储区域(Android/data/应用包名)。比如浏览器的私有外部存储空间:

下面是一个存储与读取的例子:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="20dp"android:orientation="vertical"tools:context=".MainActivity">
​<EditTextandroid:id="@+id/et_content"android:layout_width="match_parent"android:layout_height="wrap_content"android:minLines="10" />
​<Buttonandroid:id="@+id/btn_save"android:onClick="save"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="保存" />
​<Buttonandroid:onClick="read"android:id="@+id/btn_read"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="读取" />
​<TextViewandroid:id="@+id/tv_show"tools:text="Content Text!"android:layout_width="match_parent"android:layout_height="wrap_content"/>
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private EditText etContent;private TextView tvShow;
​// 申请权限请求码private static final int REQUEST_EXTERNAL_STORAGE = 1001;
​// 检查权限,这种写法主要是针对比较新的Android6.0及以后的版本public static void verifyStoragePermissions(Activity activity) {int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
​if (writePermission != PackageManager.PERMISSION_GRANTED|| readPermission != PackageManager.PERMISSION_GRANTED) {// 如果没有权限需要动态地去申请权限ActivityCompat.requestPermissions(activity,// 权限数组new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},// 权限请求码REQUEST_EXTERNAL_STORAGE);}}// 如果在申请权限的过程中需要做一些对应的处理,则在此方法中处理@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if(REQUEST_EXTERNAL_STORAGE == requestCode){// TODO ...}}
​@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获得外部存储的目录File externalStorageDirectory = Environment.getExternalStorageDirectory();Log.i(TAG, "onCreate: externalStorageDirectory = " + externalStorageDirectory.getAbsolutePath());etContent = findViewById(R.id.et_content);tvShow = findViewById(R.id.tv_show);verifyStoragePermissions(this);}
​public void save(View view) {String content = etContent.getText().toString();if(TextUtils.isEmpty(content)) {Toast.makeText(MainActivity.this, "输入为空", Toast.LENGTH_SHORT).show();return;}
​// 判断外部存储的状态if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){// 外部存储已挂载String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();String descPath = absolutePath + "/input_content.txt";File descFile = new File(descPath);Log.i(TAG, "save: descFile = " + descFile.getAbsolutePath());try {BufferedWriter writer = new BufferedWriter(new FileWriter(descFile, true));writer.write(content);writer.close();Toast.makeText(MainActivity.this, "写入成功", Toast.LENGTH_SHORT).show();} catch (IOException e) {e.printStackTrace();}}else{Toast.makeText(MainActivity.this, "存储设备未挂载", Toast.LENGTH_SHORT).show();}}
​public void read(View view) {String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();String descPath = absolutePath + "/input_content.txt";try {BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(descPath)));String line;StringBuilder builder = new StringBuilder();while((line = bufferedReader.readLine()) != null){builder.append(line).append("n");}tvShow.setText(builder.toString());} catch (IOException e) {e.printStackTrace();}}
}

manifest文件中别忘记声明权限:

<!-- 在SDCard中创建与删除文件的权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

获得外部存储目录

通过Environment.getExternalStorageDirectory(),我们很容易获得外部存储的根目录,通过拼接,很容易拿到DOWNLOAD、DCIM、MUSIC、MOVIES、LOST.DIR等公有目录,如何拿到外部存储的私有目录呢?

Context.getExternalFilesDir(String type),通常用于需要长时间保存的数据,获取到SDCard/Android/data/包名/files/目录。

Context.getExternalCacheDir(),通常用于需要临时保存的数据,获取到SDCard/Android/data/包名/cache/目录。下面演示一下向私有空间和缓存空间分别存入一个文件:

// 存储一个字符串到私有外部存储空间 Downloads
public void saveToPrivate(View view) {File externalPrivateDir = MainActivity.this.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);File myDownloadTxt = new File(externalPrivateDir, "myDownload.txt");try {BufferedWriter writer = new BufferedWriter(new FileWriter(myDownloadTxt));writer.write("这是下载目录的文件内容!");writer.close();} catch (IOException e) {e.printStackTrace();}
​
}
​
// 存储一个字符串到私有外部存储空间 cache
public void saveToCache(View view) {File externalPrivateDir = MainActivity.this.getExternalCacheDir();File myCacheTxt = new File(externalPrivateDir, "myCache.txt");try {BufferedWriter writer = new BufferedWriter(new FileWriter(myCacheTxt));writer.write("这是缓存文件内容!");writer.close();} catch (IOException e) {e.printStackTrace();}
}

所以总结一下就是:要获取外部存储就公用空间就用Environment,获取外部存储私有空间就用Context对象。

清除缓存与清除数据

清除缓存

反射调用接口:PackageManager.deleteApplicationCacheFiles

它会清除以下项目:

1、清除data/data/应用包名/cache/下的所有文件

2、清除data/data/应用包名/code_cache/下的所有文件

3、清除mnt/sdcard/Android/data/应用包名/下的cache文件夹

清除数据

反射调用接口:ActivityManager.clearApplicationUserData

它会清除以下项目:

1、清除data/data/应用包名/下的所有文件和文件夹

2、清除mnt/sdcard/Android/data/应用包名

3、清除mnt/sdcard/Android/media/应用包名

4、清除应用包名对应的App所有运行时权限的授权

总结一下内部存储与外部存储

android studio 读取内存txt文件_SharedPreference与文件存储相关推荐

  1. 生成jni的android.mk,Android Studio 3.5版本JNI生成SO文件详解

    学习在于记录,把自己不懂得容易忘记得记录下,才是最好得选择. 废话不多说,想要在Android开发中嵌入c/c++代码,直接开始如下步骤 1.创建需要调用的Java类 在你某个指定的包下创建如下类pa ...

  2. Android Studio(九):引用jar及so文件

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  3. 解决Android Studio读取不了SD卡上的文件

    问题: 上课要求练习操作SD卡上的文件,界面如图所示,要求点击保存按钮会出现success的toast,并可以读取文件内容.但是我一直出现的都是failure,原因是不能执行这句代码:Environm ...

  4. Android Studio MAT内存分析初探

    点击打开链接 做开发有一些年头的想必都会碰到程序性能方面的问题,性能优化有很多种,但是首先我们得定位是哪一块的问题:好在前方有巨人可以让我们站,Android Studio已经为我们提供了性能分析工具 ...

  5. Android Studio检测内存泄露和性能

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 首先需要明白一个概念, 内存泄露就是指,本应该回收的内存,还驻留在内存中.  一般情况下,高密度 ...

  6. android studio占内存大小,极大精简android studio在C盘的内存

    在C盘占很大的内存大约就2种原因: 1.SDK占内存太大 2.AVD模拟器占内存太大 第一种情况,移动SDK(用android studio不需要配置环境变量) 先移动C盘的Android目录,里面是 ...

  7. 使用Android Studio 查看内存泄漏

    用新版的AS 的profiler 查看内存泄漏 记录一下使用Android Studio 的profiler 查看内存泄漏的过程.新版的AS 的profiler 功`能强大.我们可以很方便的查看到一个 ...

  8. Android起始内存大,调整Android Studio分配内存大小

    如果Androidstudio运行起来非常卡顿.缓慢,很可能是因为初始分配的内存不够导致卡顿. 查看当前分配的Heap 总大小以及使用状况可以在studio中设置展示.具体位置Settings -&g ...

  9. Mac中Android Studio使用内存调整方法

    Mac下调整Android Studio可使用内存大小 前言 当使用 MAC 安装完 AS 后,系统会给AS的内存值分配一个默认值,这个默认值是一个通用的,不可能去适配到每台机器. 默认的值在/App ...

最新文章

  1. Android 编译源码 注意事项
  2. visio 2010下载
  3. Intel DPDK包部署试验
  4. Eclipse 代码提示功能设置
  5. mysql基础(DQL语言、DML语言、DDL语言)详解
  6. 三种会计科目表:运营会计科目表、国家会计科目表、集团会计科目表
  7. kafka集群编程指南
  8. 硬盘结构,主引导记录MBR,硬盘分区表DPT,主分区、扩展分区和逻辑分区,电脑启动过程...
  9. IBM发布32纳米芯片技术 明年下半年量产
  10. 简述对linux系统的认识,对Linux的认识
  11. 计算机毕业设计中民宿平台信息管理系统设计
  12. arch linux 看图软件,菠萝看图
  13. CTF Crypto 入门练习
  14. android studio 截图方法,Android studio 2.0 的安装的全程截图,手把手教学,亲自实践。...
  15. 带有Powershell的XSLT
  16. 指数基金日涨跌幅python_用Python验证指数基金定投策略
  17. 在数据可视化这条路上,除了天天做图表,还有更重要的3件事
  18. 1553B 协议详解
  19. GoDaddy域名过户PUSH攻略
  20. 《计算机网络技术》第一章测试(题目及答案)

热门文章

  1. 基于mybatis声明SQL Session对象
  2. ATS插件channel_stats源码分析解读
  3. Rocksdb 写入数据后 GetApproximateSizes 获取的大小竟然为0?
  4. 字符串匹配算法 -- BM(Boyer-Moore) 和 KMP(Knuth-Morris-Pratt)详细设计及实现
  5. leetcode-452 用最少数量的箭引爆气球
  6. awk3.0 — awk变量
  7. scala构建工具sbt使用介绍
  8. Qt 学习之路:模型-视图高级技术
  9. 白话spring依赖注入
  10. SQL时间相关 - SQL日期,时间比较