2012-12-06 12 views
0

我想在gridView中显示一些图像,这个图像来自对ElasticSearch服务器的研究。所以我在我的第一个活动中有一个textfield +按钮,当我单击按钮时,与textfield中的关键字相关的一些图像将打印在gridview中。从互联网和内存不足的图像的Gridview

直到现在我可以做我的研究和一些图像显示在gridView,但我的应用程序崩溃(outofmemory)后一些向下滚动/向上或如果我做别人的研究。我想我必须分别解决这两个问题。 对于第一个(向上/向下滚动),我想记住缓存中的位图(http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html)。 对于第二个问题,我不知道该怎么做。所有的建议/想法都欢迎。

当我将图片记忆在缓存中时,我仍然遇到问题,当我向下滚动时,在向上滚动后,没有图像显示,并且在catlog中没有错误。

AndroidGridLayoutActivity.java

public class AndroidGridLayoutActivity extends Activity { 
ImageAdapter imgAdapter =new ImageAdapter(this); 
GridView gridView; 
private static LruCache<String, Bitmap> mMemoryCache; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.grid_layout); 

    gridView = (GridView) findViewById(R.id.grid_view); 

    // Get memory class of this device, exceeding this amount will throw an 
    // OutOfMemory exception. 
    final int memClass = ((ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); 

    // Use 1/8th of the available memory for this memory cache. 
    final int cacheSize = 1024 * 1024 * memClass/8; 

    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
     @Override 
     protected int sizeOf(String key, Bitmap bitmap) { 
      // The cache size will be measured in bytes rather than number of items. 
      return bitmap.getByteCount(); 
     } 
    }; 

} 

public void sendMessage(View view){ 

    imgAdapter.clearmThumbIds(); 

    gridView = (GridView) findViewById(R.id.grid_view); 
    EditText editText = (EditText) findViewById(R.id.searchBar); 
    String message = editText.getText().toString(); 
    try { 
     eSearchElastic.ESE(imgAdapter,message,gridView,0); 
    } catch (ClientProtocolException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    System.out.println("SendMessage is ok poiuur ca"); 



} 

public static void addBitmapToMemoryCache(String key, Bitmap bitmap) { 
    if (getBitmapFromMemCache(key) == null) { 
     mMemoryCache.put(key, bitmap); 
    } 
} 

public static Bitmap getBitmapFromMemCache(String key) { 
    return mMemoryCache.get(key); 
} 

} 

ImageAdapter.java

