I am using async to load the image into a grid view / list view. For each place download the image for internet , I use a class to handle it. The problem is , how to set a loading icon on it (at the center of the image view)? Thanks
The imageloader class:
public class ImageLoader extends AsyncTask<Object, Void, Bitmap> {
private static String TAG = "ImageLoader";
public InputStream input;
public ImageView view;
public String imageURL;
#Override
protected Bitmap doInBackground(Object... params) {
try {
view = (ImageView) params[0];
imageURL = (String) params[1];
URL url = new URL(imageURL);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
try {
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
protected void onPostExecute(Bitmap result) {
if (result != null && view != null) {
view.setImageBitmap(result);
}
}
}
You could use a custom layout in your GridView or ListView that is a RelativeLayout containing your ImageView and a ProgressBar for the loading-animation.
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<ProgressBar
android:id="#+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>
You would then need to pass the RelativeLayout to the AsyncTask from which you can retreive
a) your ImageView and
b) the ProgressBar
When the download is complete (e.g. you enter the method onPostExecute) you do the following:
#Override
protected void onPostExecute(Bitmap result) {
if (result != null && image != null) {
image.setImageBitmap(result); // change 'image' to the ImageView you retreived earlier from your RelativeLayout
}
progressBar.setVisibility(View.GONE); // hide the ProgressBar
}
Related
I've tried may be every solution from here but nothing helped me. The image doesn't show on the listview only the text. I got only this in LogCat
11-04 14:46:29.319: I/(1225): {"Restaurants":[{"id":"1","name":"Restaurant- 1","menu":"Restaurant-1","image":"rest1.jpg"},{"id":"2","name":"Restaurant-2","menu":"Restaurant-2","image":"rest2.jpg"},{"id":"3","name":"Restaurant-3","menu":"Restaurant-3","image":"rest3.jpg"},{"id":"4","name":"Restaurant-4","menu":"Restaurant-4","image":"rest4.jpg"}]}
11-04 14:46:29.329: E/err(1225): rest1.jpg Restaurant-1 Restaurant-1
11-04 14:46:29.329: E/err(1225): rest2.jpg Restaurant-2 Restaurant-2
11-04 14:46:29.329: E/err(1225): rest3.jpg Restaurant-3 Restaurant-3
11-04 14:46:29.329: E/err(1225): rest4.jpg Restaurant-4 Restaurant-4
This is the code
public class Restaurants extends Activity {
ListView listView;
private StockAdaptor stockAdaptor;
String jsonResult = null;
ImageView image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.restaurants);
listView = (ListView) findViewById(android.R.id.list);
image = (ImageView) findViewById(R.id.image);
new JsonReadTask().execute("http://link/GetRestaurants.php");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true; //No options
}
public void onStart() {
super.onStart();
stockAdaptor = new StockAdaptor(this); //Create a new StockAdaptor
}
public static String strFromStream(InputStream in) throws IOException { //Simple function, getting a String from an InputStream
StringBuilder out = new StringBuilder();
BufferedReader breader = new BufferedReader(new InputStreamReader(in));
String cline;
String newLine = System.getProperty("line.separator");
while ((cline = breader.readLine()) != null) {
out.append(cline);
out.append(newLine);
}
return out.toString();
}
private class StockAdaptor extends BaseAdapter { //The stocks list adaptor
class ViewHolder {
TextView name;
TextView menu;
ImageView image;
}
private LayoutInflater layoutInflater;
private RestaurantInformation[] stocks = null; //Array of stocks
private ListView stocksListView = null;
public StockAdaptor(Context context) {
super();
layoutInflater = LayoutInflater.from(context);
}
public void setStockList(RestaurantInformation[] stocksinfo) {
this.stocks = stocksinfo;
}
#Override
public int getCount() {
return stocks.length;
}
#Override
public Object getItem(int position) {
return stocks[position];
}
public RestaurantInformation[] getAll() { //Return the array of stocks
return stocks;
}
#Override
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder; //New holder
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.restaurant_information, null);
holder = new ViewHolder();
// Creates the new viewHolder define above, storing references to the children
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.menu = (TextView) convertView.findViewById(R.id.menu);
holder.image = (ImageView) convertView.findViewById(R.id.image);
if (holder.image != null) {
if (holder.image.getDrawable() == null) {
new ImageDownloaderTask(holder.image, null)
.execute(stocks[position].image); //Download the image using the image
}
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(stocks[position].name);
holder.menu.setText(stocks[position].menu);
return convertView;
}
}
private class JsonReadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
if (URLUtil.isValidUrl(params[0])) {
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(params[0]);
try {
HttpResponse response = client.execute(getRequest);
final HttpEntity httpentity = response.getEntity();
if (httpentity != null){
InputStream inputStream = null;
try {
inputStream = httpentity.getContent();
jsonResult = strFromStream(inputStream);
Log.i("", jsonResult);
return jsonResult;
} catch (IllegalArgumentException e) {
//
} finally {
httpentity.consumeContent();
}
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
client.close();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
ListDrwaer();
}
}// end async task
// build hash set for list view
public void ListDrwaer() {
//Log.d("data from server", "data: " + jsonResult.toString());
try {
if (jsonResult!=null) {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("Restaurants");
Vector<RestaurantInformation> vstocks = new Vector<RestaurantInformation>();
if(jsonMainNode == null)
{
Log.e("If is null", "jsonMainNode is null");
return;
}
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
RestaurantInformation stock = new RestaurantInformation();
stock.image = jsonChildNode.getString("image");
stock.name = jsonChildNode.optString("name");
stock.menu = jsonChildNode.optString("menu");
//stock.imgPath = jsonChildNode.getString("imgPath");
Log.e("err", stock.image + " " + stock.name + " " + stock.menu);
vstocks.add(stock);
}
RestaurantInformation[] stocks = new RestaurantInformation[jsonMainNode.length()];
int stockscount = jsonMainNode.length();
for (int n = 0; n < stockscount; n++)
{
stocks[n] = vstocks.get(n);
}
stockAdaptor.setStockList(stocks);
listView.setAdapter(stockAdaptor);
} else {
Toast.makeText(getApplicationContext(), "Error; jsonResult null",
Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error" + e.toString(),
Toast.LENGTH_SHORT).show();
}
}
private class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloaderTask(ImageView imageView, View view) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return downloadBitmap(params[0]);
}
#Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
//
}
}
}
}
Bitmap downloadBitmap(String url) {
if(URLUtil.isValidUrl(url)){
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode
+ " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
try {
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
return BitmapFactory.decodeByteArray(output.toByteArray(), 0, output.toByteArray().length);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
getRequest.abort();
Log.w("ImageDownloader", "Error while retrieving bitmap from " + url);
} finally {
if (client != null) {
client.close();
}
}
return null;
}
return null;
}
}
}
I'm not so experienced in Java+Android and really have no idea what can be the problem.
This is the restaurants.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".Activity" >
<ImageView
android:id="#+id/image"
android:layout_width="70dp"
android:layout_height="70dp" />
<ListView
android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignLeft="#+id/image"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
UPDATE
The goal is something like this. I want to load image on the left side and next to it to have text and sub-text if is possible
UPDATE restaurant_information.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="#+id/image"
android:layout_width="70dp"
android:layout_height="70dp" />
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="3dp"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:text="" />
<TextView
android:id="#+id/menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:text="" />
</LinearLayout>
Your ListView is defined as layout_width="fill_parent" and layout_height="fill_parent". As such, it will take up the entire area of it's parent and since it is defined last in the layout, will be at the top of the z-order thereby obscuring your ImageView.
Give this a try:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".Activity" >
<ImageView
android:id="#+id/image"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"/>
<ListView
android:id="#id/android:list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/image"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
You're trying to download the picture from: "rest1.jpg". You need a complete URL.
You can either send the complete url inside the json response, or add it inside your code (if the part that comes before the filename is fixed)
I have parsed JSON at the time of Splash screen, in which image url is parsed for background image for login screen. Here is sample XMLcode for login screen:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/loginLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_bg" <!-- I want to change this background dynamically. -->
android:focusableInTouchMode="true"
android:gravity="center"
tools:context=".activity.LoginActivity" >
<ScrollView
android:id="#+id/mainScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- .... Here is edit text for login inputs and buttuns for singnup and login. -->
</LinearLayout>
</ScrollView>
</RelativeLayout>
In above i have placed static image in the background of RelativeLayout but i want to make backgroud as changeble according to image url.
Thanks in advance.
You need to convert url image to bitmap then bitmap image to Drawable and set it RelativeLayout.
First convert url image to bitmap, see the sample code.
Bitmap myImage = getBitmapFromURL("http://looksok.files.wordpress.com/2011/12/me.jpg");
Take RelativeLayout reference
RelativeLayout rLayout=(RelativeLayout)findViewById(R.id.relativeLayout);
BitmapDrawable(obj) convert Bitmap object into drawable object.
Drawable dr = new BitmapDrawable(myImage);
rLayout.setBackgroundDrawable(dr);
Url image to bitmap convertion method
public Bitmap getBitmapFromURL(String imageUrl) {
try {
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Try this way,hope this will help you to solve your problem.
Download Latest AndroidQuery jar from here:
Put this jar to your libs folder and right click on jar and Build Path -> Add to bulid path.
How to use see this example:
AQuery androidQuery = new AQuery(this);
androidQuery.ajax(url.trim(), Bitmap.class, 0, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap object, AjaxStatus status) {
super.callback(url, object, status);
yourRelativeLayout.setBackground(new BitmapDrawable(object));
}
});
This is how I would do it
Call the AsyncTask like this
new GetImageFromServer().execute(strUrl); // strUrl is your URL
Here is the AsyncTask class
public class GetImageFromServer extends AsyncTask<String, Void, Bitmap>
{
private Bitmap image;
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected Bitmap doInBackground(String... params){
try{
URL urli = new URL(params[0].trim());
URLConnection ucon = urli.openConnection();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
image = BitmapFactory.decodeStream(ucon.getInputStream(),null,options);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return image; //<<< return Bitmap
}
#Override
protected void onPostExecute(Bitmap result){
RelativeLayout relative = (RelativeLayout) findViewById(R.id.loginLayout);
Drawable dr = new BitmapDrawable(result);
relative.setBackgroundDrawable(dr);
}
}
I have been reading through a lot of answers of questions that are similar to mine, but still having problem fixing my issue. I have a project that is an RSS Reader that loads in images in the background with an AsyncTask class. The program works, except if the user scrolls quickly then the images sometimes do not load in my rows. They never load in the incorrect spot, it just seems like they are skipped if the user scrolls quickly. Also, on start-up, only 2 or 1 of the images in my listview load out of the 4 rows that the user can see.
I know the problem has something to do with the WeakReference object that I use, but I am not sure how to implement it in a better way...
This is my RssListAdapter, which contains my Async class as well.
public class RssListAdapter extends ArrayAdapter<JSONObject>
{
TextView textView;
ImageView imageView;
JSONObject jsonImageText;
ProgressDialog progressDialog;
Activity activity2;
View rowView;
public RssListAdapter(Activity activity, List<JSONObject> imageAndTexts)
{
super(activity, 0, imageAndTexts);
activity2 = activity;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
Activity activity = (Activity) getContext();
LayoutInflater inflater = activity.getLayoutInflater();
// Inflate the views from XML
View rowView = (View) inflater
.inflate(R.layout.image_text_layout, null);
jsonImageText = getItem(position);
// ////////////////////////////////////////////////////////////////////////////////////////////////////
// The next section we update at runtime the text - as provided by the
// JSON from our REST call
// //////////////////////////////////////////////////////////////////////////////////////////////////
textView = (TextView) rowView.findViewById(R.id.job_text);
imageView = (ImageView) rowView.findViewById(R.id.feed_image);
BitmapDownloaderTask task = new BitmapDownloaderTask();
Spanned text;
try
{
text = (Spanned) jsonImageText.get("text");
textView.setText(text);
}
catch (JSONException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
task.execute();
return rowView;
}
public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap>
{
private String url;
private RssListAdapter adapter;
private WeakReference<ImageView> imageViewReference = null;
#Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params)
{
imageViewReference = new WeakReference<ImageView>(imageView);
Bitmap img = null;
try
{
if (jsonImageText.get("imageLink") != null)
{
System.out.println("XXXX Link found!");
String url = (String) jsonImageText.get("imageLink");
URL feedImage = new URL(url);
HttpURLConnection conn = (HttpURLConnection) feedImage
.openConnection();
InputStream is = conn.getInputStream();
img = BitmapFactory.decodeStream(is);
}
}
catch (MalformedURLException e)
{
// handle exception here - in case of invalid URL being parsed
// from the RSS feed item
}
catch (IOException e)
{
// handle exception here - maybe no access to web
}
catch (JSONException e)
{
// textView.setText("JSON Exception");
}
return img;
}
#Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap)
{
if (isCancelled())
{
bitmap = null;
}
if (imageViewReference != null)
{
ImageView imageView = imageViewReference.get();
if (imageView != null)
{
imageView.setImageBitmap(bitmap);
}
}
}
#Override
// Before images are loaded
protected void onPreExecute()
{
if (imageViewReference == null)
{
imageView.setImageResource(R.drawable.stub);
}
}
}
}
You should check the official Android "Displaying Bitmaps Efficiently" tutorial on how to load and display bitmaps efficiently. It comes with a ready to use piece of code.
I am trying to display some images in a gridView, this images come from a research on an ElasticSearch server. So I have a textfield + button on my first activity and when I click on the button some images in relation with the keyword in the textfield are printed in a gridview.
Until now I can do my research and some images are displayed in the gridView, but my application crash (outofmemory) after some scroll down/up or if I do others researches. I guess I have to fix this two problems separately.
For the first one (scroll up/down) I want to memorize the bitmap in the cache (http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html).
For the second problem I don't know what to do. All advices/ideas are welcome.
When I memorize the image in the cache, I have still a problem, when I scroll down and after I scroll up no image are displayed anymore and the is no error in 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>
In case of need 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);
}
}
#Lazy Ninja is right, key is lazy image loading. Moreover, to increase the performance of your adapter, you should consider multi-threading it. There is a very good reference on Android Developer's blog. Simpler than the example #Lazy Ninja gave.
It's hard to understand at the beginning, but by far the best approach.
Also, you should consider using an Android Service more than an asynctask for loading data from the network. RoboSpice can help you to achieve that.
You should use lazy image loading. Here is a very good example: Universal Image Loader
I have an Async running to get data from a page I've created. It get's the text just fine, but when I try and get the image from the image src via another class the app force closes. Here is the code that it force closes on:
public class FullReportActivity extends NavigationActivity {
private TextView textView;
private String url = "http://www.backcountryskiers.com/sac/sac-full.html";
private ImageView ivDangerRose;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// tell which region this covers
getSupportActionBar().setSubtitle("...from Sierra Avalanche Center");
setContentView(R.layout.activity_fullreport);
textView = (TextView) findViewById(R.id.todaysReport);
ivDangerRose = (ImageView) findViewById(R.id.dangerRose);
fetcher task = new fetcher();
task.execute();
}
// GET THE IMAGE and RETURN IT
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
class fetcher extends AsyncTask<String, Void, String> {
private ProgressDialog dialog = new ProgressDialog(
FullReportActivity.this);
private Document doc = null;
private Document parse = null;
private String results = null;
private String reportDate = null;
private Bitmap bimage = null;
#Override
protected String doInBackground(String... params) {
try {
doc = Jsoup.connect(url).get();
Log.e("Jsoup", "...is working...");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Exception", e.getMessage());
}
parse = Jsoup.parse(doc.html());
results = doc.select("#fullReport").outerHtml();
Element dangerRoseImg = doc.getElementById("reportRose")
.select("img").first();
String dangerRoseSrc = dangerRoseImg.absUrl("src");
Log.i("Report Rose IMG", dangerRoseSrc);
bimage = getBitmapFromURL(dangerRoseSrc);
ivDangerRose.setImageBitmap(bimage);
return results;
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
// smooth out the long scrolling...
textView.setMovementMethod(ScrollingMovementMethod.getInstance());
reportDate = parse.select("#reportDate").outerHtml();
textView.setText(Html.fromHtml(reportDate + results));
textView.setPadding(30, 20, 20, 10);
}
#Override
protected void onPreExecute() {
dialog.setMessage("Loading Full Report from the Sierra Avalanche Center...");
dialog.show();
}
}
}
I have run this Async alone to get the image like so without a force close and I don't understand what i am doing different besides calling the method:
public class MainActivity extends Activity {
public String durl = "http://www.sierraavalanchecenter.org/dangerrose.png?a=2955";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadImageTask((ImageView) findViewById(R.id.dangerrose))
.execute(durl);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap drose = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
drose = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return drose;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
This class gets the image src and creates a bitmap and puts it into an ImageView, what is different here than on my first class???
Frustrated.
You can not modify UI from background thread.
move ivDangerRose.setImageBitmap(bimage); in onPostExecute
In the method doInBackground
remove --> ivDangerRose.setImageBitmap(bimage);
as you can't modify UI in background process.
If you still want you can try runOnUiThread Method
In doInBackground() we should not access the content of activity.