Ankit Srivastava
Ankit Srivastava

Reputation: 280

Async loading of images in a CustomListView from MediaFiles

I am developing a music app and my app takes a lot of time to generate the list of music files(because it has to generate the bitmaps) so I searched the net and came to know about the asynctask, I was able to implement it successfully in one another problem I had (so I think I understand the logic behind it) but in this case I just cant figure a way how to do it,(

Custom Adapter is confusing me a bit,i am wondering where should i do the tasks a- synchronously ,while i am generating the list or whether in the custom adapter where i am displaying the list i have generated )

so please I need help. here is the logic behind the program

I have a class "SongDetails" which has the following elements

Bitmap icon;
String song;
String Artist;
String Album;
String Path;

I have created an arraylist of SongDetails now I have another class called getSongsFromDirectory which searches for music files, fetches album and artist info from it, and adds the each item to the ArrayList and when the list is generated it returns the list to the onCreate method.Now onCreate method sorts the list by name of the songs and then gives the list to the custom adapter which displays the result,I can't understand where I should put this async task thing...........here is the code I have used

public class FragmentSongs extends  Fragment implements Serializable  {

    
    


    AdapterView.AdapterContextMenuInfo info;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    {
              
       
       
       
       
        View view = inflater.inflate(R.layout.fragment_song, container, false);
                ListView SngList = (ListView) view.findViewById(R.id.SongList);
        registerForContextMenu(SngList);
        //File f=new File(Environment.getExternalStorageDirectory()+"Music");
        //File f=new File("/sdcard/Music");
        File f=new File(Environment.getExternalStorageDirectory()+"musicz");
        //File f=new File("/storage/extSdCard/My Music/");
        int j=0;int i=0;
        
        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

         final ArrayList<SongDetails> Songinfo = getSongsFromDirectory(f);
         FragmentSongs dv=new  FragmentSongs ();
         if (Songinfo.size()>0)
        {
         Bundle bundle = new Bundle();
        
         bundle.putParcelableArrayList("Fragdata",Songinfo);
         dv.setArguments(bundle);
         
        }
         
         
         
        
        
        if (Songinfo.size()>0)
        {
            
            for( j=0; j<Songinfo.size();j++)
            {
                for ( i=j+1 ; i<Songinfo.size(); i++)
                { 
                    SongDetails a=Songinfo.get(i);
                    SongDetails b=Songinfo.get(j);
                    if(a.getSong().toLowerCase().compareTo(b.getSong().toLowerCase())<0)
                    {   
                
                        Songinfo.set(i,b );
                        Songinfo.set(j,a);
                    }
                }
                
            }

            SngList.setOnItemClickListener(new OnItemClickListener() {
                 public void onItemClick(AdapterView a, View v, int position, long id) {
                                
                
                       Intent intent = new Intent(getActivity(), NowPlaying.class);
                       
                       intent.putParcelableArrayListExtra("Data1",Songinfo);
                       
                       intent.putExtra("Data2",position);
                       startActivity(intent);
                 
                             }
                     });
            
        
           SngList.setAdapter(new CustomAdapter(Songinfo));
           return view;
        }
        else return null;
              
    }
    public ArrayList<SongDetails> getSongsFromDirectory(File f)
        {MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        
            ArrayList<SongDetails> songs = new ArrayList<SongDetails>();
            Bitmap bitmap2; 
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ab);

            float ht_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
            float wt_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
            
