简体   繁体   中英

Android Java creating new thread in BaseAdapter not working

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM