當前位置:首頁 » 文件管理 » 緩存bitmap

緩存bitmap

發布時間: 2023-07-27 12:06:50

❶ 安卓開發Xutils.Bitmap怎麼實現的三級緩存

網路緩存
網路拉取圖片嚴格來講不能稱之為緩存,實質上就是下載url對應的圖片,我們這里姑且把它看作是緩存的一種。仿照BitmapUtil中的display方法,我自己定製的CustomBitmapUtils也定義這個方法,根據傳入的url,將圖片設置到ivPic控制項上。

[java] view plain
public void display(ImageView ivPic, String url) {

}
定義網路緩存的工具類,在訪問網路的時候,我使用了AsyncTask來實現,在AsyncTask的doInBackGround方法里下載圖片,然後將 圖片設置給ivPic控制項,AsyncTask有三個泛型,其中第一個泛型是執行非同步任務的時候,通過execute傳過來的參數,第二個泛型是更新的進度,第三個泛型是非同步任務執行完成之後,返回來的結果,我們這里返回一個Bitmap。具體的下載實現代碼如下:

[java] view plain
<pre name="code" class="java">/**
* 網路緩存的工具類
*
* @author ZHY
*
*/
public class NetCacheUtils {

private LocalCacheUtils localCacheUtils;
private MemoryCacheUtils memoryCacheUtils;

public NetCacheUtils() {
localCacheUtils = new LocalCacheUtils();
memoryCacheUtils = new MemoryCacheUtils();
}

/**
* 從網路下載圖片
*
* @param ivPic
* @param url
*/
public void getBitmapFromNet(ImageView ivPic, String url) {
// 訪問網路的操作一定要在子線程中進行,採用非同步任務實現
MyAsyncTask task = new MyAsyncTask();
task.execute(ivPic, url);

}

/**
* 第一個泛型--非同步任務執行的時候,通過execute傳過來的參數; 第二個泛型--更新進度; 第三個泛型--非同步任務執行以後返回的結果
*
* @author ZHY
*
*/
private class MyAsyncTask extends AsyncTask<Object, Void, Bitmap> {

private ImageView ivPic;
private String url;

// 耗時任務執行之前 --主線程
@Override
protected void onPreExecute() {
super.onPreExecute();
}

// 後台執行的任務
@Override
protected Bitmap doInBackground(Object... params) {
// 執行非同步任務的時候,將URL傳過來
ivPic = (ImageView) params[0];
url = (String) params[1];
Bitmap bitmap = downloadBitmap(url);
// 為了保證ImageView控制項和URL一一對應,給ImageView設定一個標記
ivPic.setTag(url);// 關聯ivPic和URL

return bitmap;
}

// 更新進度 --主線程
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}

// 耗時任務執行之後--主線程
@Override
protected void onPostExecute(Bitmap result) {
String mCurrentUrl = (String) ivPic.getTag();
if (url.equals(mCurrentUrl)) {
ivPic.setImageBitmap(result);
System.out.println("從網路獲取圖片");
// 從網路載入完之後,將圖片保存到本地SD卡一份,保存到內存中一份
localCacheUtils.setBitmap2Local(url, result);
// 從網路載入完之後,將圖片保存到本地SD卡一份,保存到內存中一份
memoryCacheUtils.setBitmap2Memory(url, result);

}
}
}

/**
* 下載網路圖片
*
* @param url
* @return
*/
private Bitmap downloadBitmap(String url) {
HttpURLConnection conn = null;
try {
URL mURL = new URL(url);
// 打開HttpURLConnection連接
conn = (HttpURLConnection) mURL.openConnection();
// 設置參數
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
// 開啟連接
conn.connect();

// 獲得響應碼
int code = conn.getResponseCode();
if (code == 200) {
// 相應成功,獲得網路返回來的輸入流
InputStream is = conn.getInputStream();

// 圖片的輸入流獲取成功之後,設置圖片的壓縮參數,將圖片進行壓縮
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;// 將圖片的寬高都壓縮為原來的一半,在開發中此參數需要根據圖片展示的大小來確定,否則可能展示的不正常
options.inPreferredConfig = Bitmap.Config.RGB_565;// 這個壓縮的最小

// Bitmap bitmap = BitmapFactory.decodeStream(is);
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);// 經過壓縮的圖片

return bitmap;
}

} catch (Exception e) {
e.printStackTrace();
} finally {
// 斷開連接
conn.disconnect();
}

return null;
}
}

❷ Bitmap使用詳解

用到的圖片不僅僅包括.png、.gif、.9.png、.jpg和各種Drawable系對象,還包括點陣圖Bitmap

圖片的處理也經常是影響著一個程序的高效性和健壯性。

為什麼不直接用Bitmap傳輸?
點陣圖文件雖好,但是非壓縮格式,佔用較大存儲空間。

Bitmap主要方法有:獲取圖像寬高、釋放,判斷是否已釋放和是否可修改,壓縮、創建制定點陣圖等功能

