0

我对 android 开发比较陌生,我正在尝试使用 ImageView 和 TextView 创建自定义 ListView。我正在将 URL 转换为位图图像,然后尝试在 imageView 中显示图像。但是我收到一个错误,我的应用程序立即崩溃。能够在我的 imageView 中显示可绘制对象,我进行了一些修改并尝试显示位图,然后我的应用程序崩溃了。任何帮助将不胜感激。这是我的 3 节课:

编辑我使用 asynctask 在单独的线程上获取位图图像,现在我的应用程序不再崩溃。但是当我开始活动时它不显示列表视图。这是我更新的代码。

编辑我再次更改了我的代码,我只在我的异步任务的执行方法中传递了一个 imageView。我现在可以在列表视图中看到文本,但看不到图像。这是我编辑的代码。

编辑我使用调试器找出位图没有显示的原因,我发现我的位图变量为空。这是因为我没有添加互联网权限。添加权限后,我的应用程序开始在给定行崩溃:

 b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());

由于 OutofMemory 错误,我得到了 RuntimeException。我不知道如何解决这个问题。我将不胜感激任何帮助。谢谢 !

这是我的 Loadimage AsyncTask 类:

 public class LoadImage extends AsyncTask<String, Integer, Bitmap>{

    Context callingContext = null;
    Bitmap b = null;

    ImageView view;

    public LoadImage(ImageView view){

        this.view = view;
    }

    @Override
    protected Bitmap doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        String p_url = "http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png";

        Bitmap b = null;
        try {
            URL image_url = new URL(p_url);
            b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b;
    }



    @Override
    protected void onPostExecute(Bitmap result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        view.setImageBitmap(result);

    }   
}
4

1 回答 1

2

您的代码正在崩溃,因为您在严格模式下在 UI 线程上从服务器加载图像文件。这通常被认为是不好的做法,因为如果图像需要很长时间才能下载,您的应用程序似乎已被锁定。

严格模式正在强制崩溃(它抛出异常)。如果您禁用严格模式,它应该可以让您的应用正常工作。但是,在 UI 线程上执行网络 I/O 的问题仍然存在。

更好的长期解决方案是使用AsyncTask之类的东西。这会将您的图像加载到不同的线程上,从而使您的应用程序保持响应。AsyncTask的文档有一个下载图像的简单示例,这个帮助页面有更多信息。

例如,我可能会将您的代码更改为类似这样的代码(请注意,我在没有测试运行的情况下编写此代码,因此可能存在一些错误):

我会将您的列表条目更改为:

public class CustomList {

    public String iconUrl;
    public String title;
    public CustomList(){
        super();
    }

    public CustomList(String icon, String title) {
        super();
        this.icon = icon;
        this.title = title;
    }
}

然后只将图标 URL 传递到您的列表中。

接下来创建一个 AsyncTask:

public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
     public ImageDownloader(ImageView view){
          mView = view;
     }

     protected Bitmap doInBackground(String... url) {
        Bitmap b = null;
        try {
            URL image_url = new URL(url);
            b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());
            list_data = new CustomList[]{
                    new CustomList(b,"Android")};
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b;
     }

     protected void onPostExecute(Bitmap result) {
         mView.setImageBitmap(result);
     }
     ImageView mView;
}

然后对于您的适配器,而不是设置图像,请执行以下操作:

new ImageDownloader(holder.thumbnail).execute(cl.icon);

这应该足以让你开始。请注意,此示例存在几个问题:

  1. 存在潜在的内存泄漏。一般来说,您不应该像我一样在 AsyncTask 中保留对视图或活动(或其他此类对象)的引用。
  2. 如果您旋转手机并且列表发生变化,您可能会显示旧的缩略图。
  3. 如果一个视图被回收,一个旧的缩略图可能会出现。
于 2012-07-23T16:32:42.793 回答