zoukankan      html  css  js  c++  java
  • 分享一个安卓中异步获取网络图片并自适应大小的第三方程序(来自github)

    安卓中获取网络图片,生成缓存

      用安卓手机,因为手机流量的限制,所以我们在做应用时,要尽量为用户考虑,尽量少耗点用户的流量,而在应用中网络图片的显示无疑是消耗流量最大的,所以我们可以采取压缩图片或者将图片进行缓存,使图片只需要获取一次即可。

    获取网络图片,并进行压缩

    public static Bitmap returnBitMapWego(String url) {
            URL myFileUrl = null;
            Bitmap bitmap = null;
            try {
                myFileUrl = new URL(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            try {
                HttpURLConnection conn = (HttpURLConnection) myFileUrl
                        .openConnection();
                conn.setDoInput(true);
                conn.connect();
                InputStream is = conn.getInputStream();
                Options op = new Options();
                op.inSampleSize = 2;//压缩的倍数
                op.inJustDecodeBounds = false;
                Rect rect = new Rect(0, 0, 0, 0);
                bitmap = BitmapFactory.decodeStream(is, rect, op);
                is.close();
            } catch (IOException e) {
                // e.printStackTrace();
                bitmap = null;
    
            }
            return bitmap;
        }

    异步获取网络图片并进行缓存

    package com.jijie.yibu;
    
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.lang.ref.SoftReference;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.drawable.BitmapDrawable;
    import android.net.ConnectivityManager;
    import android.os.Environment;
    import android.os.Handler;
    import android.os.Message;
    import android.widget.ImageView;
    
    public class LogoLoader {
    
        public static final String CACHE_DIR = "/图片在手机中的保存路径";
        // 缓存下载过的图片的Map
        private Map<String, SoftReference<Bitmap>> caches;
        // 任务队列
        private List<Task> taskQueue;
        private boolean isRunning = false;
        private int width, height;
        private Context ctx;
    
        public LogoLoader(Context ctx) {this.ctx = ctx;
            // 初始化变量
            caches = new HashMap<String, SoftReference<Bitmap>>();
            taskQueue = new ArrayList<LogoLoader.Task>();
            // 启动图片下载线程
            isRunning = true;
            new Thread(runnable).start();
        }
    
        /**
         * 
         * @param imageView
         *            需要延迟加载图片的对象
         * @param url
         *            图片的URL地址
         * @param resId
         *            图片加载过程中显示的图片资源
         */
        public void showImageAsyn(ImageView imageView, String url, int resId) {
            imageView.setTag(url);
            Bitmap bitmap = loadImageAsyn(url, getImageCallback(imageView, resId));
    
            if (bitmap == null) {
                // imageView.setImageResource(resId);
                // imageView.setBackgroundResource(resId);
            } else {
                // imageView.setImageBitmap(bitmap);
                BitmapDrawable bd = new BitmapDrawable(bitmap);
                imageView.setBackgroundDrawable(bd);
            }
        }
    
        public Bitmap loadImageAsyn(String path, ImageCallback callback) {
            // 判断缓存中是否已经存在该图片
            if (caches.containsKey(path)) {
                // 取出软引用
                SoftReference<Bitmap> rf = caches.get(path);
                // 通过软引用,获取图片
                Bitmap bitmap = rf.get();
                // 如果该图片已经被释放,则将该path对应的键从Map中移除掉
                if (bitmap == null) {
                    caches.remove(path);
                } else {
                    // 如果图片未被释放,直接返回该图片
    
                    return bitmap;
                }
            } else {
                // 如果缓存中不常在该图片,则创建图片下载任务
                Task task = new Task();
                task.path = path;
                task.callback = callback;
    
                if (!taskQueue.contains(task)) {
                    taskQueue.add(task);
                    // 唤醒任务下载队列
                    synchronized (runnable) {
                        runnable.notify();
                    }
                }
            }
    
            // 缓存中没有图片则返回null
            return null;
        }
    
        /**
         * 
         * @param imageView
         * @param resId
         *            图片加载完成前显示的图片资源ID
         * @return
         */
        private ImageCallback getImageCallback(final ImageView imageView,
                final int resId) {
            return new ImageCallback() {
    
                public void loadImage(String path, Bitmap bitmap) {
                    if (path.equals(imageView.getTag().toString())) {
                        // imageView.setImageBitmap(bitmap);
                        BitmapDrawable bd = new BitmapDrawable(bitmap);
                        imageView.setBackgroundDrawable(bd);
    
                    } else {
                        // imageView.setImageResource(resId);
                        // imageView.setBackgroundResource(resId);
                    }
                }
            };
        }
    
        private Handler handler = new Handler() {
    
            @Override
            public void handleMessage(Message msg) {
                // 子线程中返回的下载完成的任务
                Task task = (Task) msg.obj;
                // 调用callback对象的loadImage方法,并将图片路径和图片回传给adapter
                task.callback.loadImage(task.path, task.bitmap);
            }
    
        };
    
        private Runnable runnable = new Runnable() {
    
            public void run() {
                while (isRunning) {
                    // 当队列中还有未处理的任务时,执行下载任务
                    while (taskQueue.size() > 0) {
                        // 获取第一个任务,并将之从任务队列中删除
                        Task task = taskQueue.remove(0);
                        // 将下载的图片添加到缓存
    
                        if (Environment.getExternalStorageState().equals(
                                Environment.MEDIA_MOUNTED)
                                && !checkNetWorkStatus()) {
                            File file = new File("/mnt/sdcard/jijie/imagecache/"
                                    + getFileName(task.path));
                            if (file.exists() && file.length() > 100) {
    
                                try {
                                    task.bitmap = PicUtil
                                            .getRoundedCornerBitmap(
                                                    BitmapFactory
                                                            .decodeFile("/mnt/sdcard/jijie/imagecache/"
                                                                    + getFileName(task.path)),
                                                    10);
    
                                } catch (OutOfMemoryError err) {
                                }
                            }
                        } else if (checkNetWorkStatus()) {
    
                            task.bitmap = PicUtil.getRoundedCornerBitmap(
                                    PicUtil.returnBitMap(task.path), 10);
                            try {
                                ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
                                task.bitmap.compress(Bitmap.CompressFormat.PNG,
                                        100, baos);
    
                                Write(task.path, baos.toByteArray());
                            } catch (Exception e) {
    
                            }
    
                        }
    
                        // task.bitmap=PicUtil.getbitmapAndwrite(task.path);
                        // caches.put(task.path, new
                        // SoftReference<Bitmap>(task.bitmap));
                        if (handler != null) {
                            // 创建消息对象,并将完成的任务添加到消息对象中
                            Message msg = handler.obtainMessage();
                            msg.obj = task;
                            // 发送消息回主线程
                            handler.sendMessage(msg);
                        }
                    }
    
                    // 如果队列为空,则令线程等待
                    synchronized (this) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
    
        // 回调接口
        public interface ImageCallback {
            void loadImage(String path, Bitmap bitmap);
        }
    
        class Task {
            // 下载任务的下载路径
            String path;
            // 下载的图片
            Bitmap bitmap;
            // 回调对象
            ImageCallback callback;
    
            @Override
            public boolean equals(Object o) {
                Task task = (Task) o;
                return task.path.equals(path);
            }
        }
    
        public void Write(String imageurl, byte[] b) {
            File cacheFile = FileUtil.getCacheFile(imageurl);
    
            BufferedOutputStream bos = null;
            try {
                bos = new BufferedOutputStream(new FileOutputStream(cacheFile));
    
                bos.write(b, 0, b.length);
                bos.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        public static String getFileName(String path) {
            int index = path.lastIndexOf("/");
            return path.substring(index + 1);
        }
    
        private boolean checkNetWorkStatus() {
            boolean netSataus = false;
            ConnectivityManager cwjManager = (ConnectivityManager) ctx
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            cwjManager.getActiveNetworkInfo();
            if (cwjManager.getActiveNetworkInfo() != null) {
                netSataus = cwjManager.getActiveNetworkInfo().isAvailable();
            }
            return netSataus;
        }
    }

      经过上面的代码虽然能够实现了图片的异步获取,自动缓存读取,图片压缩的功能,但是处理图片使图片适应控件大小还是比较让人头疼的问题,还有就是如果一起获取大量的网络的图片,会占用的非常多的内存,而且系统默认自由在界面销毁的时候才会释放,所以很容易遇到内存溢出的问题,下面向大家分享一个我在github上看到的一个处理网络的图片的程序。

    能够实现异步获取图片,自动缓存读取,自动适应空间大小,而且完美解决内存溢出的问题

    下面向大家展示一下:

    以集街网(www.jijie.cc)中的一个图片为例,原图为:

    <con.standopen.view.NetworkedCacheableImageView
            android:id="@+id/nciv_pug"
            android:layout_width="fill_parent"
            android:layout_height="100dip"
            android:scaleType="centerCrop" />

     <con.standopen.view.NetworkedCacheableImageView
            android:id="@+id/nciv_pug"
            android:layout_width="fill_parent"
            android:layout_height="300dip"
            android:scaleType="centerCrop" />

      <con.standopen.view.NetworkedCacheableImageView
            android:id="@+id/nciv_pug"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="centerCrop" />

      这分别是在不同大小的空间中显示同一张图片,能够看出来,代码只是将图片进行了剪切处理,避免拉伸变形,程序异步获取和自动缓存就不展示了,大家看代码就行的了。

    工程文件(百度网盘):http://pan.baidu.com/s/1mguh2qc

    github:https://github.com/yimengqingqiu/Android-Universal-Image-Loader

    个人邮箱:standopen@foxmail.com(也可以发邮件给我索取)

  • 相关阅读:
    持久化 XSS:ServiceWorkers 利用
    preg_replace引发的phpmyadmin(4.3.0-4.6.2)命令执行漏洞
    seacms6.5 注入漏洞1
    渗透中常见的网络端口
    composer安装指定版本的ThinkPHP
    php-fpm以root权限运行
    ntp网络时间服务器地址
    查看*.dll文件是32位还是64位的方法
    从经典案例学习SSRF漏洞的产生原因和修复方法
    Apache将AllowOverride设置为All以后出现403 Forbidden的解决方法
  • 原文地址:https://www.cnblogs.com/standopen/p/3494818.html
Copyright © 2011-2022 走看看