安卓中SharedPreferences存储和SD卡存储以及三级缓存操作
三级缓存的原理先从内存中找数据没有去SD卡中寻找如果再没有就去网上下载。
SharedPreferences存储
- SharedPreferences存储简称sp存储是一种保存少量与简单数据且只能存储5种原始数据类型: boolean, float, int, long, String
- 一般用于记住密码 保存视频、音频播放记录 用于一切功能的标记
- 存储在data/data应用程序包名/shared_prefs/xxx.xml文件,以键值对形式存储
// An highlighted block
private void write() {
//得到SharedPreferences对象
//参数一 xml文件的名字 参数二 模式 MODE_PRIVATE 指定该SharedPreferences数据只能被本应用程序读写
SharedPreferences preferences = getSharedPreferences("test", MODE_PRIVATE);
//获得编辑对象
SharedPreferences.Editor editor = preferences.edit();
//写数据
editor.putString("ss","隔壁老王");
//提交数据
editor.commit();
读取数据
// 读取数据
private void read() {
//得到SharedPreferences对象
//参数一 xml文件的名字 参数二 模式 MODE_PRIVATE 指定该SharedPreferences数据只能被本应用程序读写
SharedPreferences preferences = getSharedPreferences("test", MODE_PRIVATE);
//直接读取
//参数一 键 参数二 找不到的时候给默认值
String name=preferences.getString("ss",null);
Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
}
SD卡存储
SD卡文件存储在 /storage/emulated/0/或者/mnt/shell/emulated/0
SD卡的操作需要在清单文件添加权限如果需要在网上下载还需要添加网上权限
// 读取根目录文件下的图片并且给控件设置
public void du(){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file = Environment.getExternalStorageDirectory();
try {
FileInputStream fis=new FileInputStream(new File(file,"炸鸡.png"));
img.setImageBitmap(BitmapFactory.decodeStream(fis));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
// 从网上下载图片写入sd卡
public void xie(){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file = Environment.getExternalStorageDirectory();
FileOutputStream fos=null;
byte[] getbyte = new HttpBytes("http://www.dv37.com/upload/editor/201804/1524894535_871992.jpg").getbyte();
try {
fos=new FileOutputStream(new File(file,"炸鸡.png"));
fos.write(getbyte,0,getbyte.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// Http网上下载
public class HttpBytes {
String str;
byte[] b;
public HttpBytes(String str) {
this.str = str;
}
public byte[] getbyte(){
try {
URL url=new URL(str);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
if(urlConnection.getResponseCode()==200){
InputStream inputStream = urlConnection.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes=new byte[1024];
int len=0;
while((len=inputStream.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
b=byteArrayOutputStream.toByteArray();
}
return b;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
三级缓存
展示效果
案例分析: 利用三级缓存原理首先从内存中寻找这张图片如果内存中没有这张图片则从SD卡中寻找如果SD卡里面也没有则从网上下载
//布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="账号"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/zh"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="密码"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/mm"
android:password="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住密码"
/>
<Button
android:id="@+id/buttondenglu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="登录"
/>
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".Main2Activity">
<Button
android:id="@+id/button"
android:text="点击我弹出图片"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/img"
android:layout_below="@id/button"
/>
</RelativeLayout>
主页面进行记住密码的操作
public class MainActivity extends AppCompatActivity {
SharedPreferences pwd;
Button button;
CheckBox checkBox;
EditText editTextz;
EditText editTextm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextz=findViewById(R.id.zh);
editTextm=findViewById(R.id.mm);
checkBox=findViewById(R.id.checkbox);
button=findViewById(R.id.buttondenglu);
pwd = getSharedPreferences("pwd", MODE_PRIVATE);
boolean shifou = pwd.getBoolean("shifou", false);
if (shifou==true){
String name = pwd.getString("zh", "admin");
String string = pwd.getString("mm", "123456");
editTextm.setText(string);
editTextz.setText(name);
checkBox.setChecked(true);
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String zh = editTextz.getText().toString().trim();
String mm = editTextm.getText().toString().trim();
if(checkBox.isChecked()){
SharedPreferences.Editor edit = pwd.edit();
edit.putBoolean("shifou",true);
edit.putString("zh",zh);
edit.putString("mm",mm);
edit.commit();
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
}else{
SharedPreferences.Editor edit = pwd.edit();
edit.putBoolean("shifou",false);
edit.commit();
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
}
}
});
}
点击按钮进行页面跳转
public class Main2Activity extends AppCompatActivity {
String pic = "http://www.dv37.com/upload/editor/201804/1524894535_871992.jpg";
Button button;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
button = findViewById(R.id.button);
imageView = findViewById(R.id.img);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getpic();
}
});
}
public void getpic() {
Cache cache = new Cache();
Bitmap ji = cache.getbitmap("炸鸡");
if (ji != null) {
imageView.setImageBitmap(ji);
} else {
Sdcard instance = Sdcard.getInstance();
File read = instance.read();
if (read != null) {
imageView.setImageBitmap(BitmapFactory.decodeFile(read.getAbsolutePath()));
cache.save("炸鸡",BitmapFactory.decodeFile(read.getAbsolutePath()));
}else{
try {
byte[] bytes = new MyAsyncTask().execute(pic).get();
if(bytes.length>0){
cache.save("炸鸡",BitmapFactory.decodeByteArray(bytes,0,bytes.length));
instance.write(bytes);
imageView.setImageBitmap(BitmapFactory.decodeByteArray(bytes,0,bytes.length));
}
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
以下是封装的工具类
内存查找是否有图片
public class Cache {
LruCache<String, Bitmap> cache;
public Cache(){
long l = Runtime.getRuntime().maxMemory();
cache=new LruCache<String,Bitmap>((int) (l/8)){
@Override
protected int sizeOf(String key, Bitmap value) {
return super.sizeOf(key, value);
}
};
}
public void save(String k,Bitmap v){
if(cache.get(k)==null){
cache.put(k,v);
}
}
public Bitmap getbitmap(String k){
Log.i("######", "getbitmap: 有图片");
return cache.get(k);
}
}
查找SD卡里是否有这张图片
public class Sdcard {
private static Sdcard sdcard=new Sdcard();
private Sdcard(){
}
public static Sdcard getInstance(){
return sdcard;
}
public File read(){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File externalStorageDirectory = Environment.getExternalStorageDirectory();
File file=new File(externalStorageDirectory,"炸鸡.png");
if(file.exists()){
return file;
}
}
return null;
}
public void write(byte[] b){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File externalStorageDirectory = Environment.getExternalStorageDirectory();
File file=new File(externalStorageDirectory,"炸鸡.png");
try {
file.createNewFile();
FileOutputStream fos=new FileOutputStream(file);
fos.write(b);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
异步任务下载图片
public class MyAsyncTask extends AsyncTask<String,String,byte[]> {
@Override
protected byte[] doInBackground(String[] objects) {
return new HttpBytes(objects[0]).getbyte();
}
}
网络下载工具类
public class HttpBytes {
String str;
byte[] b;
public HttpBytes(String str) {
this.str = str;
}
public byte[] getbyte(){
try {
URL url=new URL(str);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
if(urlConnection.getResponseCode()==200){
InputStream inputStream = urlConnection.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes=new byte[1024];
int len=0;
while((len=inputStream.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
b=byteArrayOutputStream.toByteArray();
}
return b;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}