0

I am new to Parse and the Android API. I want to fetch pictures of my users, but the problem is that I can't get these pictures after they were fetched. Precisely, I use a Loader and I can't get back the pictures in the method onLoadFinished after they were fetched in onCreateLoader.

How can I manage this?

Current code:

public Loader<List<ParseUser>> onCreateLoader(int id, Bundle args) {
    return new ThrowableLoader<List<ParseUser>>(getActivity(), users) {
        // where ThrowableLoader simply extends AsyncLoader which implements loadData
        @Override
        public List<ParseUser> loadData() throws Exception {
            try {
                if(getActivity() != null) {
                    ParseQuery<ParseUser> query = ParseUser.getQuery();
                    query.orderByAscending(Constants.ParseConstants.KEY_USERNAME);
                    query.setLimit(10);
                    users = query.find();
                    bitmap = new Bitmap[users.size()];

                    for(ParseUser user : users) {
                        ParseFile file = (ParseFile) user.get("picture");
                        if(file != null)
                        file.getDataInBackground(new GetDataCallback() {
                            public void done(byte[] data, ParseException e) {
                                if (e == null) {
                                    bitmap[0] = BitmapFactory.decodeByteArray(data, 0, data.length); // here I put this bitmap[0] as a test purpose
                                }
                                else {
                                    System.out.println("Loading image failed for the user" + e.getMessage());
                                }
                            }
                        });
                    }
admdrew
  • 3,790
  • 4
  • 27
  • 39
epsilones
  • 11,279
  • 21
  • 61
  • 85
  • what result do u get if the userList size is just 1 user? The loop "for users" wrapping "getDatainBackground" not likely to scale very well at all IMO. I would look at getting the list of url's to user photos and then spend some time optimizing the network GET AND the Bmp.decode on the list of photo URL's stored as parse files. – Robert Rowntree Sep 11 '14 at 22:58
  • http://stackoverflow.com/a/13311731/560435 – Robert Rowntree Sep 11 '14 at 23:00
  • @RobertRowntree sorry I didn't understand your response. You mean I need to use Loader to query users, then store for each of them the ParseFile objects `ParseFile file = (ParseFile) user.get("picture");`. But then, I need to run `getDataInBackground()`, where do I do that ? – epsilones Sep 13 '14 at 21:25

1 Answers1

0

Do you have a performance problem in the loop or is it some other type of defect?

IMO - the inner loop in your code

 file.getDataInBackground

stands out for a couple reasons relating to scalability and to details of how the parse SDK implements details of AsyncTask that backs the "InBackground". I linked to another thread that gets into why it may not be a good idea to LOOP then in the loop call "inBackground" type stuff because they may not have high priority on the AsnycTask piece or they may still be single threading and you will just get bogged down in a loop construct that could run a whole lot faster using a diff loop manager.

If you have only one user and the code runs OK that could mean its alright without a bigger array that has to cycle thru iteration steps of :

Get the URL corresponds to photo

Decode the response stream of the GET to a Bitmap

I recommend that you consider getting the list of URL's and then

use a threadPool of Multiple Connections

Get the Photo
pass the response stream to a bitmap decoder

I did tests on this with parse and got 3 SECONDS vs 8 minutes in a looper using Parse's version of AsnycTask that i know was single threaded back then.

Robert Rowntree
  • 6,230
  • 2
  • 24
  • 43
  • thank you for your detailed response but sorry I am very new to Android, could you provide a link to some docs about `threadPool of Multiple Connections` ? – epsilones Sep 13 '14 at 22:41