2016-03-11 42 views
0

所以现在我包括picassosonce然后我经常走出我想做的任何事情,每次内存errors。这可能是因为picasso缓存图像?我完全不知道为什么会发生这种情况,以及如何解决......有什么经验?毕加索内存不足的错误 - 在ListView的Android的图像加载自定义适配器

编辑:解决方案非常简单。必须改变我的自定义adapters建议由picasso接收图像url并将其直接加载到imageview而不是使用绕行保存为bitmap。忽视了暗示,不知道为什么。 这里的适配器:

public class ImageTextListViewAdapter extends ArrayAdapter<RowItem> { 

Context context; 

public ImageTextListViewAdapter(Context context, int resourceId, 
          List<RowItem> items) { 
    super(context, resourceId, items); 
    this.context = context; 
} 

/*private view holder class*/ 
private class ViewHolder { 
    ImageView imageView; 
    TextView txt; 
    TextView id; 
} 

public View getView(int position, View convertView, ViewGroup parent) { 
    ViewHolder holder = null; 
    RowItem rowItem = getItem(position); 

    LayoutInflater mInflater = (LayoutInflater) context 
      .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 

    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.list_item_friends, null); 
     holder = new ViewHolder(); 

     holder.id = (TextView) convertView.findViewById(R.id.text_view_id_friends); 
     holder.txt = (TextView) convertView.findViewById(R.id.list_item_friends_textview); 
     holder.imageView = (ImageView) convertView.findViewById(R.id.friends_image); 

     convertView.setTag(holder); 
    } else 
     holder = (ViewHolder) convertView.getTag(); 

    holder.txt.setText(rowItem.getText()); 
    String url = getItem(position).getUrl(); 

    Picasso.with(context).load(url).into(holder.imageView); 
    holder.id.setText(rowItem.getId()); 

    return convertView; 
} 

}

我在ListViewlistview,我从每个用户从json(通过asynctask)加载名称。 此外,用户映像也必须从服务器加载。这通过第二个ajax请求发生。因为我得到的json与保存的图像的url,然后从服务器获取图像,每个图像通过asynctask发起请求。这使得listview的负载持续很长时间,所以其他活动仍在排队,直到完成此任务。 我发现如何将图像保存在内存缓存中。但是这并不能解决问题,因为只有在将应用程序置于后台时才能保存图像。

listview包含一个称为RowItem custom adapter其含有imageview和两个listviews

有什么建议吗?我正在为此工作约1天半...

谢谢!

继承人我的异步任务加载图像。

public class ImageLoadTask extends AsyncTask<Void, Void, Bitmap> { 
    private final String LOG_TAG = ImageLoadTask.class.getSimpleName(); 
    String url, userId; 
    String[] items; 
    BufferedReader reader = null; 

    public ImageLoadTask(String url, String userId, String[] items) { 
     this.url = url; 
     this.userId = userId; 
     this.items = items; 
    } 

    private String getImageUrlFromJson(String imageJson) throws JSONException { 
     JSONObject imageJsonOutput = new JSONObject(imageJson); 
     imageJsonUrl = imageJsonOutput.getString("imageUrl"); 
     Log.v(LOG_TAG, imageJsonUrl); 
     return imageJsonUrl; 
    } 

    @Override 
    protected Bitmap doInBackground(Void... params) { 
     String imageJson = null; 
     try { 
      URL urlConnection = new URL(url + userId); 
      HttpURLConnection connection = (HttpURLConnection) urlConnection 
        .openConnection(); 
      connection.setDoInput(true); 
      connection.connect(); 
      InputStream input = connection.getInputStream(); 
      StringBuffer buffer = new StringBuffer(); 
      if (input == null) { 
       // Nothing to do. 
       //jsonStr = null; 
       return null; 
      } 
      reader = new BufferedReader(new InputStreamReader(input)); 

      String line; 
      while ((line = reader.readLine()) != null) { 
       // Since it's JSON, adding a newline isn't necessary (it won't affect parsing) 
       // But it does make debugging a *lot* easier if you print out the completed 
       // buffer for debugging. 
       buffer.append(line + "\n"); 
      } 

      if (buffer.length() == 0) { 
       return null; 
      } 
      imageJson = buffer.toString(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     try { 
      String imageUrl = getImageUrlFromJson(imageJson); 
      URL url = new URL(imageUrl); 
      bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream()); 

      addBitmapToMemoryCache(userId, bmp); 
      return bmp; 
     } 
     catch(Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     super.onPostExecute(result); 
     bmp = result; 
     item = new RowItem(bmp, item[0], item[1], item[2]); 
     mDiscoverAdapter.add(item); 
    } 
} 
+0

你不使用毕加索的理由是什么?可以省略这个库,但是你只需要自己替换大部分的功能。 –

+0

通用图像加载器内置选项。这是一个很好的图书馆。 –

+0

以为我必须更改我的代码才能够使用毕加索比我必须。谢谢你的帮助,我现在要用它:) – rudi

回答

3

您试图通过不使用现有的图像加载库来重新发明轮子。看看一些顶级库:

如果你仍然决定建立它自己。您将需要创建缓存系统以根据需要从内存/磁盘保存/加载。还要注意泄漏的视图,因为这可能会非常棘手的图像加载(特别是一个列表或网格)与方向的变化。

官方的android文档有一个伟大的教程Loading/Caching Images。仔细阅读并看看他们提供的示例应用程序,以帮助您开始使用。

相关问题