Android加载网络图片入门<一>

1.加载网络图片的方法

public Bitmap getImageBitmap(String url) {
    Bitmap bitmap =null ;
    try {
        URL imgUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) imgUrl
                .openConnection();

        conn.connect();
        InputStream is = conn.getInputStream();
        bitmap = BitmapFactory.decodeStream(is);
        is.close();
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bitmap;
}

2.主线程调用

new Thread(new Runnable() {
        @Override
        public void run() {
            final Bitmap bitmap=getImageBitmap(imageUrl);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    iv_glide.setImageBitmap(bitmap);
                }
            });
        }
    }).start();

3.效果预览

Android加载网络图片入门<一>_第1张图片
20190414100022.jpg

4图片占用内存

Android加载网络图片入门<一>_第2张图片
20190414101737.jpg

图片实际大小4M

当前存在的问题

  • 没有线程管理
  • 复用不方便
  • 没有使用缓存机制,每次加载都从网络获取,消耗用户流量和加载慢
    +图片占用空间还有优化的空间
    +关闭输入输出流

优化调用

public static void getImageBitmap(final String url, final ImageView imageView, final Context context) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            final Bitmap bitmap ;
            InputStream is=null;
            try {
                URL imgUrl = new URL(url);
                HttpURLConnection conn = (HttpURLConnection) imgUrl
                        .openConnection();
                conn.connect();
                is = conn.getInputStream();

                bitmap = BitmapFactory.decodeStream(is);
                ((Activity)context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        imageView.setImageBitmap(bitmap);
                    }
                });

            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(is!=null){
                    try {
                        is.close();
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                }

            }


        }
    }).start();

}

新建一个工具类
ImageLoaderUtils.getImageBitmap(imageUrl,iv_glide,this);
直接调用

增加线程管理

   public static void getImageBitmap(final String url, final ImageView imageView, final Context context) {
  //  ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(5,7,60*1000,TimeUnit.SECONDS, new ArrayBlockingQueue(3));

    ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue);
    executorService.execute(new Runnable() {
        @Override
        public void run() {
            final Bitmap bitmap ;
            InputStream is=null;
            try {
                URL imgUrl = new URL(url);
                HttpURLConnection conn = (HttpURLConnection) imgUrl
                        .openConnection();
                conn.connect();
                is = conn.getInputStream();

                bitmap = BitmapFactory.decodeStream(is);
                ((Activity)context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        imageView.setImageBitmap(bitmap);
                    }
                });

            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(is!=null){
                    try {
                        is.close();
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                }

            }



        }
    });

使用缓存
内存缓存和磁盘缓存

 public static int maxMemory = (int) (Runtime.getRuntime().maxMemory() /1024);
final int cacheSize = maxMemory / 8;
public static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
public static int KEEP_ALIVE_TIME = 1;
public static TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
public static BlockingQueue  taskQueue = new LinkedBlockingQueue ();
private  LruCache  mCaches;
private static ExecutorService executorService;
private static ImageLoaderUtils imageLoaderUtils;

private DiskLruCache diskLruCache;

private ImageLoaderUtils(Context context){
    mCaches = new LruCache(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap value) {
            //判断添加进入的value的占用内存的大小
            //这里默认sizeOf是返回1,不占用,内存会不够用,所以要给它一个具体占用内存的大小
            //                    return super.sizeOf(key, value);
            //获取Bitmap的大小
            System.out.println("value.getRowBytes() * value.getHeight()/1024=="+value.getRowBytes() * value.getHeight()/1024);
            return value.getRowBytes() * value.getHeight()/1024;
        }
    };

    /**
              * 初始化硬盘缓存DiskLruCahce
               */
           // 获取硬盘缓存路径,参数二为所在缓存路径的文件夹名称
           File directory = getDiskCacheDir(context, "bitmap");
            if (!directory.exists()) {
                    // 若文件夹不存在,建立文件夹
                     directory.mkdirs();
                }
             int appVersion = getAppVersion(context);
            try {
                     // 参数1:缓存文件路径,参数2:系统版本号,参数3:一个缓存路径对于几个文件,参数4:缓存空间大小:字节
                     diskLruCache = DiskLruCache.open(directory, appVersion, 1, 1024 * 1024 * 50);
                 } catch (IOException e) {
                     e.printStackTrace();
                }



    executorService = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES * 2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue);
}
public static ImageLoaderUtils getImageLoaderUtils(Context context){
    if(imageLoaderUtils==null) {
        imageLoaderUtils = new ImageLoaderUtils(context);
    }

    return imageLoaderUtils;
}


