Android动态图片加载

时间:2012-04-03 07:43:31

标签: android database image lazy-loading dynamic-data

我正在研究使用JSON从互联网上获取内容的Android应用程序,我使用服务在本地数据库中加载JSON,我有两个主要的疑问:

1-如何告诉应用程序数据库加载了新数据以重新加载显示。

2-我在DB中存储了需要显示的图像URL,为了显示我已经使用progressBar和Image视图扩展了默认的FrameLayout,如果Image不是,则新的Frame Layout将显示progressBar加载,如果图像被加载,它将被显示,而且新的FreamLayout有一个扩展AsyncTask的类,它接受URL检查文件系统上存在Image,如果它不存在,则发生图像下载。下面是我所做的课程的样本。这是正确的做法吗?在这种情况下,我有一些图像在下载时被破坏,如何克服这个问题?

感谢您的帮助。

    public class ImageLoader extends FrameLayout
    {
private String imageURL;
private ImageView img;
private ProgressBar pb;
private boolean isLoaded;
File rootDir = new File("/data/data/com.ait.kw.pharmacy/files");
private static final String TAG = "FrameLayoutExpander";

    //defining file name and url
    public String fileName = "";
    public String fileURL = "";

public ImageLoader(Context context , AttributeSet attr) {
    super(context,attr);
    isLoaded = false;
    img = new ImageView(context , null);
    pb = new ProgressBar(context,null , android.R.attr.progressBarStyle);
    img.setVisibility(View.INVISIBLE);
    pb.setVisibility(View.VISIBLE);
    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
            LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    super.addView(img,params);
    super.addView(pb,params);
    checkAndCreateDirectory("/images");

}

public ImageLoader(Context context, AttributeSet attr, int defaultStyle)
{
    super(context, attr, defaultStyle);
    isLoaded = false;
    img = new ImageView(context , null);
    pb = new ProgressBar(context,null , android.R.attr.progressBarStyle);
    img.setVisibility(View.INVISIBLE);
    pb.setVisibility(View.VISIBLE);
    super.addView(img);
    super.addView(pb);
    checkAndCreateDirectory("/images");
    isLoaded = checkImaeExists(rootDir.getAbsolutePath()+"/images/"+fileName);
  }
public void setImageResource(int resId) {
    pb.setVisibility(View.GONE);
    img.setVisibility(View.VISIBLE);
    img.setImageResource(resId);
  }

public void setImageDrawable(Drawable drawable) {
    pb.setVisibility(View.GONE);
    img.setVisibility(View.VISIBLE);
    img.setImageDrawable(drawable);
  }

public void startLoad(String url)
{
    setImageURL(url);
    loadImage();
}

public void setImageURL(String url)
{
    imageURL = url;
    fileName = imageURL.substring(imageURL.lastIndexOf("/")+1);
    isLoaded = checkImaeExists(rootDir.getAbsolutePath()+"/images/"+fileName);
}
public void loadImage() 
{
    if(! isLoaded)
    {
        DownloadFileAsync d = new DownloadFileAsync();
        d.execute(imageURL);
    }
    else
    {
        Drawable d = Drawable.createFromPath(rootDir + "/images/" + fileName);
        setImageDrawable(d);
    }
}
//this is our download file asynctask
class DownloadFileAsync extends AsyncTask<String, String, String> {


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }


    @Override
    protected String doInBackground(String... aurl) {

        try {
            //connecting to url
            URL u = new URL(imageURL);
            HttpURLConnection c = (HttpURLConnection) u.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            //lenghtOfFile is used for calculating download progress
            int lenghtOfFile = c.getContentLength();

            //this is where the file will be seen after the download
            FileOutputStream f = new FileOutputStream(new File(rootDir + "/images/", fileName));
            //file input is from the url
            InputStream in = c.getInputStream();

            //here's the download code
            byte[] buffer = new byte[1024];
            int len1 = 0;
            long total = 0;

            while ((len1 = in.read(buffer)) > 0) {
                total += len1; //total = total + len1
                publishProgress("" + (int)((total*100)/lenghtOfFile));
                f.write(buffer, 0, len1);
            }
            f.close();

        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
        }

        return null;
    }

    @Override
    protected void onPostExecute(String unused) 
    {
        //dismiss the dialog after the file was downloaded
        isLoaded = true;
        Drawable d = Drawable.createFromPath(rootDir + "/images/" + fileName);
        setImageDrawable(d);
    }
}

//function to verify if directory exists
public void checkAndCreateDirectory(String dirName){
    File new_dir = new File( rootDir + dirName );
    if( !new_dir.exists() ){
        new_dir.mkdirs();
    }
}

public boolean checkImaeExists(String filename)
{
    File file = new File(filename);

    return file.exists();

}
}

2 个答案:

答案 0 :(得分:0)

第一个问题

  • 您可以从正在使用的服务中广播一个意图来加载数据库...现在注册应用程序中的接收器..并且在接收器的onreceive方法中,您可以将代码重新加载并显示..

以及第二个问题

  • 你使用的逻辑似乎是正确的..但是我无法理解你的意思是“一些图像在下载时被破坏了”......当它们被破坏时会发生什么......?

答案 1 :(得分:0)

我在github.com(nostra13 / Android-Universal-Image-Loader(Java))上找到了这个很棒的库,它非常完美,可以通过缓存磁盘和内存以及兑现大小等方式来完成工作。

金币是:不要重新发明轮子:)