用於從不同的數據源(如文件、輸入流、資源文件、位元組數組、文件描述符等)解析、創建Bitmap對象

允許我們定義圖片以何種方式如何讀到內存。

推薦閱讀: Android - Bitmap-內存分析

注意事項:

decodeFileDescriptor比decodeFile高效

查看源碼可以知道

替換成

建議採用decodeStream代替decodeResource。

因為BitmapFactory.decodeResource 載入的圖片可能會經過縮放,該縮放目前是放在 java 層做的,效率比較低,而且需要消耗 java 層的內存。因此,如果大量使用該介面載入圖片,容易導致OOM錯誤,BitmapFactory.decodeStream 不會對所載入的圖片進行縮放,相比之下佔用內存少,效率更高。

這兩個介面各有用處,如果對性能要求較高,則應該使用 decodeStream;如果對性能要求不高,且需要 Android 自帶的圖片自適應縮放功能,則可以使用 decodeResource。

推薦閱讀:[ BitmapFactory.decodeResource載入圖片縮小的原因及解決方法

canvas和Matrix可對Bitmap進行旋轉、放縮、平移、切錯等操作

可以用Bitmap.onCreateBitmap、Canvas的clipRect和clipPath等等方式

推薦閱讀: android自定義View學習4--圖像剪切與變換

對初始化Bitmap對象過程中可能發生的OutOfMemory異常進行了捕獲。如果發生了OutOfMemory異常,應用不會崩潰,而是得到了一個默認的Bitmap圖。

如果不進行緩存,盡管看到的是同一張圖片文件,但是使用BitmapFactory類的方法來實例化出來的Bitmap,是不同的Bitmap對象。緩存可以避免新建多個Bitmap對象,避免內存的浪費。

如果圖片像素過大,使用BitmapFactory類的方法實例化Bitmap的過程中,需要大於8M的內存空間,就必定會發生OutOfMemory異常。
可以將圖片縮小,以減少載入圖片過程中的內存的使用,避免異常發生。

推薦閱讀:
Bitmap詳解與Bitmap的內存優化

❸ 緩存擊穿互斥鎖 設置鎖的失效時間

  • 設置鎖的失效時間是自己設置的,它的過期時間會很短,最長不超過五分鍾

  • 緩存穿透是指查詢一個一定不存在的數據

  • 由於緩存是不命中時被動寫的,

  • 並且出於容錯考慮,如果從存儲層查不到數據則不寫入緩存,

  • 這將導致這個不存在的數據每次請求都要到存儲層去查詢,失去了緩存的意義。

  • 在流量大時,可能DB就掛掉了,

  • 要是有人利用不存在的key頻繁攻擊我們的應用,這就是漏洞。

  • 最常見的則是採用布隆過濾器

  • 將所有可能存在的數據哈希到一個足夠大的bitmap中,

  • 一個一定不存在的數據會被 這個bitmap攔截掉,

  • 從而避免了對底層存儲系統的查詢壓力。

  • 另外也有一個更為簡單粗暴的方法

  • 如果一個查詢返回的數據為空(不管是數 據不存在,還是系統故障),

  • 我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鍾

❹ Android-Listview中Bitmap的緩存實現都有哪些方式

1.一般使用2中,一種是 通過 adapter 參數中的List的對應位置線放入一張載入中的圖片,然後把adapter 賦值給View以後,開啟另外一個線程下載圖片,然後刷新adapter 達到效果,
2.自定意個adapter 然後在adapter 中獲得獲得圖片路徑有開啟一個線程下載,之後在ImageView等VIEW 賦值。

❺ 安卓從手機相冊獲取照片作為頭像緩存地址

* 1、實現原理:用戶打開相冊或相機選擇相片後,相片經過壓縮並設置在控制項上,圖片在本地sd卡存一份(如果有的話,沒大桐有則內部存儲,所以還
* 需要判斷用戶是否掛載了sd卡),然後在伺服器上存儲一份該圖片,當下次再次啟桐則動應用時,會默認去sd卡載入該圖片,如果本地沒有,再會去聯網請求
* 2、使用了picasso框架以及自定義BitmapUtils工具類
* 3、記得加上相關權局仿棚限
* <uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
* */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ImageView iv;//要設置的頭像
private Button btn_photo;//調用相冊按鈕
private Button btn_camera;//調用相機按鈕
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv=(ImageView) findViewById(R.id.iv);
btn_photo = (Button) findViewById(R.id.btn_photo);
btn_camera = (Button) findViewById(R.id.btn_camera);
btn_photo.setOnClickListener(this);
btn_camera.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_photo://打開系統相冊
Intent intent=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,100);
break;
case R.id.btn_camera://打開系統相機
Intent intent2=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent2,200);
break;
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==100&&resultCode==RESULT_OK&&data!=null){//系統相冊
Uri imageData = data.getData();
String path=getPath(imageData);
Bitmap bitmap = BitmapFactory.decodeFile(path);
Bitmap bitmap1 = BitmapUtils.zoom(bitmap, iv.getWidth(), iv.getHeight());
Bitmap bitmap2 = BitmapUtils.circleBitmap(bitmap1);
//載入顯示
iv.setImageBitmap(bitmap2);
//bitmap圖片上傳到伺服器......
//bitmap圖片保存到本地
saveImage(bitmap2);
}else if(requestCode==200&&resultCode==RESULT_OK&&data!=null){//系統相機
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
BitmapUtils.zoom(bitmap,iv.getWidth(),iv.getHeight());
bitmap=BitmapUtils.circleBitmap(bitmap);
//載入顯示
iv.setImageBitmap(bitmap);
//bitmap圖片上傳到伺服器......
//bitmap圖片保存到本地
saveImage(bitmap);
}
}
/**
* 數據的存儲。(5種)
* Bimap:內存層面的圖片對象。
*
* 存儲--->內存:
* BitmapFactory.decodeFile(String filePath);
* BitmapFactory.decodeStream(InputStream is);
* 內存--->存儲:
* bitmap.compress(Bitmap.CompressFormat.PNG,100,OutputStream os);
*/
private void saveImage(Bitmap bitmap) {
File filesDir;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判斷sd卡是否掛載
//路徑1:storage/sdcard/Android/data/包名/files
filesDir = this.getExternalFilesDir("");
}else{//手機內部存儲
//路徑:data/data/包名/files
filesDir = this.getFilesDir();
}
FileOutputStream fos = null;
try {
File file = new File(filesDir,"icon.png");
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100,fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//如果本地有,就不需要再去聯網去請求
private boolean readImage() {
File filesDir;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判斷sd卡是否掛載
//路徑1:storage/sdcard/Android/data/包名/files
filesDir = getExternalFilesDir("");
}else{//手機內部存儲
//路徑:data/data/包名/files
filesDir = getFilesDir();
}
File file = new File(filesDir,"icon.png");
if(file.exists()){
//存儲--->內存
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
iv.setImageBitmap(bitmap);
return true;
}
return false;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private String getPath(Uri uri) {
int sdkVersion = Build.VERSION.SDK_INT;
//高於4.4.2的版本
if (sdkVersion >= 19) {
Log.e("TAG", "uri auth: " + uri.getAuthority());
if (isExternalStorageDocument(uri)) {
String docId = DocumentsContract.getDocumentId(uri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(this, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(this, contentUri, selection, selectionArgs);
} else if (isMedia(uri)) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor actualimagecursor = this.managedQuery(uri, proj, null, null, null);
int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
actualimagecursor.moveToFirst();
return actualimagecursor.getString(actual_image_column_index);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(this, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* uri路徑查詢欄位
*
* @param context
* @param uri
* @param selection
* @param selectionArgs
* @return
*/
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean isMedia(Uri uri) {
return "media".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
/**
* 判斷本地是否有該圖片,沒有則去聯網請求
* */
@Override
protected void onResume() {
super.onResume();
if(readImage()){
return;
}
}
}
//BitmapUtils工具類public class BitmapUtils { /**
* 該方法用於將圖片進行圓形處理
* */ public static Bitmap circleBitmap(Bitmap source){ //默認只對寬進行處理 int width=source.getWidth(); Bitmap bitmap=Bitmap.createBitmap(width,width,Bitmap.Config.ARGB_8888); Canvas canvas=new Canvas(bitmap); Paint paint=new Paint(); //設置抗鋸齒 paint.setAntiAlias(true); canvas.drawCircle(width/2,width/2,width/2,paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(source,0,0,paint); return bitmap; } /** * 該方法用於圖片壓縮處理,注意width、height參數的類型必須是float * */ public static Bitmap zoom(Bitmap source,float width,float height){ Matrix matrix=new Matrix(); //圖片進行壓縮處理 matrix.postScale(width/source.getWidth(),height/source.getHeight()); Bitmap bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, false); return bitmap; }}
以上所述是小編給大家介紹的Android實現調用系統圖庫與相機設置頭像並保存在本地及伺服器 ,希望對大家有所幫助

熱點內容
滑板鞋腳本視頻 發布:2025-02-02 09:48:54 瀏覽:433
群暉怎麼玩安卓模擬器 發布:2025-02-02 09:45:23 瀏覽:557
三星安卓12彩蛋怎麼玩 發布:2025-02-02 09:44:39 瀏覽:743
電腦顯示連接伺服器錯誤 發布:2025-02-02 09:24:10 瀏覽:537
瑞芯微開發板編譯 發布:2025-02-02 09:22:54 瀏覽:147
linux虛擬機用gcc編譯時顯示錯誤 發布:2025-02-02 09:14:01 瀏覽:240
java駝峰 發布:2025-02-02 09:13:26 瀏覽:652
魔獸腳本怎麼用 發布:2025-02-02 09:10:28 瀏覽:538
linuxadobe 發布:2025-02-02 09:09:43 瀏覽:212
sql2000資料庫連接 發布:2025-02-02 09:09:43 瀏覽:726