            Bitmap bitmap3 = Bitmap.createScaledBitmap(bmp, (int) ht_px, (int) wt_px, true);
            byte[] rawArt = null;
            Bitmap art;
            BitmapFactory.Options bfo=new BitmapFactory.Options();
            if (!f.exists() || !f.isDirectory()) 
            {    
                return songs;
            }
            File[] files = f.listFiles(new Mp3Filter());
            for(int i=0; i<files.length; i++) 
            { 
                if (files[i].isFile())
                { 
                 mmr.setDataSource(files[i].getPath());
                 rawArt = mmr.getEmbeddedPicture();
                    SongDetails detail=new SongDetails(); 
                if ( rawArt != null) 
                    {   
                    bitmap2=BitmapFactory.decodeByteArray(rawArt, 0, rawArt.length, bfo);
                    bitmap2 = Bitmap.createScaledBitmap(bitmap2, (int) ht_px, (int) wt_px, true);
                     
                    detail.setIcon(bitmap2);
                }else 
            {   
                    detail.setIcon(bitmap3);
                }   
           
                    detail.setSong(files[i].getName()); 
           detail.setArtist(files[i].getName());
           detail.setArtist(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)); 
           if (mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)==null||(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)==""))
           {  detail.setArtist("Unknow Artist");   }
           detail.setAlbum(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)); 
           if (mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)==null||mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)=="")
           {  detail.setAlbum("Unknow Album");   }
           detail.setPath2( files[i].getPath()) ;
           songs.add(detail); 
                }
                else if (files[i].isDirectory())
                { 
                songs.addAll(getSongsFromDirectory(files[i])); 
                } 
         
            }       return songs;
    }
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) 
        {
                        super.onCreateContextMenu(menu, v, menuInfo);      
                       info = (AdapterContextMenuInfo) menuInfo;
                       menu.add(Menu.NONE, v.getId(), 0, "Play");
                       menu.add(Menu.NONE, v.getId(), 0, "Delete");
                       menu.add(Menu.NONE, v.getId(), 0, "Queue Item");                  
               }
                
        @Override
        public boolean onContextItemSelected(MenuItem item) {
                if (item.getTitle() == "Play") {
                  
                       }
                 else if (item.getTitle() == "Delete") {
                  
                       }
                      
                 else if (item.getTitle() == "Queue Item") {
                   
                       }
                 else     {
                       return false;
                       }
               return true;
               }}
    
    
        class Mp3Filter implements FileFilter
        {
            public boolean accept(File file)
            {
            return (file.isDirectory()||file.getName().endsWith(".mp3")|| file.getName().endsWith(".Mp3")||file.getName().endsWith(".wma")||file.getName().endsWith(".Wma")||file.getName().endsWith(".WMA")||file.getName().endsWith(".mp4"));
            }
        }
    

now here is the code for the adapter

public class CustomAdapter extends BaseAdapter {

    private ArrayList<SongDetails> _data;

    CustomAdapter (ArrayList<SongDetails> data){
        _data = data;
    }

    public int getCount() {

        return _data.size();
    }

    public Object getItem(int position) {

        return _data.get(position);
    }

    public long getItemId(int position) {

        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        Context context = parent.getContext();
        View v = convertView;

        if (v == null) {
           v = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        }
        SongDetails sng = _data.get(position);
        ImageView image = (ImageView) v.findViewById(R.id.icon);
        ImageView image2 = (ImageView) v.findViewById(R.id.icon);
        TextView SongView = (TextView)v.findViewById(R.id.Song);
        TextView AlbumView = (TextView)v.findViewById(R.id.Album);
        TextView ArtistView = (TextView)v.findViewById(R.id.Artist);
       /*ImageLoaderConfiguration config=new ImageLoaderConfiguration.Builder(context).build();
        ImageLoader imageloader=ImageLoader.getInstance();  
        imageloader.init(config);
        imageloader.displayImage( null, image2);
       */

        image.setImageBitmap(sng.icon);
        image2.setBackgroundResource(sng.icLauncher);
        SongView.setText(sng.song);
        AlbumView.setText(sng.Album);
        ArtistView.setText(sng.Artist);

        return v;
    }
}

Upvotes: 1

Views: 414

Answers (1)

Eugene S
Eugene S

Reputation: 3122

i can't understand where i should put this async task thing.

The AsyncTask should be used when you need your application to perform a long-running, and/or potentially blocking (e.g., file read) operation. The way you have it structured now, your application will seem to hang and be unresponsive because you're performing all these file reads on the main UI thread. This is where the AsyncTask comes in. When you use this class, your "work" is done on a separate thread, so that the UI can still respond while the work is going on.

You can find plenty of examples on how to properly use this class on this site, or by searching Google, or by checking the official documentation here.

You can write a custom AsyncTask class, instantiate it, and call its execute() method inside your activity's onCreate() method.

You will perform your file scans in the doInBackground() method of your AsyncTask and then deliver the final ArrayList back to the adapter (e.g., by calling adapter.addAll(yourSongListArray)) in the postExecute() method.

Hope that helps.

Upvotes: 2

Related Questions