Android使用缓存来保存图像

时间:2011-08-03 13:27:19

标签: android image caching

基本思想是:我从互联网下载加密图像文件并开始解密。

完成后我想将它保存到缓存中(如果这是我需要的最佳方式),而不是在延迟加载列表视图中加载它。

但是现在我只想在ImageView中解密后测试显示图像。

以下是我正在使用的代码:

package com.android.basetableview;

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 javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.ImageView;

public class BaseTableViewActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        ImageView imgView = (ImageView) findViewById(R.id.imgView);

        Bitmap myBitmap = getBitmapFromURL("http://pu-twitter.netau.net/card1.png");
        imgView.setImageBitmap(myBitmap);
    }


    public static Bitmap getBitmapFromURL(String src) {
        Bitmap myBitmap = null;
            try {

                URL url = new URL(src);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();

                //Decryption
                try {
                Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
                SecretKeySpec keySpec = new SecretKeySpec("01234567890abcde".getBytes(), "AES");
                IvParameterSpec ivSpec = new IvParameterSpec("fedcba9876543210".getBytes());
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

                InputStream input = connection.getInputStream();
                CipherInputStream cis = new CipherInputStream(input, cipher);
                FileOutputStream fos  = new FileOutputStream(
                           new File(Environment.getExternalStorageDirectory(), "card2_decrypted.jpg"));
                byte[] b = new byte[8];
                int i;

                while ((i = cis.read(b)) != -1) {
                  fos.write(b, 0, i);
                }
                fos.flush(); fos.close();
                cis.close(); input.close();


                //myBitmap = BitmapFactory.decodeStream(input);

                }
                catch(Exception e){
                    e.fillInStackTrace();
                    Log.v("ERROR","Errorchence : "+e);
                }

                return myBitmap;


            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
}

正如您所看到的,我将解密的图像保存在SD卡中,但我使用的图像很小,可能缓存也是更好的选择。所以,如果你们可以给我一些建议,我该怎么做呢?哪种是保存图像然后在ImageView中将它们显示为内容的最佳方式。

2 个答案:

答案 0 :(得分:1)

好的,你不需要保存图像:

    public static Bitmap getBitmapFromURL(String src) {
        Bitmap myBitmap = null;
            try {

                URL url = new URL(src);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();

                //Decryption
                try {
                Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
                SecretKeySpec keySpec = new SecretKeySpec("01234567890abcde".getBytes(), "AES");
                IvParameterSpec ivSpec = new IvParameterSpec("fedcba9876543210".getBytes());
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

                InputStream input = connection.getInputStream();
                CipherInputStream cis = new CipherInputStream(input, cipher);


                myBitmap = BitmapFactory.decodeStream(cis);

                }
                catch(Exception e){
                    e.fillInStackTrace();
                    Log.v("ERROR","Errorchence : "+e);
                }

                return myBitmap;


            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
}

答案 1 :(得分:0)

您需要使用ImageView来显示图像。第二,imageview可以接受位图,资源或URI。但是位图是最好的,因为使用uri和资源意味着在放置之前对图像进行解码会发生在ui线程中,这对图像来说不是一件好事。

用于设置图像位图,在布局中获取对imageview的引用并使用

myImageView.setImageBitmap(myImageBitmap);

从SD卡获取图像位图可以使用BitmapFactory.decodeFile();例如,功能。我通常直接从互联网流中将图像解码为位图,然后将位图保存为SD上的文件。我认为这是一个更好的解决方案。

File f = new File(cacheDir, filename);
        OutputStream outStream = new FileOutputStream(f);
        Bitmap bmp;
        bmp = BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
        bmp.compress(Bitmap.CompressFormat.PNG, 90, outStream);

我正在使用函数刷新的输入流,因为url连接中存在错误。见this link

对于缓存,你绝对可以使用sdcard。它比使用手机内存要好得多(即手机上的缓存目录填充手机内存),你可以通过删除缓存文件夹onDestroy()中的所有图像来清除sd缓存。这很简单。如果您喜欢内存缓存,则使用hashMap,weakReference或softReference映射。我建议使用hashMap进行更长时间的存储,但要注意内存消耗。

用于“延迟加载”图片see this link