lucasr / smoothie

[DEPRECATED] Easy async loading for Android's ListView/GridView
985 stars 163 forks source link

Help required #25

Closed theoklink closed 10 years ago

theoklink commented 10 years ago

I am using the library in my app "Playlist Manager" The implementation of displaying albumart is more or less similar to the example. However, smoothie never seems to get it 100% correct. It seems to decide not to display according to some arbitary rules. I do not have the technical understanding to fully understand managing threads etc so have done my best to understand the process. I do not seem to get closer to resolving this.

For example, without touching, displaying 5 tracks from the same album (id = 12) albumart icon on the left, track detail, track duration and checkbox, produces different results each time. Never are all tracks displayed with its albumart. When flinging and moving up/down, smoothie is never able to be 100% correct and often displays the incorrect albumart (related to the previous page) Below the sequence of events from ItemLoader using Log.i:

performLoadItem for position 0 - shouldDisplayItem = true No pending item request, creating new: 12 performLoadItem - shouldDisplayItem = true|| isItemInMemory(itemParams) performLoadItem for position 1 - shouldDisplayItem = true No pending item request, creating new: 12 performLoadItem - shouldDisplayItem = true|| isItemInMemory(itemParams) performLoadItem for position 2 - shouldDisplayItem = true There's a pending item request, reusing: 12 performLoadItem - shouldDisplayItem = true|| isItemInMemory(itemParams) performLoadItem for position 3 - shouldDisplayItem = true There's a pending item request, reusing: 12 performLoadItem - shouldDisplayItem = true|| isItemInMemory(itemParams) performLoadItem for position 4 - shouldDisplayItem = true There's a pending item request, reusing: 12 performLoadItem - shouldDisplayItem = true|| isItemInMemory(itemParams) mRequest.itemView != null - Done loading image: mRequest.itemView != null - Done loading image: mRequest.itemView != null - Done loading image: mItemLoader.mHandler.post - run the display routine mItemLoader.mHandler.post - run the display routine mItemLoader.itemViewReused mRequest.itemView != null - Done loading image: mItemLoader.itemViewReused mRequest.itemView != null - Done loading image: mItemLoader.mHandler.post - run the display routine

The end result is shown image

The outcome is different each time.

also During my investigation I found the following code line 705 if (mItemLoader.itemViewReused(mRequest)) { return; } but further on Line 719 the same test is made. Is one of these redundant?

Who can help me out here?

theoklink commented 10 years ago

I have paired down the code to a simple test framework. Following the steps as outlined in itemLoader, the tracing shows that all pass getItemParams, loadItemFromMemory, loadItem, but when it comes to displayItem only some of the drawables are displayed. Although all have passed, something has decided incorrectly some drawables need not be displayed. Step 1 getItemParams - Album Id = 12 Step 2 loadItemFromMemory - albumid = 12 Step 2 loadItemFromMemory - albumid = 12 Step 3 loadItem - Load item albumid = 12 Step 1 getItemParams - Album Id = 12 Step 2 loadItemFromMemory - albumid = 12 Step 2 loadItemFromMemory - albumid = 12 Step 1 getItemParams - Album Id = 12 Step 2 loadItemFromMemory - albumid = 12 Step 2 loadItemFromMemory - albumid = 12 Step 1 getItemParams - Album Id = 12 Step 2 loadItemFromMemory - albumid = 12 Step 2 loadItemFromMemory - albumid = 12 Step 1 getItemParams - Album Id = 12 Step 2 loadItemFromMemory - albumid = 12 Step 2 loadItemFromMemory - albumid = 12 Step 3 loadItem - Load item albumid = 12 Step 3 loadItem - Load item albumid = 12 Step 3 loadItem - Load item albumid = 12 Step 3 loadItem - Load item albumid = 12 Step 4 - displayItem Step 4 fading drawable Step 4 - displayItem Step 4 fading drawable

This is the result image

theoklink commented 10 years ago

Additional: I started from scratch. Took the Gallery example that is included in the zip. Added lots of images to my avd. Behaves perfect and as expected. However, when trying to display album covers the behaviour changes and issue as described above occurs. The only changes made to the original code are: Use the AsyncListView In MainActivity amend Loader uri and selection: Uri newuri = MediaStore.Audio.Playlists.Members.getContentUri( "external", 259); String[] columns = { MediaStore.Audio.Playlists.Members.ALBUM_ID + " as _id" ,// needed for album cover MediaStore.Audio.Playlists.Members.AUDIO_ID , MediaStore.Audio.Playlists.Members.TRACK, MediaStore.Audio.Playlists.Members.ARTIST, MediaStore.Audio.Playlists.Members.TRACK, MediaStore.Audio.Playlists.Members.ALBUM, MediaStore.Audio.Playlists.Members.TITLE, MediaStore.Audio.Playlists.Members.DURATION, MediaStore.Audio.Playlists.Members.DATA, MediaStore.Audio.Playlists.Members.PLAY_ORDER, MediaStore.Audio.Playlists.Members.DATE_MODIFIED }; return new CursorLoader(this, newuri, columns, null, null, null); default: return null; }

in GalleryAdapter: String label = c.getString(c.getColumnIndex(MediaStore.Audio.Playlists.Members.ALBUM)); label = label + "\r\n" + c.getString(c.getColumnIndex(MediaStore.Audio.Playlists.Members.TITLE)); holder.title.setText(label);

in GalleryLoader: @Override public Long getItemParams(Adapter adapter, int position) { Cursor c = (Cursor) adapter.getItem(position); long album_id = c.getLong(c.getColumnIndex(MediaStore.Audio.Playlists.Members._ID)); return album_id; // return c.getLong(c.getColumnIndex(MediaStore.Audio.Media._ID)); } and @Override public Bitmap loadItem(Long id) { Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart"); Uri imageUri = Uri.withAppendedPath(sArtworkUri, String.valueOf(id));

Now when launching this and without touching the screen, the first page only loads a few album icons. Again, which ones it displays appears to be arbitrary.

image

The loading of bitmaps in the background does not appear to be working corretly. Anyone with similar experiences? I would appreciate some response(s)

theoklink commented 10 years ago

Still investigating. Smoothie does not refresh correctly when I display albumart for all tracks in a gridview. First of all, it incorrectly loads the first page views, secondly when scrolling, it gets its knickers in a twist with the paging. This effectively means displaying the same (album) id repeatedly, which I think is where the problem lies. smoothie seems to be quite happy when each id is different but dealing with many same ids appears to be a problem.