1. 程式人生 > >第6天Bitmap三級快取

第6天Bitmap三級快取

第6天Bitmap三級快取

Bitmap三級快取

一.為什麼Bitmap三級快取?

  1. 沒有快取的弊端 :費流量, 載入速度慢
  2. 加入快取的優點: 省流量,支援離線瀏覽

二.原理

在這裡插入圖片描述

思路:

  1. 從記憶體獲取圖片, 如果存在, 則顯示; 如果不存在, 則從SD卡中獲取圖片
  2. 從SD卡中獲取圖片, 如果檔案中存在, 顯示, 並且新增到記憶體中; 否則開啟網路下載圖片
  3. 從網路下載圖片, 如果下載成功, 則新增到快取中, 存入SD卡, 顯示圖片

三.程式碼

(1)新增讀寫SD卡的許可權和網路許可權

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
 <uses-permission android:name="android.permission.INTERNET"
></uses-permission>

(2)操作記憶體工具類:提供從記憶體中讀寫的方法,記憶體不能持久儲存,可能過一會就會被回收掉

 //Lrucache儲存工具類
public class LruUtils {
    //TODO 1:例項化LruCache物件
    private LruCache<String,Bitmap> lruCache;
    private long max=Runtime.getRuntime().maxMemory();//獲得手機的最大記憶體
    public LruUtils(){
        lruCache=
new LruCache<String,Bitmap>((int)max/8){//給記憶體大小,一般是最大記憶體的1/8 //重寫該方法返回每個物件的大小 @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } }; } //TODO 2:讀圖片 public Bitmap getBitmap(String key){ return lruCache.get(key); } //TODO 3:存圖片 public void setBitmap(String key,Bitmap bitmap){ lruCache.put(key,bitmap); } }

(3)操作SD卡工具類:提供從SD卡中讀寫的方法

 //TODO 讀圖片和寫圖片
public class SDUtils {
    //TODO 1:存圖片:bitmap.compress()
    public static void setBitmap(String name,Bitmap bitmap){
        //獲取路徑儲存圖片
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            File file=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            File file1=new File(file,name);
            //儲存圖片:bitmap物件---->SD卡
            try {
                //引數一 圖片的格式 引數二 圖片質量 0-100  引數三:輸出流
                bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file1));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    //TODO 2:讀圖片:BitmapFactory.decodeFile()
    public static Bitmap getBitmap(String name){
        //獲取路徑儲存圖片
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            File file=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            File file1=new File(file,name);
            //讀取圖片:SD卡-----Bitmap
            return BitmapFactory.decodeFile(file1.getAbsolutePath());

        }
        return null;
    }
}

(3)網路下載工具類:提供下載圖片的方法

 //網路獲取工具類
public class NetUtils {
    //TODO 獲取網路圖片
    public static Bitmap getBitmap(String url) throws ExecutionException, InterruptedException {
         return new MyTask().execute(url).get();//get方法獲取執行完畢返回的結果Bitmap物件
    }

    static class MyTask extends AsyncTask<String,String,Bitmap>{
        @Override
        protected Bitmap doInBackground(String... strings) {
            String imageUrl = strings[0];
            HttpURLConnection conn = null;
            try {
                URL url = new URL(imageUrl);
                conn = (HttpURLConnection) url.openConnection(); // 開啟連線
                conn.setReadTimeout(5000); // 設定讀取超時時間
                conn.setConnectTimeout(5000); // 設定連線超時時間
                conn.setRequestMethod("GET"); // 設定請求方式
                if (conn.getResponseCode() == 200) {
                    InputStream is = conn.getInputStream(); // 獲取流資料
                    Bitmap bitmap = BitmapFactory.decodeStream(is); // 將流資料轉成Bitmap物件
                    return bitmap;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (conn != null) {
                    conn.disconnect(); // 斷開連線
                }
            }
            return null;
        }
    }

}

(4)使用三個工具類完成Bitmap的三級快取

 /*
一。三級快取
1.執行記憶體:LruUtils(建立例項,存,讀)
2.檔案SD
3.網路請求
* */
public class MainActivity extends AppCompatActivity {
    private ImageView imageView;
    private  LruUtils lruUtils= new LruUtils();//TODO 注意:同一個記憶體物件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView=findViewById(R.id.image);
    }

    public void click(View view) throws ExecutionException, InterruptedException {
        //TODO 1:先從執行記憶體中讀取
        Bitmap bitmap=lruUtils.getBitmap("宋定行");
        if(bitmap!=null){//有圖片
            imageView.setImageBitmap(bitmap);
            Toast.makeText(this, "圖片來自記憶體", Toast.LENGTH_SHORT).show();
        }else{
            //TODO 2:若記憶體沒有去SD卡
            bitmap=SDUtils.getBitmap("宋定行.jpg");
            if(bitmap!=null){
                imageView.setImageBitmap(bitmap);
                Toast.makeText(this, "圖片從SD卡來de", Toast.LENGTH_SHORT).show();
                //向記憶體中儲存一下
                lruUtils.setBitmap("宋定行",bitmap);
            }else{
                //TODO 3:執行記憶體和SD卡都沒有圖片,接下來網路獲取
                bitmap=NetUtils.getBitmap("http://upload.cbg.cn/2015/1126/1448506973451.jpg");
                if(bitmap!=null){
                    imageView.setImageBitmap(bitmap);
                    Toast.makeText(this, "圖片從網路獲取", Toast.LENGTH_SHORT).show();
                    //將圖片再放到SD卡和記憶體中
                    SDUtils.setBitmap("宋定行.jpg",bitmap);
                    lruUtils.setBitmap("宋定行",bitmap);
                }else{
                    Toast.makeText(this, "窮玩意檢查下你的網咖", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
}