我正在开发一个音乐应用程序,我的应用程序需要花费大量时间来生成音乐文件列表(因为它必须生成位图)所以我搜索网络并了解了asynctask,我能够在我遇到的另一个问题上成功地实现了它(所以我认为我理解它背后的逻辑)但在这种情况下我只是想办法如何做到这一点,(
所以请我帮忙。 这是程序背后的逻辑
我有一个“SongDetails”类,其中包含以下元素
Bitmap icon;
String song;
String Artist;
String Album;
String Path;
我创建了一个SongDetails的arraylist 现在我有另一个名为getSongsFromDirectory的类来搜索音乐文件, 从中获取相册和艺术家信息,并将每个项目添加到ArrayList,并在生成列表时将列表返回到onCreate方法。现在onCreate方法按歌曲名称对列表进行排序,然后将列表提供给自定义显示结果的适配器,我无法理解我应该把这个异步任务放在哪里...........这里是我用过的代码
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"));
}
}
现在这里是适配器的代码
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;
}
}
答案 0 :(得分:2)
我无法理解我应该把这个异步任务放在哪里。
当您需要应用程序执行长时间运行和/或可能阻塞(例如,文件读取)操作时,应使用AsyncTask
。现在你的结构方式,你的应用程序似乎挂起并没有响应,因为你在主UI线程上执行所有这些文件读取。这就是AsyncTask
的用武之地。当你使用这个类时,你的“工作”是在一个单独的线程上完成的,这样UI在工作进行时仍然可以响应。
您可以找到大量有关如何在本网站上正确使用此课程,或通过搜索Google,或查看官方文档here的示例。
您可以编写自定义AsyncTask
类,对其进行实例化,并在活动的execute()
方法中调用其onCreate()
方法。
您将使用doInBackground()
的{{1}}方法执行文件扫描,然后将最终的AsyncTask
发送回适配器(例如,通过调用ArrayList
) adapter.addAll(yourSongListArray)
方法。
希望有所帮助。