Android解决网络加载大图片OOM的问题
发布日期:2021-06-29 11:46:10 浏览次数:3 分类:技术文章

本文共 5104 字,大约阅读时间需要 17 分钟。

首先我们要获取网络上的图片,这里我们使用AndroidAPI中的HttpUrlConnection,具体代码如下:

private HttpURLConnection getHttpURLConnection(String imgUrl)throws Exception{    URL url=new URL(imgUrl);    HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection();    httpURLConnection.setConnectTimeout(10000);    httpURLConnection.setRequestMethod("GET");    httpURLConnection.setRequestProperty("Accept-Language","zh-CN,zh;q=0.9");    httpURLConnection.setRequestProperty("Accept","*/*");    return httpURLConnection;}

类中的其他方法获取HttpUrlConnection并开启连接:

HttpURLConnection httpURLConnection=getHttpURLConnection(imgUrl);httpURLConnection.connect();

获取图片输入流:

InputStream inputStream=httpURLConnection.getInputStream();BufferedInputStream buffInputStream = new BufferedInputStream(inputStream);

在这里,我们解决图片OOM问题的方法是设置图片采样时的样本大小,即sampleSize。

这里打个比方,假如网络图片的宽高是1920*1080,这里我们设置样本大小sampleSize=n,那么网络图片的宽高都会除以n倍,即网络图片的宽高变为:(1920/n)*(1080/n)。通过这个方法,我们就可以将图片压缩来解决OOM的问题。

当然,sampleSize不应该被设置成固定值,我们应该让他按照原控件的大小来缩放相应的比例

假设我们用ImageView来存放图片,ImageView(img)宽高分别为800*600,网络图片(netImg)宽高分别为1920*1080,那么sampleSize的值就应该是两者宽的比和高的比取其中更大的那个比值

即:sampleSize=max( netImg.width / img.width , netImg.height / img.height )

具体代码如下:

private int getBitmapSampleSize(BitmapFactory.Options options,int measuredWidth,int measuredHeight){    int outWidth=options.outWidth;    int outHeight=options.outHeight;    int sampleSize=1;    //原图要大于控件大小,不然就没有必要压缩    if(outHeight>measuredHeight||outWidth>measuredWidth){        int btHeight=outHeight/measuredHeight;        int btWidth=outWidth/measuredWidth;        sampleSize=btHeight>btWidth?btHeight:btWidth;    }    return sampleSize;}

下面贴出完整代码:

public class NetImageActivity extends AppCompatActivity{    private ImageView img;    private String imgUrl="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1586846404773&di=38a80a02ad991f77c610c52c661241d2&imgtype=0&src=http%3A%2F%2Fwww.baiyunshan.org.cn%2Fd%2Ffile%2Fnews%2Fgame%2F20190926%2Fcfd02160c79deeb5ce2f71c4b175b43a.jpg";    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.net_image_layout);        initView();        loadImg();    }    private void initView(){        img=findViewById(R.id.img);    }    private void loadImg(){        new Thread(new Runnable() {            @Override            public void run() {                try {                    HttpURLConnection httpURLConnection=getHttpURLConnection(imgUrl);                    httpURLConnection.connect();                    int responseCode=httpURLConnection.getResponseCode();                    if(responseCode==HttpURLConnection.HTTP_OK){                        InputStream inputStream=httpURLConnection.getInputStream();                        BufferedInputStream buffInputStream = new BufferedInputStream(inputStream);                        BitmapFactory.Options options=new BitmapFactory.Options();                        //不加载图片到内存                        options.inJustDecodeBounds=true;                        //对buffInputStream进行重复利用                        buffInputStream.mark(0);                        BitmapFactory.decodeStream(buffInputStream,null,options);                        buffInputStream.reset();                        options.inSampleSize=getBitmapSampleSize(options,img.getMeasuredWidth(),img.getMeasuredHeight());                        //这里要设为false,否则图片无法加载到内存                        options.inJustDecodeBounds=false;                        final Bitmap bitmap=BitmapFactory.decodeStream(buffInputStream,null,options);                        buffInputStream.close();                        inputStream.close();                        runOnUiThread(new Runnable() {                            @Override                            public void run() {                                img.setImageBitmap(bitmap);                            }                        });                    }                    httpURLConnection.disconnect();                } catch (Exception e) {                    e.printStackTrace();                }            }        }).start();    }    private HttpURLConnection getHttpURLConnection(String imgUrl)throws Exception{        URL url=new URL(imgUrl);        HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection();        httpURLConnection.setConnectTimeout(10000);        httpURLConnection.setRequestMethod("GET");        httpURLConnection.setRequestProperty("Accept-Language","zh-CN,zh;q=0.9");        httpURLConnection.setRequestProperty("Accept","*/*");        return httpURLConnection;    }    private int getBitmapSampleSize(BitmapFactory.Options options,int measuredWidth,int measuredHeight){        int outWidth=options.outWidth;        int outHeight=options.outHeight;        int sampleSize=1;        //原图要大于控件大小,不然就没有必要压缩        if(outHeight>measuredHeight||outWidth>measuredWidth){            int btHeight=outHeight/measuredHeight;            int btWidth=outWidth/measuredWidth;            sampleSize=btHeight>btWidth?btHeight:btWidth;        }        return sampleSize;    }}

 

转载地址:https://blog.csdn.net/zz51233273/article/details/105509676 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:设计模式之单例模式
下一篇:git上传代码到远程仓库的命令行步骤

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月09日 00时31分27秒