2013-03-29 2 views
0

Я написал класс, который получает изображения от JSON. Работает, проблема с памятью. когда я прокручиваю приложение, оно протекает в памяти. Вот мои коды.ListView утечка памяти в Android

package com.nexum.senddata; 

public class MainActivity extends Activity { 

private ListView list; 
private MyAdapter adapter; 

    private final String parsingUrl = "http://sametdede.com/expo/data.json"; 
private String tag_coord = "Coord"; 
private String tag_lat = "Lat"; 
private String tag_lon = "Lon";// Double 
private String tag_image = "Image"; 
private String tag_InIzmir = "InIzmir"; 
private String tag_name = "Name"; 

private ProgressDialog pDialog; 

private static int clickedItemPosition = -1; 
private final int REQUEST_CODE_DETAIL = 1; 

ArrayList<CoordItem> items; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    items = new ArrayList<CoordItem>(); 
    adapter = new MyAdapter(this, R.layout.list_item, items); 

    list = (ListView) findViewById(R.id.exampList); 
    list.setAdapter(adapter); 

    pDialog = new ProgressDialog(this); 
    pDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    pDialog.setMessage("Veriler alınıyor..."); 

    new ListViewLoad().execute(); 

    list.setOnItemClickListener(new OnItemClickListener() { 

     @SuppressLint("ShowToast") 
     @Override 
     public void onItemClick(AdapterView<?> a, View v, int position, 
       long id) { 
      /* 
      * String bulunma = ""; if (items.get(position).inIzmir) { 
      * bulunma+="İzmir de bulundu."; }else{ 
      * bulunma+="İzmir de bulunmadı."; } String 
      * s="Name:"+items.get(position).name+"\nInIzmir:"+bulunma; 
      * Toast.makeText(getApplicationContext(), s, 
      * Toast.LENGTH_LONG).show(); 
      */ 

      clickedItemPosition = position; 
      Intent myIntent = new Intent(MainActivity.this, 
        DetailActivity.class); 
      Bundle bundle = new Bundle(); 
      bundle.putParcelable(
        "parcelable_key", 
        new CoordItem(items.get(position).name, items 
          .get(position).img, items.get(position).lat, 
          items.get(position).lon, 
          items.get(position).inIzmir)); 
      myIntent.putExtras(bundle); 
      // Güncelleme olayı burada başlıyor 
      // startActivityForResult(myIntent, REQUEST_CODE_DETAIL); 

      startActivityForResult(myIntent, REQUEST_CODE_DETAIL); 

     } 

    }); 

} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // TODO Auto-generated method stub 
    super.onActivityResult(requestCode, resultCode, data); 

    if (requestCode == REQUEST_CODE_DETAIL && resultCode == RESULT_OK 
      && data != null) { 
     CoordItem coorditem = new CoordItem(data.getStringExtra("name"), 
       items.get(clickedItemPosition).img, Double.parseDouble(data 
         .getStringExtra("lat")), Double.parseDouble(data 
         .getStringExtra("lon")), 
       items.get(clickedItemPosition).inIzmir); 

     items.set(clickedItemPosition, coorditem); 
     adapter.notifyDataSetChanged(); 
     Toast.makeText(getApplicationContext(), "Guncelleme yapıldı.", 
       Toast.LENGTH_SHORT).show(); 
    } 
    /* 
    * CoordItem coorditem = new CoordItem(data.getStringExtra("name"), 
    * items.get(clickedItemPosition).img, 
    * Double.parseDouble(data.getStringExtra("lat")),Double.parseDouble(
    * data.getStringExtra("lon")), items.get(clickedItemPosition).inIzmir); 
    * 
    * items.set(clickedItemPosition, coorditem); 
    * adapter.notifyDataSetChanged(); 
    * Toast.makeText(getApplicationContext(), "Guncelleme yapıldı.", 
    * Toast.LENGTH_SHORT).show(); 
    */ 

} 

private class ListViewLoad extends AsyncTask<Void, Void, Void> { 

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

