what I am currently doing is allowing users to look up tracks, it will display the song name and display the artist and then start downloading the images in the background so that the user sees the results quickly. What I currently do is take the first 10 queries and dislpay those and download those images, then when the user clicks show more it will download 10 more and so on, but the only image that actually displays once it is done loading is the first one. The rest of the images download, but the imageviews do not populate unless i scroll away from them and then back over them. I can't figure out why, but here is my code.
My code for the custom list adapter:
public class SearchSongAdapter extends BaseAdapter {
ArrayList<ArrayList<String>> track_info;
private static LayoutInflater inflater=null;
String token;
ArrayList<ImageView> imageViews;
ArrayList<Bitmap> imageBitMaps;
DownloadImageTask downloadImageTask;
int downloadsCounter = 0;
public SearchSongAdapter(Context context, ArrayList<ArrayList<String>> track_info, String token)
{
imageViews = new ArrayList<ImageView>();
imageBitMaps = new ArrayList<Bitmap>();
inflater = (LayoutInflater)context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.track_info = track_info;
this.token = token;
//start the downloads
if(track_info.size() > 0) {
downloadImageTask = new DownloadImageTask();
downloadImageTask.execute("https://api.spotify.com/v1/tracks/" + track_info.get(0).get(1).replace("spotify:track:", ""), String.valueOf(downloadsCounter));
}
}
#Override
public int getCount() {
return this.track_info.size();
}
#Override
public Object getItem(int position) {
return track_info.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder
{
TextView songNameTextView, artistNameTextView;
ImageView trackIconImageView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView;
Holder holder = new Holder();
rowView = inflater.inflate(R.layout.song_list_items, null);
holder.songNameTextView = (TextView) rowView.findViewById(R.id.songName);
holder.artistNameTextView = (TextView) rowView.findViewById(R.id.artistNameTextView);
holder.trackIconImageView = (ImageView) rowView.findViewById(R.id.trackIconImageView);
holder.songNameTextView.setText(track_info.get(position).get(0));
holder.artistNameTextView.setText(track_info.get(position).get(2));
imageViews.add(position, holder.trackIconImageView);
if(position < imageBitMaps.size()) {
holder.trackIconImageView.setImageBitmap(imageBitMaps.get(position));
}
return rowView;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
int position;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected Bitmap doInBackground(String... urls) {
HttpResponse response = null;
HttpClient httpClient = new DefaultHttpClient();
String albumpicture;
Bitmap mIcon11 = null;
position = Integer.valueOf(urls[1]);
HttpGet httpPost = new HttpGet(urls[0]);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("Accept", "application/json"));
params.add(new BasicNameValuePair("Authorization Bearer ", token));
try {
response = httpClient.execute(httpPost);
// writing response to log
} catch (IOException e) {
e.printStackTrace();
}
try {
try {
JSONObject jsonObject = new JSONObject(EntityUtils.toString(response.getEntity()));
albumpicture = jsonObject.getJSONObject("album").getJSONArray("images").getJSONObject(0).getString("url");
InputStream in = new java.net.URL(albumpicture).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
mIcon11 = getResizedBitmap(mIcon11, 50, 50);
} catch (JSONException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return mIcon11;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
imageViews.get(position).setImageBitmap(bitmap);
imageBitMaps.add(position, bitmap);
if(position < track_info.size() - 1) {
downloadImageTask = new DownloadImageTask();
downloadImageTask.execute("https://api.spotify.com/v1/tracks/" + track_info.get(downloadsCounter).get(1).replace("spotify:track:", ""), String.valueOf(downloadsCounter));
}
downloadsCounter++;
}
}
DownloadImageTask is where I download the image and I first call it in the constructor.
Summary:
The first imageView loads and populates, but the others do not populate unless I scroll away from there (scroll down) and then back up.
#Rockyfish,
you can reduce your hustle about loading the Images and managing the network call all by your self.
your loading image logic can be replaced by one line of code like this.
Picasso.with(getApplicationContext()).load(image_url).into(holder.trackIconImageView);
where,
getApplicationContext() ===> is context which can be replaced with context you you are assigning to the `adapter`
image_url =================> is the url to the imgae,
the process of loading the ImgaeView from a image kept at some url is done by Picasso as you know he is a great painter so let him do the work.
to add the Picasso library adding following code to the dependencies block in the build.gradle file like this
compile 'com.squareup.picasso:picasso:2.5.2'
and you would be able to use picasso
We have awesome open source libraries to handle the image download and caching stuff - Picasso Square.
We should always try to use existing and proven solutions rather than trying to reinvent the wheel.
Related
I've a fragment which is called from the MainActivity. And this Fragment fetches a JSON file of image URL's and displays images on the screen.
I've used Fresco library to download these images and then pop as a image list view. The images are automatically cached by the Fresco Library.
I want to remove all cached images when I perform a back press from the Fragment.
The images are immediately uncached as the user scrolls down the list and I want to uncache all images when user performs a backPress in the Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_gallery, container, false);
private List<gallery_adapter> gallery_adapterList = new ArrayList<>();
ListView list = (ListView) view.findViewById(R.id.galleryList);
gallery_adapterList.clear();
if(isNetworkConnected()){
new galleryImages().execute("http://www.myurl.json");
}else
Toast.makeText(context,"No Internet Connection!",Toast.LENGTH_SHORT).show();
return view;
}
public class galleryImages extends AsyncTask<String, String, String> {
HttpURLConnection connection;
BufferedReader reader;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
String str = builder.toString();
return str;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(s!=null){
try {
JSONObject parent = new JSONObject(s);
JSONArray images = parent.getJSONArray("images");
if(images!=null){
for(int i=0; i<images.length();i++){
JSONObject child = images.getJSONObject(i);
gallery_adapterList.add(new gallery_adapter(child.getString("url"),child.getString("text")));
}
displayList();
}else
Toast.makeText(context,"error",Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
Toast.makeText(context, "Images not yet added. Try later",Toast.LENGTH_SHORT).show();
}
}else
Toast.makeText(context, "Images not yet added. Try later",Toast.LENGTH_SHORT).show();
}
}
Display list method
private void displayList() {
ArrayAdapter<gallery_adapter> adapter = new galleryAdapterList();
list.setAdapter(adapter);
}
public class galleryAdapterList extends ArrayAdapter<gallery_adapter> {
galleryAdapterList() {
super(context, R.layout.gallery_item, gallery_adapterList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.gallery_item, parent, false);
}
gallery_adapter current = gallery_adapterList.get(position);
TextView mText=(TextView) convertView.findViewById(R.id.galleryText);
mText.setText(current.getText());
uri = Uri.parse(current.getUrl());
//code to remove images from cache
ImagePipeline imagePipeline = Fresco.getImagePipeline();
imagePipeline.evictFromCache(uri);
//code ends here
SimpleDraweeView mImage = (SimpleDraweeView) convertView.findViewById(R.id.galleryImage);
mImage.setImageURI(uri);
return convertView;
}
}
I think what you was it's this however if I may why do you want to clear the cache? Because the next time the user opens the activity he needs to wait for the json response again
Below are option that you can do so:
1.You can cache backpress event in Fragment and call your function to clear cache images ,Handle Back Press.
2.Track Fragment by it's onAttach(Context) , Mean while you need to write FragmentManager.addOnBackStackChangedListener(); it will be called if you have added your fragment with addtoBackStack .
I am tying to lazy load images into my ListView, the images are loading fine, but I've a problem. While loading the images get interchanged.
Let's say that the ListView has 10 rows. It loads the images for 1st row, it displays it in the 1st row, then it loads the image for the 2nd row. It displays in the 2nd row for a moment and then it displays the image for the 2nd row in the 1st row. Then the ImageView in row1 switches between images of 1st row and 2nd. Similarly while loading images of next rows. the previous row's images get switched between. And then after loading all the images, everything gets displayed correctly.
Here's my code
Adapater class:
public class FamilyMemberListAdapter extends ArrayAdapter<Map<String, String>> {
List<Map<String, String>> familyMemberList = new ArrayList<Map<String, String>>();
private Activity activity;
public FamilyMemberListAdapter(Activity activity,
List<Map<String, String>> familyMemberList) {
super(activity, R.layout.activity_gch_family_members, familyMemberList);
this.activity = activity;
this.familyMemberList = familyMemberList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(this.getContext()).inflate(
R.layout.activity_gch_family_member_item, parent, false);
holder = new ViewHolder();
holder.lblFamilyMemberName = (TextView) convertView
.findViewById(R.id.lblFamilyMemberItem);
holder.lblFamilyMemberRelation = (TextView) convertView
.findViewById(R.id.lblFamilyMemberRelationItem);
holder.imgProfilePic = (ImageView) convertView
.findViewById(R.id.imgvProfilePic);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
int accountId = Integer.valueOf(familyMemberList.get(position).get(
"accountId"));
holder.lblFamilyMemberName.setText("Name: "
+ familyMemberList.get(position).get("name"));
holder.lblFamilyMemberRelation.setText("Relation: "
+ familyMemberList.get(position).get("relation"));
if (holder.imgProfilePic != null) {
new ImageDownloaderTask(holder.imgProfilePic).execute(String
.valueOf(accountId));
}
return convertView;
}
#Override
public int getCount() {
return familyMemberList.size();
}
static class ViewHolder {
TextView lblFamilyMemberName;
TextView lblFamilyMemberRelation;
ImageView imgProfilePic;
}
}
Imageloader AsyncTask:
public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
protected Bitmap doInBackground(String... params) {
String responseText = null;
HttpClient httpClient = ServiceHelper.getHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(RestApiPaths.GET_PROFILE_PIC + accountId);
try {
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
// getting contents from the stream
inputStream = entity.getContent();
// decoding stream data back into image Bitmap that android understands
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
Log.d(TAG, responseText);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
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 {
Drawable placeholder = imageView.getContext().getResources().getDrawable(R.drawable.holder_pic_side);
imageView.setImageDrawable(placeholder);
}
}
}
}
}
I've created a Static class for the ListView items. Still Why is the images go on interchanging while loading. Please tell me what I'm doing wrong here.
Add holder.imgProfilePic.setTag(accountId); before you call the AsyncTask. Add an extra parameter accountId to your task. Then in onPostExecute check if it is the same accountId as in the image view
Maybe try to use libraries like picasso or universal image loader or something.
They have solved most of problems with image loading
So now I included picasso and sonce then I regularly get out of memory errors every time I want to do anything. could this be because of picasso caching the images? I have absolutely no idea why this is happening and how to solve... any experiences with that?
EDIT: Solution was pretty simple. had to change my custom adapters as suggested by picasso to receive images url and load it directly into the imageview instead of using the detour of saving as bitmap. overlooked the hint, don't know why.
Here's the adapter:
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;
}
}
I have a listview where I load the name from every user from json (via asynctask) in a ListView.
Additionally the user image has to be loaded from server, too. this happens via a second ajax request. as I get the json with the url for the saved image to get the image then from server, for each image a request is fired via asynctask. this makes the load of the listview last very long so other activities stay in queue until this task is finished.
I found out how to save images in memory cache. but that does not solve the problem as the images are only saved when I put the app in background.
the listview contains a custom adapter called RowItem which contains an imageview and two listviews.
any suggestions? I am working on this for about 1 day and a half now...
thank you!
heres my Async task for loading the images.
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);
}
}
You are trying to reinvent the wheel by not using an existing image loading library. Have a look at some of the top libraries:
Glide
Picasso
Fresco
If you are still determined to build it yourself. You will need to create a caching system to save/load from memory/disk as needed. Also be careful about leaking views as this can get very tricky with image loading (esp a list or grid) with orientation change.
The official android documentation has a great tutorial on Loading/Caching Images. Go through that and have a look at the sample app that they provide to help you get started.
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 developing Android apps,
once part of this apps is creating a GridView that contain some image (the image is loaded from URL),
then another activity that show the selected image in full screen will be appeared when one of image in GridView is onClick.
Problem:
When I enter the GridView activity, it takes some second to load all image in gridview normally.
Then I click one of image to enter the full screen activity and click back button to go back to GridView,
but, it takes some second to loading when go back to gridview, just like loading all image again.
I wonder why the gridview activity will loading for a few second when onResume?
For example, in Google Play, the full screen view of sample image in any apps can be back to previous view immediately.
Enclosed code:
GridView:
public class ManagePhoto extends Activity {
ImageAdapter ia;
GridView gridview;
InputStream inputStream;
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
TextView tvRunningMark;
boolean bRunning;
String[] purl;
Bitmap[] bm;
String the_string_response;
TouchImageView touch;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photo_manage);
//gv is Gobal Value
final Gvalue gv = ((Gvalue) getApplicationContext());
gridview = (GridView) findViewById(R.id.gv_photo);
gridview.setOnItemClickListener(new GridView.OnItemClickListener() {
public void onItemClick(AdapterView adapterView, View view,int position, long id) {
gv.setbm(bm[position]);
Intent myIntent = new Intent(adapterView.getContext(), FullScreenImage.class);
startActivityForResult(myIntent, 0);
}
});
new GridTask().execute();
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return purl.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some
// attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200,200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
try {
bm[position] = loadBitmap(purl[position]);
imageView.setImageBitmap(bm[position]);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageView;
}
}
class GridTask extends AsyncTask<Void, String, Void> {
#Override
protected void onPostExecute(Void result) {
gridview.setAdapter(ia);
final LinearLayout llo_probar = (LinearLayout)findViewById(R.id.llo_probar);
llo_probar.setVisibility(LinearLayout.GONE);
gridview.setVisibility(GridView.VISIBLE);
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(String... values) {
}
#Override
protected Void doInBackground(Void... params) {
getphoto();
bm = new Bitmap[purl.length];
ia = new ImageAdapter(ManagePhoto.this);
return null;
}
}
private Bitmap loadBitmap(String url) throws MalformedURLException,IOException {
return BitmapFactory.decodeStream(new FlushedInputStream(
(InputStream) new URL(url).getContent()));
}
class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(final InputStream inputStream) {
super(inputStream);
}
#Override
public long skip(final long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int bytesRead = read();
if (bytesRead < 0) { // we reached EOF
break;
}
bytesSkipped = 1;
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
public void getphoto(){
final Gvalue gv = ((Gvalue) getApplicationContext());
final TextView tv_fn = (TextView) findViewById(R.id.tv_fn);
String result = "";
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("sql",
("select * from personal_photo where member_id = " + gv.getuid())));
InputStream is = null;
// http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://" + gv.getserverIP()
+ "/android_getdata.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
// parse json data
try {
List url = new ArrayList();
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
url.add(json_data.getString("save_location"));
}
int size = url.size();
purl = new String[size];
for (int j = 0; j < size; j++) {
purl[j] = (String) url.get(j);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
}
public void toast(String text) {
Toast.makeText(ManagePhoto.this, text, 5).show();
}
}
Full screen:
public class FullScreenImage extends Activity {
TouchImageView touch;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
new ShowPhotoTask().execute();
}
class ShowPhotoTask extends AsyncTask<Void, String, Void> {
#Override
protected void onPostExecute(Void result) {
setContentView(touch);
}
#Override
protected void onPreExecute() {
setContentView(R.layout.full_image);
}
#Override
protected void onProgressUpdate(String... values) {
}
#Override
protected Void doInBackground(Void... params) {
final Gvalue gv = ((Gvalue) getApplicationContext());
touch = new TouchImageView(FullScreenImage.this);
touch.setMaxZoom(4f); // change the max level of zoom, default is 3f
touch.setImageBitmap(gv.getbm());
return null;
}
}
}
From your getView code in your ImageAdapter, everytime you will load the image from the internet again.
You should download the image to local, next time, when your set the image, you try to get it from local firstly.
As well you should put the get bitmap in the thread as you have putting the parse JSON in the thread.
Here is an demo, i think it will help you.
In your gridview onclick you are starting activity with startActivityForResults(intent,0); replace it with startActivity(intent);
also when you are finishing the FullScreenActivity just use finish();
might solve your problem
It's so slow because you don't perform your operations with background threads, caching..
A simple and better solution could be a collection that contains all your bitmaps inserted by AsyncTasks that you'll execute to download the pictures.
There are better solutions but they are more difficult to implement.
For example you can consider the possibility to keep a thread pool that resolves your runnables represented by "download the http://jhon.doe.jpg" and then "show now on the UI thread".
As you have written below function inside the getView() method:
bm[position] = loadBitmap(purl[position]);
I would say you should implement code to load Image Asynchronously. In this logic, image is synced in your memory card once its downloading is done. So next time it will load directly from memory card instead of loading it from web again.
Here is a code example you can give a try: Android - Universal Image Loader