一、手机存储结构
注:系统分区上装的系统预装的app。
系统预装app产生的数据在程序分区内。
手机上的数据展示实例:
使用Android DeviceMonitor查看
二、res/raw 、assets/
相同点:res/raw 、assets/编译时都会编译进data/app/base.apk文件
读取Raw资源
private void readFromRaw(Context context){
InputStream inputStream = context.getResources().openRawResource(R.raw.city);
String rawContent = Util.getStringStream(inputStream);
Log.i("RAW",rawContent);
try {
JSONObject citys = new JSONObject(rawContent);
hzCitys = citys.getJSONObject("浙江").getJSONArray("杭州市");
mApater.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
读取assets资源
private void readFromAsset(Context context) {
try {
InputStream inputStream = context.getAssets().open("city/city.json");
String assetContent = Util.getStringStream(inputStream);
Log.i("ASSET",assetContent);
JSONObject citys = new JSONObject(assetContent);
hzCitys = citys.getJSONObject("浙江").getJSONArray("杭州市");
mApater.notifyDataSetChanged();
} catch (IOException e) {
e.printStackTrace();
}catch (JSONException e){
e.printStackTrace();
}
}
不同点:
1、读取raw资源,文件名称不能相同,不允许有子文件夹
2、assert可以有子文件夹,可以有html文件
三、app私有目录空间
(1)私有目录数据读写
private void saveUserPwd(Context context, String userName,String pwd){
try {
FileOutputStream outputStream = context.openFileOutput("myuser",Context.MODE_PRIVATE);
String userPwd = String.format("%s;%s",userName,pwd);
byte[] b = userPwd.getBytes("utf-8");
outputStream.write(b);
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
(2)Context.Mode
MODE_PRIVATE
每次写文件都是从文件头开始写。
MODE_APPEND
每次写文件都是追加形式写入
(3)私有缓存空间读写
private void writeAndReadCacheFile(Context context){
try {
File cacheDir = context.getCacheDir();
File cacheFile = new File(cacheDir.getAbsolutePath()
+"/myinternalcache");
FileOutputStream cacheFileOut = null;
cacheFileOut = new FileOutputStream(cacheFile);
String cacheString = new String("hello internal cache");
cacheFileOut.write(cacheString.getBytes("utf-8"));
cacheFileOut.close();
FileInputStream cacheFileIn = new FileInputStream(cacheFile);
String myCache = Util.getStringStream(cacheFileIn);
Log.i("INTERNALCACHE",myCache);
} catch (IOException e) {
e.printStackTrace();
}
}
私有缓存空间特性:内置存储空间不足会自动清除。需要自行管理缓存生命周期;DiskLruCache。
适合存放业务缓存。
四、公共存储空间
(1)需要申请外部存储写权限
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
(2)公共目录,可能被其他app访问
(3)分类
应用扩展存储
应用扩展存储特性
不会产生垃圾文件
不会被媒体管理器扫描,相对私密
API>19无需外部存储空间写权限
应用扩展存储读写
适合存放非业务Cache,即图片,升级包
公共存储空间文件
File externalStorageDirectory = Environment.getExternalStorageDirectory();
小技巧:
设置成隐藏目录.文件名
文件夹根目录添加.nomedia
异常保护
public class SDStateReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_MEDIA_MOUNTED.equals(action)){
Toast.makeText(context, "SD卡可用", Toast.LENGTH_SHORT).
show();
}
else if(Intent.ACTION_MEDIA_UNMOUNTED.equals(action)
||Intent.ACTION_MEDIA_REMOVED.equals(action)
||Intent.ACTION_MEDIA_SHARED.equals(action)
||Intent.ACTION_MEDIA_BAD_REMOVAL.equals(action)
||Intent.ACTION_MEDIA_EJECT.equals(action)){
Toast.makeText(context, "SD卡不可用", Toast.LENGTH_SHORT).
show();
}
}
}