    @Override 
    protected Void doInBackground(Void... params) { 

     String json = getStringFromURL(parsingUrl); 
     try { 
      final JSONArray jArray = new JSONArray(json); 

      for (int i = 0; i < jArray.length(); i++) { 
       JSONObject c = jArray.getJSONObject(i); 
       JSONObject coord = c.getJSONObject(tag_coord); 
       double lat = coord.getDouble(tag_lat); 
       double lon = coord.getDouble(tag_lon); 
       String image = c.getString(tag_image); 
       boolean InIzmir = c.getBoolean(tag_InIzmir); 
       String name = c.getString(tag_name); 

       CoordItem item = new CoordItem(name, image, lat, lon, 
         InIzmir); 
       items.add(item); 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 

     adapter.notifyDataSetChanged(); 

     pDialog.dismiss(); 
    } 

} 

private class MyAdapter extends ArrayAdapter<CoordItem> { 

    private LayoutInflater inflater; 

    public MyAdapter(Context context, int textViewResourceId, 
      ArrayList<CoordItem> objects) { 
     super(context, textViewResourceId, objects); 

     this.inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public int getCount() { 
     if (items != null) 
      return items.size(); 
     else 
      return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     ViewHolder viewholder = null; 

     if (convertView == null) { 
      viewholder = new ViewHolder(); 

      convertView = inflater.inflate(R.layout.list_item, parent, 
        false); 
      viewholder.listItemImage = (ImageView) convertView 
        .findViewById(R.id.listItemImage); 

      viewholder.listItemName = (TextView) convertView 
        .findViewById(R.id.listItemName); 
      viewholder.listItemInIzmir = (TextView) convertView 
        .findViewById(R.id.listItemInIzmir); 
      viewholder.listItemLatitude = (TextView) convertView 
        .findViewById(R.id.listItemLatitude); 
      viewholder.listItemLongitude = (TextView) convertView 
        .findViewById(R.id.listItemLongitude); 
      convertView.setTag(viewholder); 
     } else { 
      viewholder = (ViewHolder) convertView.getTag(); 
     } 

     viewholder.listItemName.setText(items.get(position).name); 
     if (items.get(position).inIzmir) { 
      viewholder.listItemInIzmir.setText("Izmirde."); 
     } else { 
      viewholder.listItemInIzmir.setText("Izmirde degil."); 
     } 

     try { 
      viewholder.listItemImage 
        .setImageDrawable(getDrawableFromUrl(new URL(items.get(
          position).getImg()))); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return convertView; 
    } 

    public Drawable getDrawableFromUrl(URL url) { 
     try { 
      InputStream is = (InputStream) url.getContent(); 
      Drawable d = Drawable.createFromStream(is, "src"); 
      return d; 
     } catch (Exception e) { 
      return null; 
     } 
    } 

} 

/** 
* Burada layoutinflater da kullandığımız layoutun componentlerini 
* yazıyoruz.Bu da bizim list_item.xml imizdir. 
*/ 
static class ViewHolder { 
    ImageView listItemImage; 
    TextView listItemName, listItemInIzmir, listItemLatitude, 
      listItemLongitude; 
} 

public String getStringFromURL(String url) { 

    // Making HTTP request 
    String json = ""; 
    InputStream is = null; 
    try { 
     // defaultHttpClient 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(url); 

     HttpResponse httpResponse = httpClient.execute(httpPost); 
     HttpEntity httpEntity = httpResponse.getEntity(); 
     is = httpEntity.getContent(); 

    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
       is, "UTF-8"), 8); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
     is.close(); 
     json = sb.toString(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    // return JSON String 
    return json; 

} 

}

Где я могу прочитать и получить изображение для выполнения быстрее и не утечка памяти?

ответ

1

Вы уже использовали ViewHolder.

Используйте LazyList или универсальный погрузчик Изображение

Ленивый Список

Изображения могут быть кэшируются на локальной карте памяти сд или телефон mmeory. Url считается ключевым. Если ключ присутствует на SD-карте, изображение с SD-карты еще отображает изображение, загружая с сервера и кешируйте то же самое в выбранное вами местоположение. Предел кеша может быть установлен. Вы также можете выбрать свое местоположение для кэширования изображений. Кэш также можно очистить.

Вместо пользователя, ожидающего загрузки больших изображений, а затем отображения ленивого списка загружает изображения по запросу. Поскольку кеши изображений вы можете отображать изображения в автономном режиме.

https://github.com/thest1/LazyList. Ленивый Список

В вашем GetView

imageLoader.DisplayImage(imageurl, imageview); 

метод ImageLoader Дисплей

public void DisplayImage(String url, ImageView imageView) //url and imageview as parameters 
{ 
imageViews.put(imageView, url); 
Bitmap bitmap=memoryCache.get(url); //get image from cache using url as key 
if(bitmap!=null)   //if image exists 
    imageView.setImageBitmap(bitmap); //dispaly iamge 
else //downlaod image and dispaly. add to cache. 
{ 
    queuePhoto(url, imageView); 
    imageView.setImageResource(stub_id); 
} 
} 

Универсальный Image Loader

https://github.com/nostra13/Android-Universal-Image-Loader.

Может загружать изображения локально или с сервера.

Он основан на Lazy List (работает по тому же принципу). Но у него много других конфигураций. Я бы предпочел использовать Universal Image Loader coz, это даст вам больше возможностей настройки. Вы можете отобразить изображение ошибки, если downlaod не удалось. Может отображать изображения с закругленными углами. Может кэшировать диск или память. Может сжимать изображение.

В пользовательском адаптере конструктор

File cacheDir = StorageUtils.getOwnCacheDirectory(activity context, "your folder");//for caching 

// Get singletone instance of ImageLoader 
imageLoader = ImageLoader.getInstance(); 
// Create configuration for ImageLoader (all options are optional) 
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a) 
// You can pass your own memory cache implementation 
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation 
.discCacheFileNameGenerator(new HashCodeFileNameGenerator()) 
.enableLogging() 
.build(); 
// Initialize ImageLoader with created configuration. Do it once. 
imageLoader.init(config); 
options = new DisplayImageOptions.Builder() 
.showStubImage(R.drawable.stub_id)//display stub image untik image is loaded 
.cacheInMemory() 
.cacheOnDisc() 
.displayer(new RoundedBitmapDisplayer(20)) 
.build(); 

В вашем GetView()

ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options. 

Вы можете настроить другие параметры в соответствии с вашими потребностями.

+0

Я получаю URL-адреса от JSON. Итак, как я могу инициализировать ImageLoader в соответствии с моими кодами? – emrerme

+0

imageLoader.displayImage (imageurl, изображение, опции); если вы используете универсальный загрузчик изображений, используйте приведенное выше. пропустите образы изображения к вашему адаптеру cusotm и укажите URL-адрес, например url [позиция] – Raghunandan

+0

Нет нет. Как инициализировать класс ImageLoader. Ему нужны некоторые параметры ImageLoader imageloader = new ImageLoader (?); В моих кодах что я могу там положить? спасибо – emrerme

Смежные вопросы