android 网络图片异步加载
2015-12-24 16:35
459 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ws_daydayup/article/details/50395379
原理:
1.通过URL下载网络图片
2.创建异步类AsyncTask执行异步操作
3.将图片写入内存或缓存
4.通知UI更新
重点:
1.使用LruCache缓存Bitmap
2.将图片写入本地下次调用无需下载
3.使用Set集合管理下载任务
4.重写滑动监听实现同步下载
注:详细请看注释
1.图片加载类
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Environment; import android.util.Log; import android.util.LruCache; import android.widget.GridView; import android.widget.ImageView; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashSet; import java.util.Set; public class LoaderImage { //图片缓存空间 private LruCache<String, Bitmap> mLruCache; private GridView mGridView; //下载任务管理集合 private Set<NewAsyncTask> mTask; public LoaderImage(GridView gridView) { mGridView = gridView; mTask = new HashSet<>(); //为LruCache初始化空间(系统内存的1/8) int maxMemory = (int) Runtime.getRuntime().maxMemory(); int cacheMemory = maxMemory / 8; mLruCache = new LruCache<String, Bitmap>(cacheMemory) { @Override protected int sizeOf(String key, Bitmap value) { //每个Bitmap所占内存 return value.getRowBytes() * value.getHeight(); } }; } private void addBitmapToLruCache(String path, Bitmap bm) { if (mLruCache.get(path) == null) { if (bm != null) { mLruCache.put(path, bm); } } } public Bitmap getBitmapByURL(String path) { Log.d("getBitmapByURL", "--- " + path); URL myFileURL; Bitmap bitmap = null; try { myFileURL = new URL(path); HttpURLConnection conn = (HttpURLConnection) myFileURL.openConnection(); conn.setConnectTimeout(6000); //连接设置获得数据流 conn.setDoInput(true); //不使用缓存 conn.setUseCaches(false); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (Exception e) { e.printStackTrace(); } return bitmap; } //从LruCache中获取图片 public void showImageByAsyncTask(ImageView imageView, String path) { Bitmap bm = mLruCache.get(path); if (bm != null) { imageView.setImageBitmap(bm); } else { //自定义未加载完成时的图片 imageView.setImageResource(R.mipmap.ic_launcher); } } //将当前屏幕的图片加入下载任务 public void loadImages(int mStart, int mEnd) { for (int i = mStart; i < mEnd; i++) { //ImageYL.Urls[i] String path = ImageYL.Urls[i]; Bitmap bm = mLruCache.get(path); if (bm == null) { NewAsyncTask task = new NewAsyncTask(path); task.execute(path); mTask.add(task); } else { ImageView imageView = (ImageView) mGridView.findViewWithTag(path); imageView.setImageBitmap(bm); } } } //用户滑动时取消下载 public void cancleAllTasks() { if (mTask != null) { for (NewAsyncTask task : mTask) { task.cancel(false); } } } //图片异步下载类 private class NewAsyncTask extends AsyncTask<String, Void, Bitmap> { private String mPath; public NewAsyncTask(String path) { mPath = path; } @Override protected Bitmap doInBackground(String... params) { Bitmap bm = null; //判断SD卡是否存在(下载图片到本地/仅缓存) if (ExistSDCard()) { String path = downloadPic(params[0]); //压缩图片 bm = ImageUtil.decodeSampledBitmapFromPath(path); } else { bm = getBitmapByURL(params[0]); } if (bm != null) { addBitmapToLruCache(mPath, bm); } return bm; } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); ImageView imageView = (ImageView) mGridView.findViewWithTag(mPath); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } mTask.remove(this); } } //判断有木有SD卡 private boolean ExistSDCard() { if (android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) { return true; } else return false; } //图片保存到本地 public String downloadPic(String relativePath) { String filePath = null; URL picUrl; HttpURLConnection conn = null; InputStream fileIn = null; BufferedOutputStream fileOut = null; try { filePath = Environment.getExternalStorageDirectory() + File.separator + relativePath; File picFile = new File(filePath); if (picFile.exists()) { return filePath; } File dir = new File(picFile.getParent()); if (!dir.isDirectory() || !dir.exists()) { dir.mkdirs(); } Log.d("--", "downloadPic,dir:" + dir.getAbsolutePath() + ",picFile:" + picFile.getAbsolutePath()); picFile.createNewFile(); picUrl = new URL(relativePath); conn = (HttpURLConnection) picUrl.openConnection(); fileIn = conn.getInputStream(); fileOut = new BufferedOutputStream( new FileOutputStream(picFile)); byte[] buf = new byte[1024]; int r = 0, all = 0; while ((r = fileIn.read(buf)) > 0) { fileOut.write(buf, 0, r); all += r; } Log.d("--", "read file : " + relativePath + ",len: " + all); fileOut.close(); fileIn.close(); } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } finally { if (fileIn != null) { try { fileIn.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileOut != null) { try { fileOut.close(); } catch (IOException e) { e.printStackTrace(); } } if (conn != null) { conn.disconnect(); } } return filePath; } }
2.图片压缩类
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; public class ImageUtil { //图片压缩(默认分辨率720*1280) public static Bitmap decodeSampledBitmapFromPath(String path) { BitmapFactory.Options options=new BitmapFactory.Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeFile(path, options); options.inSampleSize=caculateInSampleSize(options,720f,1280f); options.inJustDecodeBounds=false; Bitmap bm=BitmapFactory.decodeFile(path,options); return bm; } //获取压缩比例 public static int caculateInSampleSize(BitmapFactory.Options options, float reqWidth, float reqHeight) { int width=options.outWidth; int height=options.outHeight; int inSampleSize=1; if(width>reqWidth||height>reqHeight){ int widthRadio=Math.round(width*1.0f/reqWidth); int heightRadio=Math.round(height*1.0f/reqHeight); inSampleSize=Math.max(widthRadio,heightRadio); } return inSampleSize; }}
3.重写适配器
private class GridViewAdapter extends BaseAdapter implements AbsListView.OnScrollListener { private int mStart, mEnd; private boolean mFristin; public GridViewAdapter(GridView gridView) { loaderImage = new LoaderImage(gridView); mFristin = true; gridView.setOnScrollListener(this); } @Override public int getCount() { return image_path.size(); } @Override public String getItem(int position) { return image_path.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.layout.item_grid, null); holder = new ViewHolder(); holder.imageView = (ImageView) convertView.findViewById(R.id.id_ima); holder.textView = (TextView) convertView.findViewById(R.id.id_text); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } String path = image_path.get(position); holder.imageView.setTag(path); loaderImage.showImageByAsyncTask(holder.imageView, path); return convertView; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //根据用户滑动来决定是否加载图片 if (scrollState == SCROLL_STATE_IDLE) { loaderImage.loadImages(mStart, mEnd); } else { loaderImage.cancleAllTasks(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { mStart = firstVisibleItem; mEnd = firstVisibleItem + visibleItemCount; //第一次打开加载当前界面图片 if (mFristin && visibleItemCount > 0) { loaderImage.loadImages(mStart, mEnd); mFristin = false; } } }
相关文章推荐
- Android:ListView异步加载图片(实现网络下载、存储本地、缓存内存、压缩显示)
- Android:ViewPager详解(异步网络加载图片,带图片缓存,并带导航小圆点)
- Android网络图片异步加载实例
- Android 异步加载网络图片并缓存到本地 软引用 学习分享
- android异步加载网络图片(1)
- Android异步加载访问网络图片-解析json
- Android之ListView异步加载网络图片(优化缓存机制)【转】
- Android之ListView异步加载网络图片(优化缓存机制) .
- Android从网络上 异步加载图片
- Android异步加载网络图片
- 在Android的应用中实现网络图片异步加载的方法
- Android网络图片异步加载
- android 网络图片的异步加载 ListView
- android textView 加载HTML 异步加载网络图片
- wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)
- android开发---ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)
- Android异步加载网络图片
- 深入剖析Android之ListView从网络异步加载图片
- Android异步从网络加载图片BitmapFactory.decodeStream 返回null的问题
- 【Android】异步加载网络图片!!!!