public  void getImageBitmap(final String url, final ImageView imageView, final Context context) {
    //  ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(5,7,60*1000,TimeUnit.SECONDS, new ArrayBlockingQueue(3));
    System.out.println("maxMemory===" + maxMemory);
    Bitmap bitmapCache = mCaches.get(url);
    if(bitmapCache!=null){
        imageView.setImageBitmap(bitmapCache);
        System.out.println("Memory=="+url);
        return;
    }
 try {
     String key = hashKeyFromUrl(url);
     DiskLruCache.Snapshot snapShot = diskLruCache.get(key);
     if (snapShot != null) {
         InputStream is = snapShot.getInputStream(0);
         Bitmap bitmap = BitmapFactory.decodeStream(is);
         System.out.println("diskLruCache==");
         imageView.setImageBitmap(bitmap);
         mCaches.put(url, bitmap);
         return;
     }

    
 }catch (Exception e){
        e.printStackTrace();
 }




    executorService.execute(new Runnable() {
        @Override
        public void run() {
            final Bitmap bitmap;
            InputStream is = null;
            try {
                URL imgUrl = new URL(url);
                HttpURLConnection conn = (HttpURLConnection) imgUrl
                        .openConnection();
                conn.connect();
                is = conn.getInputStream();

                bitmap = BitmapFactory.decodeStream(is);
                mCaches.put(url, bitmap);
               String key= hashKeyFromUrl(url);
                DiskLruCache.Editor editor = diskLruCache.edit(key);
                if (editor != null) {
                    OutputStream outputStream = editor.newOutputStream(0);
                    if (downloadUrlToStream(url, outputStream)) {
                        editor.commit();
                    } else {
                        editor.abort();
                    }
                }
                diskLruCache.flush();

                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        imageView.setImageBitmap(bitmap);
                    }
                });

            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }

            }


        }
    });}    
private String hashKeyFromUrl(String url){
    String cacheKey="";
    try {
        MessageDigest messageDigest=MessageDigest.getInstance("MD5");
        messageDigest.update(url.getBytes());
        cacheKey=bytesToHexString(messageDigest.digest());

    }
    catch (Exception e){
        e.printStackTrace();
    }


    return cacheKey;}
 private String bytesToHexString(byte[] bytes){
    StringBuilder stringBuilder=new StringBuilder();
    for (int i=0;i/cache 这个路径 而后者获取到的是 datadata/application package>/cache
 *         这个路径。
 */
public File getDiskCacheDir(Context context, String uniqueName) {
    String cachePath;
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
        cachePath = context.getExternalCacheDir().getPath();
    } else {
        cachePath = context.getCacheDir().getPath();
    }
    return new File(cachePath + File.separator + uniqueName);
}

/**
 * @param context
 * @return 获取系统版本号
 */
public int getAppVersion(Context context) {
    try {
        PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        return info.versionCode;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return 1;
}



private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
    HttpURLConnection urlConnection = null;
    BufferedOutputStream out = null;
    BufferedInputStream in = null;
    try {
        final URL url = new URL(urlString);
        urlConnection = (HttpURLConnection) url.openConnection();
        in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
        out = new BufferedOutputStream(outputStream, 8 * 1024);
        int b;
        while ((b = in.read()) != -1) {
            out.write(b);
        }
        return true;
    } catch (final IOException e) {
        e.printStackTrace();
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
        try {
            if (out != null) {
                out.close();
            }
            if (in != null) {
                in.close();
            }
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }
    return false;
}

还有遗留的问题

  • 图片压缩
  • 同一网址图片资源发生变化后
  • 多线程

图片压缩

你可能感兴趣的:(Android加载网络图片入门<一>)