編輯:關於Android編程
之前寫過一篇android異步加載圖片類 ,後來接觸了一個開源項目universal-image-loader,聽說淘寶也是用這玩意
發現自己寫的那個異步加載類太簡單了,雖然功能是實現了,但是很多優化的問題都沒有解決
比如:
同一個ui加載同一張圖,會出現只加載一張,其他的加載不了
加載多圖的時候會有oom等問題
現在來說說universal-image-loader
特點:
多線程的圖像加載
的可能性的寬調諧對ImageLoader的配置(線程池的大小,HTTP選項,內存和光盤高速緩存,顯示圖像,以及其他)
的圖像的可能性中的緩存存儲器和/或設備的文件器系統(或SD卡)
可以“聽”加載過程中
可自定義每個顯示的圖像調用分隔的選項
Widget支持
Android 1.5以上支持
使用方法:(我自己封裝了一個類ImgConfig使用,方便一些)
只需兩步即可加載網絡圖片:
一、初始化
ImgConfig.initImageLoader();
二、
ImgConfig.showUserSImg(imgUrl, imageview); //圖片的url,要顯示的view
以下是我自己寫的ImgConfig,僅供參考:
public class ImgConfig extends ImageLoader { private static DisplayImageOptions options_corner; private static DisplayImageOptions options_square; private static AnimateFirstDisplayListener animateFirstDisplayListener = new AnimateFirstDisplayListener(); /** * @param url 服務器的文件名 * @param imageView * 顯示方形圖片 S for Square */ public static void showUserSImg(String url, ImageView imageView) { ImageLoader.getInstance().displayImage(url, imageView, options_square, animateFirstDisplayListener); } /** * @param url 服務器的文件名 * @param imageView * 圓角 C for Corner */ public static void showUserCImg(String url, ImageView imageView) { ImageLoader.getInstance().displayImage(url, imageView, options_corner, animateFirstDisplayListener); } /** * 初始化圖片讀取方式 */ public static void initImageLoader() { DisplayImageOptions options_corner = new DisplayImageOptions.Builder() .showImageOnLoading(ImgHandler.ToCircular(R.drawable.defult_head)) // 加載中 .showImageForEmptyUri(ImgHandler.ToCircular(R.drawable.defult_head)) // 空uri .showImageOnFail(ImgHandler.ToCircular(R.drawable.defult_head)) // 失敗時 .cacheInMemory(true) // 設置下載的圖片是否緩存在內存中 .cacheOnDisc(true) // 設置下載的圖片是否緩存在SD卡中 .considerExifParams(true) .displayer(new RoundedBitmapDisplayer(10)) // 展現方式:圓角 .resetViewBeforeLoading(true) .imageScaleType(ImageScaleType.EXACTLY) // new FadeInBitmapDisplayer(300) 漸現 .build(); options_square = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.defult_head) .showImageForEmptyUri(R.drawable.defult_head) .showImageOnFail(R.drawable.defult_head) .cacheInMemory(true) .cacheOnDisc(true) .considerExifParams(true) .displayer(new FadeInBitmapDisplayer(100)) // 展現方式:漸現 .resetViewBeforeLoading(true) .imageScaleType(ImageScaleType.EXACTLY) .build(); // This configuration tuning is custom. You can tune every option, you // may tune some of them, // or you can create default configuration by // ImageLoaderConfiguration.createDefault(this); // method. ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder( ContextUtil.getInstance()) .threadPriority(Thread.NORM_PRIORITY) //線程池的數量 .denyCacheImageMultipleSizesInMemory() // 不同大小圖片只有一個緩存,默認多個 .tasksProcessingOrder(QueueProcessingType.LIFO) // 設置圖片下載和顯示的工作隊列排序 .discCache(new LimitedAgeDiscCache(new File(Constant.SAVE_IMG_PATH), new Md5FileNameGenerator(), 7 * 24 * 60 * 60)) // 7天自動清除,按秒算 // .writeDebugLogs() // Remove for release app .imageDownloader( //或許你的服務器有特定的加載圖的方式,在這裡實現 new BaseImageDownloader(ContextUtil.getInstance()) { @Override public InputStream getStream(String imageUri, Object extra) throws IOException { return super.getStream(imageUri, extra); } @Override protected InputStream getStreamFromNetwork( String imageUri, Object extra) throws IOException { HttpURLConnection conn = createConnection( imageUri, extra); int redirectCount = 0; while (conn.getResponseCode() / 100 == 3 && redirectCount < MAX_REDIRECT_COUNT) { conn = createConnection( conn.getHeaderField("Location"), extra); redirectCount++; } InputStream imageStream = null; try { imageStream = conn.getInputStream(); } catch (IOException e) { // Read all data to allow reuse connection // (http://bit.ly/1ad35PY) IoUtils.readAndCloseStream(conn .getErrorStream()); } return new ContentLengthInputStream( new BufferedInputStream(imageStream, BUFFER_SIZE), conn .getContentLength()); } }).build(); // Initialize ImageLoader with configuration. 初始化 ImageLoader.getInstance().init(config); } /** * @author Administrator 監聽讀取完圖片 */ private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { // 放到內存 static final ListdisplayedImages = Collections .synchronizedList(new LinkedList ()); @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { if (loadedImage != null) { ImageView imageView = (ImageView) view; boolean firstDisplay = !displayedImages.contains(imageUri); if (firstDisplay) { FadeInBitmapDisplayer.animate(imageView, 500); displayedImages.add(imageUri); } } } } }
因為我不想要自動幫我加密文件,所以我.disCache() 裡面的加密方法 new Md5FileNameGenerator()
換成了
new FileNameGenerator() { @Override public String generate(String imageUri) { return FileUtil.getFileName(imageUri); } }
new BaseImageDownloader(ContextUtil.getInstance()) { @Override public InputStream getStream(String imageUri, Object extra) throws IOException { return super.getStream(imageUri, extra); } @Override protected InputStream getStreamFromNetwork( String imageUri, Object extra) throws IOException { HttpURLConnection conn = createConnection( imageUri, extra); int redirectCount = 0; while (conn.getResponseCode() / 100 == 3 && redirectCount < MAX_REDIRECT_COUNT) { conn = createConnection( conn.getHeaderField("Location"), extra); redirectCount++; } InputStream imageStream = null; try { imageStream = conn.getInputStream(); } catch (IOException e) { // Read all data to allow reuse connection // (http://bit.ly/1ad35PY) IoUtils.readAndCloseStream(conn .getErrorStream()); } return new ContentLengthInputStream( new BufferedInputStream(imageStream, BUFFER_SIZE), conn .getContentLength()); } }
總結: universal-image-loader 這個開源項目很好用,
研究了一下源碼,有很多啟發,擴展性很好,值得我們學習
官方提供的例子: universal-image-loader例子
1、rk3168_v4.2\frameworks\base\data\videos下面的mp4的拷貝方法! a、其實在我們的原始情況下這個目錄的東西並沒有拷貝到xxx/s
本章內容 第1節 SQLite數據庫概述 第2節 SQLite建庫建表 第3節管理數據庫連接 第4節 操作數據庫數據 第5節 數據綁定本章目標 掌握SQLite數據的基本
在最近的兩個項目中,項目需求要求我們實現 /*登陸頁面的內容能夠隨著鍵盤的彈出而被頂上去,避免鍵盤遮擋住登陸按鈕*/ 這樣的效果,寶寶心裡苦呀,本來半天搞定的事還非得折騰
我們在應用中經常看到一些選擇開關狀態的配置文件,做項目的時候用的是android的Switch控件,但是感覺好丑的樣子子個人認為還是自定義的比較好,先上個效果圖:實現過程