I'm developing an android app, for that app I have an activity that loads data from a database, that includes text and images. The objective is that those images are displayed in circle, and until now everything is ok.
The problem is that when I start the activity is receives the data with an AsyncTask class and shows the "Loading" dialog but when it passes to my BaseAdapter, it blocks until all the images are loaded, what makes the app to be lazy. What can I do to solve this?
Below you have all my code process.
NotificationsActivity (LoadNotifications AsyncTask)
class LoadNotifications extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Notifications.this);
pDialog.setMessage("Loading..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("token", token));
Log.d("TOKEN", token);
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(getMyNotificationsURL,
"POST", params);
try { // Trying to get notifications
// Getting Array of notifications
notifications = json.getJSONArray("notifications");
userImage = new String[notifications.length()];
message = new String[notifications.length()];
param = new String[notifications.length()];
type = new String[notifications.length()];
timestamp = new String[notifications.length()];
// Looping through all notifications
for (int i = 0; i < notifications.length(); i++) {
JSONObject c = notifications.getJSONObject(i);
try{
userImage[i] = c.getString("userImage");
} catch(Exception e){
userImage[i] = "system";
}
message[i] = c.getString("message");
param[i] = c.getString("param");
type[i] = c.getString("type");
timestamp[i] = c.getString("timestamp");
Log.d("message", message[i]);
} // End for
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
if (notifications.length() > 0) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// dismiss the dialog after getting all videos
pDialog.dismiss();
list = (ListView) findViewById(R.id.notifications_list);
NotificationsAdapter adapter = new NotificationsAdapter(
mActivity, userImage, message, param, type,
timestamp);
list.setAdapter(adapter);
}
});
} else {
pDialog.dismiss();
Toast.makeText(getApplicationContext(),
getString(R.string.noNotifications), Toast.LENGTH_LONG)
.show();
finish();
}
} // Close PostExecute
} // Close LoadNotifications
NotificationsAdapter (The for cycle in constructor is what loads the images)
public class NotificationsAdapter extends BaseAdapter{
private Activity activity;
private String[] usersImage, messages, params, types, timestamps;
private Bitmap[] loadedImages;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public boolean isOnline() {
ConnectivityManager connectivity = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
{
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
return false;
}
public NotificationsAdapter(final Activity activity, String[] userImage, String[] messages, String[] params, String[] types, String[] timestamps) {
this.activity = activity;
this.usersImage = userImage;
this.messages = messages;
this.params = params;
this.types = types;
this.timestamps = timestamps;
final ImageHelper imageHelper = new ImageHelper();
loadedImages = new Bitmap[getCount()];
/*(new Thread(new Runnable() {
@Override
public void run() {
activity.runOnUiThread(new Runnable() {
public void run() {*/
for (int i=0; i<getCount(); i++){
loadedImages[i] = imageHelper.downloadImageTaskOnly(usersImage[i]);
}
/*areImagesLoaded=true;
}
});
}
})).start();*/
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return messages.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageHelper imageHelper = new ImageHelper();
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.notifications_item, null);
ImageView userImage = (ImageView) vi.findViewById(R.id.userImage);
TextView message = (TextView) vi.findViewById(R.id.notification_message);
TextView param = (TextView) vi.findViewById(R.id.notification_param);
TextView type = (TextView) vi.findViewById(R.id.notification_type);
TextView timestamp = (TextView) vi.findViewById(R.id.notification_timestamp);
if (!isOnline()) {
Toast.makeText(activity,
activity.getString(R.string.noInternetConnection),
Toast.LENGTH_SHORT).show();
} else {
if(usersImage[position].equalsIgnoreCase("system")){
Bitmap icon = BitmapFactory.decodeResource(activity.getResources(), R.drawable.vidytape_icon);
userImage.setImageBitmap(imageHelper.BigRoundedShape(icon));
} else {
userImage.setImageBitmap(imageHelper.BigRoundedShape(loadedImages[position]));
}
}
message.setText(messages[position]);
param.setText(params[position]);
type.setText(types[position]);
timestamp.setText(timestamps[position]);
return vi;
}
}
ImageHelper
downloadImageTaskOnly method
public Bitmap downloadImageTaskOnly(String url){
Log.e("IMAGE HELPER", url);
try {
return new DownloadImageTaskOnly().execute(url).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
downloadImageTaskOnly AsyncTask
private class DownloadImageTaskOnly extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
Log.e("IMAGE HELPER", "DOWNLOAD ONLY");
String urldisplay = urls[0];
Log.e("IMAGE HELPER", urldisplay);
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
} // Close DownloadImageTaskOnly
BigRoundedShape
public Bitmap BigRoundedShape(Bitmap scaleBitmapImage) {
// TODO Auto-generated method stub
int targetWidth = 250;
int targetHeight = 300;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) targetWidth - 1) / 2,
((float) targetHeight - 1) / 2,
(Math.min(((float) targetWidth), ((float) targetHeight)) / 2),
Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(),
sourceBitmap.getHeight()), new Rect(0, 0, targetWidth,
targetHeight), null);
return targetBitmap;
}
My goal is to able the user to use the app and the images that weren't already loaded, still loading in background
It's so slow because of
return new DownloadImageTaskOnly().execute(url).get();
.get() is always waiting for the task completion. Feels like this tutorial can help you http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
You can try to pass used imageview into asynctask, pass the result to onPostExecute in bitmap and there set the image, so you don't need to wait in the main thread, just start the task. Some problems will be caused by concurrency, there you can use the second part of tutorial which works with this case.
If you're just downloading images, i'd recommend you to use Picasso ( http://square.github.io/picasso/ ) or even Ion ( https://github.com/koush/ion ) which are libraries that allow you to easily download and even transform an image while allowing you to use both a Memory and Disk Cache.
Hope it helps
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.