【问题标题】:Android dynamic image loadingAndroid动态图片加载
【发布时间】:2012-04-03 07:43:30
【问题描述】:

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

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

2- 我有存储在数据库中的图像 URL,需要按原样显示,以显示我已经使用 progressBar 和图像视图扩展了默认 FrameLayout,如果图像不是,新的 Frame Layout 将显示 progressBar尚未加载,如果图像已加载,它将显示,此外,新的 FreamLayout 有一个扩展 AsyncTask 的类,该类通过 URL 检查图像是否存在于文件系统中,如果不存在则下载图像。下面是我完成的课程的示例。这是正确的做法吗?在这种情况下,我有一些图像在下载时损坏了,如何解决这个问题?

感谢您的帮助。

    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();

}
}

【问题讨论】:

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


    【解决方案1】:

    对于第一个问题

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

    对于第二个问题

    • 您使用的逻辑似乎是正确的.. 但我无法理解您所说的“某些图像在下载时损坏”是什么意思.. 当它们损坏时会发生什么..?

    【讨论】:

    • 部分图像显示正确,其余部分显示不正确的像素,损坏的图像显示就像您下载和在电脑中停止下载时一样,您会看到未下载的部分变黑。跨度>
    【解决方案2】:

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

    黄金法则是:不要重新发明轮子:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多