public class ImageAdapter extends BaseAdapter { 
static private List<String> urlList = new ArrayList<String>(); 
private Context mContext; 
Bitmap bmImg; 

static private List<String> mThumbIds = new ArrayList<String>(); 

public void addmThumbIds(String url) { 
    mThumbIds.add(url); 
} 

public void clearmThumbIds() { 
    mThumbIds.clear(); 
} 

public String getmThumbIds(int position) { 
    return mThumbIds.get(position); 
} 

// Constructor 
public ImageAdapter(Context c) { 
    mContext = c; 
} 

@Override 
public int getCount() { 
    return mThumbIds.size(); 
} 

@Override 
public Object getItem(int position) { 
    return mThumbIds.get(position); 
} 

@Override 
public long getItemId(int position) { 
    return 0; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    ImageView imageView; 
    if (convertView == null) { 
     imageView = new ImageView(mContext); 
    } else { 
     imageView = (ImageView) convertView; 
    } 

    System.out.println("Poisition " + position); 
    downloadFile(imageView, mThumbIds.get(position)); 
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
    imageView.setLayoutParams(new GridView.LayoutParams(135, 135)); 
    imageView.setPadding(0, 0, 1, 0); 

    return imageView; 
} 

void downloadFile(final ImageView imageView, final String fileUrl) { 

    AsyncTask<Object, Object, String> task = new AsyncTask<Object, Object, String>() { 

     @Override 
     protected String doInBackground(Object... params) { 
      System.out.println("TEST 1 : begining background"); 
      if (!urlList.contains(fileUrl)) { 
       urlList.add(fileUrl); 

       URL myFileUrl = null; 
       try { 
        myFileUrl = new URL((String) params[0]); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       try { 
        HttpURLConnection conn = (HttpURLConnection) myFileUrl 
          .openConnection(); 
        conn.setDoInput(true); 
        conn.connect(); 
        InputStream is = conn.getInputStream(); 

        bmImg = BitmapFactory.decodeStream(is); 

       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } else { 
       System.out.println("TEST 2"); 
       bmImg = AndroidGridLayoutActivity 
         .getBitmapFromMemCache(fileUrl); 

      } 
      return null; 

     } 

     protected void onPostExecute(String unused) { 
      System.out.println("TEST 2 : begining postexecute"); 
      imageView.setImageBitmap(bmImg); 
      if (!urlList.contains(fileUrl)) { 
       AndroidGridLayoutActivity.addBitmapToMemoryCache(fileUrl, 
         bmImg); 
      } 


     } 
    }; 
    task.execute(fileUrl); 

} 

} 

gridlayout.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<EditText 
android:id="@+id/searchBar" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:hint="@string/Search_hint" 
android:inputType="text" 
android:imeOptions="actionSend" /> 
<Button xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/button_send" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:text="@string/button_send" 
android:onClick="sendMessage" /> 


<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/grid_view" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:numColumns="auto_fit" 
android:columnWidth="90dp" 
android:horizontalSpacing="10dp" 
android:verticalSpacing="10dp" 
android:gravity="center" 
android:stretchMode="columnWidth" > 

</GridView> 
</LinearLayout> 

在需要的情况下eSearchElastic.java

public class eSearchElastic { 

static private List<String> idRowKey = new ArrayList<String>(); 

public static void ESE(final ImageAdapter imgAdapter, final String keyword, 
     final GridView gridView,final int from) throws ClientProtocolException, 
     IOException { 

    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { 

     private String rowKey; 
     private int i =0; 
     private int imageAlreadyPrinted =0; 
     private int size=10; 

     @Override 
     protected Void doInBackground(Void... params) { 
      String server = "server"; 
      String index = "images"; 
      String type = "images_schema_1"; 

      System.out.println("\n\n KEYWORD " + keyword + "\n\n"); 
      String query = "{\"sort\" : [ {\"confidence_level\" : {\"order\" : \"desc\"} }],\"from\" : "+from+", \"size\" : "+size+",\"query\" : {\"text_phrase\" : { \"keyword\" : \"" 
           + keyword 
           + "\"}},\"filter\" : {\"numeric_range\" : {\"confidence_level\" : { \"from\" : 10, \"to\" : 100, \"include_lower\" : true, \"include_upper\" : true}}}}'"; 

      ElasticConnection connection = new ElasticConnection(server, index, type); 
      ElasticQuery elasticQuery = new ElasticQuery(query); 
      ElasticResponse response = null; 
      try { 
       response = elasticQuery.getAnswer(connection); 
      } catch (ClientProtocolException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      String[] fields = { "url"}; 
      List<ElasticResult> results = null; 
      try { 
       results = response.getAnswer(fields); 
      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      for (ElasticResult res : results) { 
       System.out.println("ICI "+from+ " " + res.getField("url")); 
       rowKey = res.getId(); 
       System.out.println(res.getId()); 

       if (rowKey != null) { 

         if (idRowKey.contains(rowKey)) { 
          if(imageAlreadyPrinted<size && i==size-1) 
           try { 
            ESE(imgAdapter,keyword,gridView,from+10); 
           } catch (ClientProtocolException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
           } catch (IOException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
           } 

          System.out.println(rowKey); 
          continue; 
         } else { 
          imageAlreadyPrinted++; 
          addidRowKey(rowKey); 
          imgAdapter.addmThumbIds(res.getField("url")); 
         } 
        } 
       i++;  
      } 

      System.out.println("-----FIN esearch"); 
      return null; 

     } 

     @Override 
     protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 
      gridView.setAdapter(imgAdapter); 
     } 

    }; 
    task.execute(); 

} 

public static void addidRowKey(String url) { 
    idRowKey.add(url); 
} 

public void cleaidRowKey() { 
    idRowKey.clear(); 
} 

public String getidRowKey(int position) { 
    return idRowKey.get(position); 
} 

}

回答

1

@Lazy忍者是对的,关键是懒惰的图像加载。此外,为了提高适配器的性能,您应该考虑对其进行多线程。 Android Developer's blog有很好的参考。比@Lazy Ninja给出的例子更简单。

开始时很难理解,但是迄今为止最好的方法。

另外,您应该考虑使用Android服务,而不是从网络上加载数据的异步应用程序。 RoboSpice可以帮助你实现这一目标。