圖片的三級快取和二次取樣使用的案例
首先跟大家介紹一下三級快取,當然快取的好處就是可以讓使用者體驗更好,通過首次訪問時將資料儲存起來,以後需要就直接在本地獲取資料,減少不必要的網路訪問次數,也減少了流量的開銷。但我們大部分應用都運用了此技術,所以三級快取運用面比較廣的。
所謂三級快取其實是一種載入圖片檔案的策略,簡單的來說就是 “記憶體——檔案——網路”,顧名思義,當你需要載入一張圖片,首先去記憶體中去取,原因是記憶體的響應速度最快,其次是外存(即SD卡),如果兩者都沒有你需要的圖片,那就只有傳送網路請求獲取圖片,但需要注意的是當網路獲取到圖片時首先存入SD卡中,當需要此圖片時,戶首先去快取中去取,但是快取還沒有存入資料,接著去sd卡中去獲取資料此時sd卡中已經有資料,在此時將sd卡中的資料存入快取中去的同時將資料取出來使用。當下一次需要使用該圖片時,就可以在快取中直接獲取圖片了。
三級快取想必大家已經有了一定的瞭解了下面來說說二次取樣
二次取樣使為了避免程式oom,當我們需要載入一張獲取多張圖片時,由於程式分配的記憶體有限,當圖片過大過多時,記憶體就就會溢位,程式就直接over了,所以二次取樣時為了優化程式。
我們來說說二次取樣的原理,首先我們獲取一張高清圖片獲取此圖片的寬(sourceWidth)和高(sourceHeight),然後自己把需要的圖片的寬(width)和高(height)通過引數縮放比率來進行調整,與原圖進行比較,通過BitmapFactory內部的解碼器引數的設定, 通過引數縮放(simpleSize)來不斷調整大小,當有一條邊和規定的邊相等時,將邊框繪製成功,第一次取樣完成,第二次取樣就是通過得到的邊框來設定彩色格式RGB_565
說了這麼多下面就給大家展示一個小案例,看完案例你應該就明白了。
下面是佈局檔案
下面是MainActivity:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="demo.liuchen.com.android25_lrucache.MainActivity"> <Button android:id="@+id/btn_getImg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="Click" android:text="獲取圖片"/> <ImageView android:id="@+id/image_Show" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop"/> </LinearLayout>
package demo.liuchen.com.android25_lrucache;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* 圖片的三級快取:LruCache--SDCard——Internet
*/
public class MainActivity extends AppCompatActivity {
// private String url = "http://p8.qhimg.com/t0113125382f3c4141a.png";
private String url = "http://t2.27270.com/uploads/tu/201606/32/k5xnewfzvz0.jpg";
private ImageView imageView;
private LruCache<String,Bitmap> lruCache;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==1){
Bitmap bitmap = (Bitmap) msg.obj;
imageView.setImageBitmap(bitmap);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.image_Show);
//獲取執行時記憶體
Long MaxSize = Runtime.getRuntime().maxMemory();
//初始化LruCache
lruCache = new LruCache<String, Bitmap>((int) (MaxSize/8)){
//key 從記憶體中取出或存入的物件的名字
//value 存取的物件
//return 返回物件的快取
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
public void Click(View view) {
//當用戶需要圖片是先到快取中去取
Bitmap bitmap = lruCache.get(getName(url));
if (bitmap!= null){
Log.e("TAG","在快取中獲取");
imageView.setImageBitmap(bitmap);
}else {
//在檔案中查詢
Bitmap bitmap1 = getBitmapFromSDCard(getName(url));
if (bitmap1!= null){
Log.e("TAG","在檔案中獲取");
imageView.setImageBitmap(bitmap1);
//如果圖片在SD卡中找到,將圖片放入快取
Log.e("TAG","檔案中存在放入快取");
lruCache.put(getName(url),bitmap1);
}else {
getBitmapFromNet();
}
}
}
//從網路獲取
private void getBitmapFromNet() {
Log.e("TAG","在網路中獲取");
new Thread(new Runnable() {
@Override
public void run() {
try {
URL path = new URL(url);
HttpURLConnection httpURLConn = (HttpURLConnection) path.openConnection();
if (httpURLConn.getResponseCode() == 200){
final Bitmap bitmap = BitmapFactory.decodeStream(httpURLConn.getInputStream());
//將圖片放入快取中
lruCache.put(getName(url),bitmap);
//將bitmap存入當前檔案的檔案中
SaveBitmapToSDCard(getName(url),bitmap);
Message message = Message.obtain();
message.obj=1;
message.obj=bitmap;
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
//將Bitmap存入sd卡中
private void SaveBitmapToSDCard(String name, Bitmap bitmap) {
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(new File(getExternalCacheDir(),name)));
if (name.endsWith("png")||name.endsWith("PNG")){
//把bitmap存入SdCard中
Log.e("TAG","把bitmap存入SdCard中");
bitmap.compress(Bitmap.CompressFormat.PNG,100,bos);
}else {
bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//從sd卡中獲取圖片
private Bitmap getBitmapFromSDCard(String name) {
// Log.e("TAG","從SD卡中獲取圖片");
//如果需要原圖就可以不呼叫二次採用方法
// Bitmap bitmap = BitmapFactory.decodeFile(getExternalCacheDir().getAbsolutePath()+ File.separator+name);
//在SD卡中取出的Bitmap進行二次取樣,傳出去後會將二次取樣好的圖片放入快取中
Bitmap bitmap = BitmapUtils.getBitmap(getExternalCacheDir().getAbsolutePath()+File.separator+name,100,100);
return bitmap;
}
//獲取Bitmap為Url的名字
public String getName(String url){
String name = url.substring(url.lastIndexOf("/")+1,url.length());
return name;
}
}
下面是二次取樣的封裝類,方便呼叫。
package demo.liuchen.com.android25_lrucache;
/**
* Created by Administrator on 2016/9/23.
*/
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
* Bitmap二次取樣工具類
*/
public class BitmapUtils {
/**
*
* @param filePath bitmap的路徑
* @param destWidth 希望取樣後Bitmap的寬
* @param destHeight 希望取樣後Bitmap的高
*
* @return 只有邊框的bitmap
*/
public static Bitmap getBitmap(String filePath, int destWidth, int destHeight) {
//第一取樣
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
int outWidth = options.outWidth;
int outHeight = options.outHeight;
int sampleSize = 1;
while ((outWidth / sampleSize > destWidth) || (outHeight / sampleSize > destHeight)) {
sampleSize *= 2;
}
//第二次取樣
options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;
options.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeFile(filePath, options);
}
}
}
//獲取Bitmap為Url的名字
public String getName(String url){
String name = url.substring(url.lastIndexOf("/")+1,url.length());
return name;
}
}
//當然訪問了網路和sd卡記得在Manifest清單檔案加上許可權:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//好了案例就完成了,如果有問題歡迎評論和指正,也可以加好友一起交流學習。
下面是以上案例的程式碼需要的可以自行下載:http://download.csdn.net/detail/mr_condingson/9765051
相關推薦
圖片的三級快取和二次取樣使用的案例
首先跟大家介紹一下三級快取,當然快取的好處就是可以讓使用者體驗更好,通過首次訪問時將資料儲存起來,以後需要就直接在本地獲取資料,減少不必要的網路訪問次數,也減少了流量的開銷。但我們大部分應用都運用了此技術,所以三級快取運用面比較廣的。 所謂三級快取其實是一種載入圖片檔案的策
大數據技術之輔助排序和二次排序案例(GroupingComparator)
group http pac ppr instance div lec tex boolean 大數據技術之輔助排序和二次排序案例(GroupingComparator) 1)需求 有如下訂單數據 訂單id 商品id 成交金額
PullToRefreshListView上拉和下拉+輪播圖多條目+fragment巢狀fragment+二次取樣+側拉點選切換fragment+PullToRefreshGritView圖片展示
側拉 程式碼 1提取的基類 1.1Activity的基類 package com.example.zonghelianxi02.ui.activity; import android.os.Bundle; import android.support.annotation.Nulla
二次取樣,三級快取
1.建立一個Util類,裡面封裝了二次取樣和三級快取的方法 public class ImageUtil { //二次取樣 public static Bitmap TwoImage(String filepath,int width,int heigh){ BitmapFac
二次取樣圖片
Mantivity主頁面: package com.bw.ymy.ymy1107; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import
圖片二次取樣
MainActivity頁面 package com.example.image; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import
側滑+fragment切換頁面+fragment巢狀+二次取樣+輪播圖+gridview展示圖片+網路請求資料+資料庫
全域性配置Appliction 所需要的依賴有:implementation ‘com.google.code.gson:gson:2.8.5’ implementation ‘com.nostra13.universalimageloader:universal-image-loader:
圖片二次取樣///////////子執行緒
1.提取的基類 在這裡插入程式碼片package com.example.imager_er; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7
fragment中的ImagView+Text多條目,點選ImageView二次取樣切換相簿圖片
##Fragmentd的 XML: <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android=“http://schemas.and
某宅的Android學習筆記(二)——圖片三級快取
圖片三級快取的重要性 很多時候我們都需要從網路上下載圖片,如果在圖片很多的情況下,每次啟動app都要從網上下載,就會造成流量的浪費,影響使用者的體驗。因此,要利用快取來避免圖片的重複載入。 圖片快取方式 所謂三級快取,即: 網路快取 記憶體快取
Android_Bitmap_圖片的二次取樣並生成縮圖
首先嚐試通過位元組陣列或者流,只去載入圖片的外邊緣,此時必須指定BitmapFactory.Options 的inJustDecodeBounds成員名,將其只為true,一旦設定為true,BitmapFactory解碼後返回值為null,通過Options的outHe
04 用戶個人信息和二次開發django的文件存儲系統
存在 引入 tracker 連接 code quest 安裝包 gis ase 用戶的個人信息的前端頁面如下: 業務邏輯分析 從上圖中可以看出,需要後端傳送的數據有,用戶的名字和練習的地址,和最近的瀏覽記錄。 用戶的名字和聯系的地址可以通過地址表(adre
Android反編譯和二次打包
犯錯 解壓 就會 field har stat 生成 https make 參考:APK反編譯 一、工具介紹: 1、解壓工具 2、JDK 3.apktool: aapt.exe,apktool.bat,apktool.jar;三個在同一目錄結合使用,用來反編譯apk
Vue 中使用 el-input 自動獲取焦點和二次獲取焦點問題
最近,碰到一個問題,就是輸入框旁邊有一個編輯按鈕,點選時,才可以對輸入框進行編輯: 要實現的效果: 為了方便輸入,需要自動獲取焦點,所以加入了autofocus,但是發現,只有第一個並且第一次點選才起作用。 查了網上的一些文件,說是跟dom的渲染順序和資料的快取有點兒關係,至
二次取樣+AsyncTask
#1.主頁面 package com.bw.ymy.imageloader; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import a
微信二次開發案例,python製作微信支付小程式!
由於最近自己在做小程式的支付,就在這裡簡單介紹一下講一下用python做小程式支付這個流程。當然在進行開發之前還是建議讀一下具體的流程,清楚支付的過程。 1.支付互動流程 當然具體的引數配置可以參考官方文件 https://p
二次取樣+質量壓縮
1.MainActivity頁面 package com.example.image; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; impo
【51Nod1405】樹上距離和 二次掃描與換根法
continue 51nod max span ons its 轉移 rom ace 題目大意:給定一棵 N 個點的邊權均為 1 的樹,依次輸出每個點到其他各個點的距離和。 題解:首先任意選定一個節點為根節點,比如 1,第一遍 dfs 遍歷樹求出子樹大小、樹上前綴和。第二遍
側滑(點選條目進行跳轉+點選更換頭像(二次取樣))+ViewPager
1.Layout佈局 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk
點選頭像二次取樣
1.側滑佈局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_w