美文网首页
Android加载网络图片入门<一>

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

作者: MarsX11 | 来源:发表于2019-04-15 10:36 被阅读0次

    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.效果预览

    20190414100022.jpg

    4图片占用内存

    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<Runnable>(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 <Runnable> taskQueue = new LinkedBlockingQueue <Runnable>();
    private  LruCache <String, Bitmap> mCaches;
    private static ExecutorService executorService;
    private static ImageLoaderUtils imageLoaderUtils;
    
    private DiskLruCache diskLruCache;
    
    private ImageLoaderUtils(Context context){
        mCaches = new LruCache<String, Bitmap>(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<Runnable>(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<bytes.length;i++){
            String hex=Integer.toHexString(0xFF & bytes[i]);
            if(hex.length()==1){
                stringBuilder.append('0');
            }
            stringBuilder.append(hex);
        }
        return stringBuilder.toString();}
    
    
    /**
     * @param context
     * @param uniqueName
     * @return
     *         当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,否则就调用getCacheDir
     *         ()方法来获取缓存路径。 前者获取到的就是 /sdcard/Android/data/<application
     *         package>/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加载网络图片入门<一>

          本文链接:https://www.haomeiwen.com/subject/pbljwqtx.html