編輯:關於Android編程
package cc.vv; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import libcore.io.DiskLruCache; import libcore.io.Utils; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.ImageView; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; /** * Demo描述: * DiskLruCache學習示例 * * DiskLruCache用於本地緩存. * 比如在網絡可用時加載一張網絡圖片,當網絡不可用時依然可以顯示該圖片。 * 實現的原理是將圖片保存到本地;當網絡不可用時從本地加載圖片。 * 在此簡單模擬該過程,步驟如下: * 1 從網絡下載圖片且保存至DiskLruCache * 2 從DiskLruCache中獲取緩存圖片進行顯示 * * * 學習備注: * 1 DiskLruCache的本地緩存文件路徑為: * /sdcard/Android/data//cache * 當應用被卸載時該文件亦會被刪除 * 2 新聞類APP一般的做法.從新聞列表(ListView)中點擊某條新聞跳轉到詳細畫面. * 在詳細畫面一般有圖片和文字.此時可以將圖片和文字用同一個key存到不同的緩存文件夾下. * 在斷網時浏覽該新聞時候依據該key分別取出對應的圖片和文字即可. * 3 在示例中用到了DiskLruCache的存和取的相關API.在此對其余重要API簡要整理: * 3.1 remove(String key) 刪除某個已緩存的對象. * 3.2 size() 得到緩存路徑下緩存的總大小.這個很常見.許多APP都提示當前有多少緩存. * 3.3 flush() 將內存中的操作記錄同步到日志文件(也就是journal文件)中 * 一般在Activity的onPause()中調用該方法. * 3.4 close() 關閉DiskLruCache.該方法與open方法對應. * 一般在Activity的onDestory()中調用該方法. * 3.5 delete() 將緩存數據全部刪除. * * * 學習資源: * http://blog.csdn.net/guolin_blog/article/details/28863651 * Thank you very much */ public class MainActivity extends Activity { private ImageView mImageView; private DiskLruCache mDiskLruCache; private Context mContext; //DiskLruCache中對於圖片的最大緩存值. private int maxSize=20*1024*1024; private String mImagePath=http://www.baidu.com/img/bdlogo.png; private Handler mHandler; private final int FINISH=9527; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } private void init(){ try { mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what==FINISH) { getDataFromDiskLruCache(); } } }; mContext=this; mImageView=(ImageView) findViewById(R.id.imageView); initDiskLruCache(); } catch (Exception e) { // TODO: handle exception } } /** * 初始化DiskLruCache */ private void initDiskLruCache(){ try { File cacheDir=Utils.getDiskLruCacheDir(mContext, bitmap); if (!cacheDir.exists()) { cacheDir.mkdirs(); } int versionCode=Utils.getAppVersionCode(mContext); mDiskLruCache=DiskLruCache.open(cacheDir, versionCode, 1, maxSize); saveDataToDiskLruCache(); } catch (Exception e) { // TODO: handle exception } } // 將數據寫入DiskLruCache private void saveDataToDiskLruCache() { new Thread(new Runnable() { @Override public void run() { try { //第一步:獲取將要緩存的圖片的對應唯一key值. String key = Utils.getStringByMD5(mImagePath); //第二步:獲取DiskLruCache的Editor DiskLruCache.Editor editor = mDiskLruCache.edit(key); if (editor!=null) { //第三步:從Editor中獲取OutputStream OutputStream outputStream=editor.newOutputStream(0); //第四步:下載網絡圖片且保存至DiskLruCache圖片緩存中 boolean isSuccessfull=Utils.getBitmapFromNetWorkAndSaveToDiskLruCache(mImagePath, outputStream); if (isSuccessfull) { editor.commit(); mHandler.sendEmptyMessage(FINISH); }else{ editor.abort(); } mDiskLruCache.flush(); } } catch (Exception e) { } } }).start(); } //從DiskLruCache中讀取數據 private void getDataFromDiskLruCache(){ try { //第一步:獲取已緩存的圖片的對應唯一key值. String key = Utils.getStringByMD5(mImagePath); //第二步:依據key獲取到其對應的snapshot DiskLruCache.Snapshot snapshot=mDiskLruCache.get(key); if (snapshot!=null) { //第三步:從snapshot中獲取到InputStream InputStream inputStream=snapshot.getInputStream(0); Bitmap bitmap=BitmapFactory.decodeStream(inputStream); mImageView.setImageBitmap(bitmap); } } catch (Exception e) { } } }
Utils如下:
package libcore.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.http.HttpStatus; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Environment; public class Utils { /** * 獲取DiskLruCache的緩存文件夾 * 注意第二個參數dataType * DiskLruCache用一個String類型的唯一值對不同類型的數據進行區分. * 比如bitmap,object等文件夾.其中在bitmap文件夾中緩存了圖片. * * 緩存數據的存放位置為: * /sdcard/Android/data//cache * 如果SD卡不存在時緩存存放位置為: * /data/data//cache * */ public static File getDiskLruCacheDir(Context context, String dataType) { String dirPath; File cacheFile = null; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { dirPath=context.getExternalCacheDir().getPath(); } else { dirPath=context.getCacheDir().getPath(); } cacheFile=new File(dirPath+File.separator+dataType); return cacheFile; } /** * 獲取APP當前版本號 * @param context * @return */ public static int getAppVersionCode(Context context){ int versionCode=1; try { String packageName=context.getPackageName(); PackageManager packageManager=context.getPackageManager(); PackageInfo packageInfo=packageManager.getPackageInfo(packageName, 0); versionCode=packageInfo.versionCode; } catch (NameNotFoundException e) { e.printStackTrace(); } return versionCode; } /** * 將字符串用MD5編碼. * 比如在改示例中將url進行MD5編碼 */ public static String getStringByMD5(String string) { String md5String = null; try { // Create MD5 Hash MessageDigest messageDigest = MessageDigest.getInstance(MD5); messageDigest.update(string.getBytes()); byte messageDigestByteArray[] = messageDigest.digest(); if (messageDigestByteArray == null || messageDigestByteArray.length == 0) { return md5String; } // Create hexadecimal String StringBuffer hexadecimalStringBuffer = new StringBuffer(); int length = messageDigestByteArray.length; for (int i = 0; i < length; i++) { hexadecimalStringBuffer.append(Integer.toHexString(0xFF & messageDigestByteArray[i])); } md5String = hexadecimalStringBuffer.toString(); return md5String; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return md5String; } /** * 從網絡獲取圖片且保存至SD卡中的緩存 */ public static boolean getBitmapFromNetWorkAndSaveToDiskLruCache(String imageUrl,OutputStream outputStream){ boolean isSuccessfull=false; URL url=null; HttpURLConnection httpURLConnection=null; BufferedOutputStream bufferedOutputStream=null; InputStream inputStream=null; BufferedInputStream bufferedInputStream=null; try { url=new URL(imageUrl); httpURLConnection=(HttpURLConnection) url.openConnection(); httpURLConnection.setConnectTimeout(5*1000); httpURLConnection.setReadTimeout(10*1000); httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); if (httpURLConnection.getResponseCode()==HttpStatus.SC_OK) { bufferedOutputStream=new BufferedOutputStream(outputStream); inputStream=httpURLConnection.getInputStream(); bufferedInputStream=new BufferedInputStream(inputStream); int len=0; byte [] buffer=new byte[1024]; while((len=bufferedInputStream.read(buffer))!=-1){ bufferedOutputStream.write(buffer, 0, len); bufferedOutputStream.flush(); } isSuccessfull=true; } else { isSuccessfull=false; System.out.println(圖片請求失敗); } } catch (Exception e) { isSuccessfull=false; System.out.println(e=+e.toString()); }finally{ try { if (bufferedOutputStream!=null) { bufferedOutputStream.close(); } if (inputStream!=null) { inputStream.close(); } if (bufferedInputStream!=null) { bufferedInputStream.close(); } if (httpURLConnection!=null) { httpURLConnection.disconnect(); } } catch (Exception e) { System.out.println(e=+e.toString()); } } return isSuccessfull; } }
簡介 在ReactiveCocoa中通過對相關的控件添加了信號的特征,采用category的方法在UIButton中添加其category。可以發現在Reac
側滑菜單在很多應用中都會見到,最近QQ5.0側滑還玩了點花樣~~對於側滑菜單,一般大家都會自定義ViewGroup,然後隱藏菜單欄,當手指滑動時,通過Scroller或者
問題現象 (該文章,引自零號路的私人博客,本人在浏覽框架的開發過程中,用該方式,規避了內存洩露的問題。) 在Android5.1系統中,會發現App存在 Web
render進程中 一.webkit模塊 webkit引擎會為網頁內容同時創建Dom tree, Render tree和RenderLayer tree. 這三棵樹之間