Reputation: 177
I'm working on fetching data from server and display it. I'm using volley library to show the information. I managed to show everything. But now I want to show images by saving it first and then display from sd card. So I created a thread to download the images. But it is affecting the loading time of the activity. Please help me how to solve that problem. My code goes like this.
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder vh ;
if(view == null){
vh = new ViewHolder();
view = lf.inflate(R.layout.row_listview,null);
vh.tvSen = (TextView)view.findViewById(R.id.textSend);
vh.tvRece = (TextView)view.findViewById(R.id.textRec);
vh.tvMsB = (TextView)view.findViewById(R.id.textMBody);
vh.nwImg = (NetworkImageView)view.findViewById(R.id.twitterUserImage);
view.setTag(vh);
}
else{
vh = (ViewHolder) view.getTag();
}
DataModel nm = arrData.get(i);
vh.tvSen.setText(nm.getSender());
vh.tvMsB.setText(nm.getMessageBody());
vh.tvMsB.setTextColor(Color.WHITE);
ImageSave saveit = new ImageSave(IMAGES[i]);
FutureTask<String> future = new FutureTask<String>(saveit);
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(future);
future.isDone();
vh.nwImg.setImageUrl(IMAGES[i], imageLoader);
return view;
}
Upvotes: 0
Views: 86
Reputation: 3098
I did something similar in a project i'm working on.
This is part of the code of the activity:
protected void onCreate(Bundle savedInstanceState) {
...
// image = image identifier, i.e. "pic1", "pic2"...
ImageView img = (ImageView) this.findViewById(R.id.big_icon);
String path = ImageManager.getCachedImage(image, this);
if(path != null)
setImage(path, img);
else {
Callback c = new ImageCallBack(img);
new ImageManager(c, this).execute(image);
}
...
}
// Image loading callback
private class ImageCallBack implements Callback {
ImageView img;
public ImageCallBack(ImageView img){
this.img = img;
}
@Override
public boolean handleMessage(Message msg) {
String path = (String) msg.obj;
setImage(path, this.img);
return false;
}
}
The ImageManager class extends AsyncTask and is used to asynchronously dowload the image and store it on the SD card. When download is done, the provided callback is called. In this way, you callback can show the image (and possibly hide a spinner, just to show to the user that something is loading). It also has a static member to check if the image is already in cache (returns null otherwise). Some of the code, easy to extend:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.http.util.ByteArrayBuffer;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler.Callback;
import android.os.Message;
public class ImageManager extends AsyncTask<String, Void, String> {
private Callback callback;
private Context context;
private String imagesUrl;
public ImageManager(Callback cb, Context con){
callback = cb;
context = con;
imagesUrl = "http://picturesurl.com/something/";
}
@Override
protected String doInBackground(String... imageCode) {
InputStream is = null;
String outFile = null;
try {
URL url = new URL(imagesUrl + imageCode[0] + ".png");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
is = conn.getInputStream();
BufferedInputStream bufferinstream = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while((current = bufferinstream.read()) != -1){
baf.append((byte) current);
}
outFile = context.getExternalFilesDir(null) + "/" + imageCode[0] + ".png";
FileOutputStream fos = new FileOutputStream(outFile);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
} catch(IOException e){
System.out.println("ImageManager error!" + imageCode[0]);
e.printStackTrace();
return null;
} finally {
if (is != null) {
try {
is.close();
} catch(IOException e){
System.out.println("ImageManager error on close!");
e.printStackTrace();
return null;
}
}
}
return outFile;
}
public static String getCachedImage(String image, Context context){
String path = context.getExternalFilesDir(null) + "/" + image + ".png";
File f = new File(path);
if (f.exists())
return path;
else
return null;
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
Message m = new Message();
m.obj = result;
if(result != null)
System.out.println("New image cached: " + result);
else
System.out.println("Error downloading image.");
this.callback.handleMessage(m);
}
}
Upvotes: 1