带有 ListView Asynctask 的多下载器
Posted
技术标签:
【中文标题】带有 ListView Asynctask 的多下载器【英文标题】:Multi Downloader With ListView Asynctask 【发布时间】:2013-09-10 20:32:37 【问题描述】:我正在努力实现作为 android 的下载器应用程序,只是我无能为力。我想一次下载多个文件并在列表视图中显示每个文件的状态。
我创建了一个适配器并对其进行了全部配置,但是当我首先下载文件时,卸载第二个文件时一切正常,第一个崩溃,至少是这样的想法,因为第一次下载的列表视图上的数据是锁定。我想在列表视图中使用 AsyncTask 管理多个下载。我试过了,但我做不到。
我还为 AsyncTask 中使用的变量创建了数组。 如果要放置源的碎片。让我知道你想要哪一部分。
这是我的 Listview ArrayAdapter:
public class MYArrayAdapter extends ArrayAdapter<String>
//riferimenti statici alle risorse e agli id
private final static int LAYOUT = R.layout.item_view;
private final static int IMMAGINE = R.id.ColImgPath;
private final static int NAMEFILE = R.id.txt_namef;
private final static int VELOCITA = R.id.txt_velocita;
private final static int TIME = R.id.txt_timerima;
private final static int DIMTOT = R.id.txt_dimtota;
private final static int DIMRIM = R.id.txt_dimrim;
private final static int PERCENTUALE = R.id.txt_percent;
private final static int Progress = R.id.prg_progressbar;
//private final static int TITOLO = R.id.riga_listview_titolo;
//private final static int DESCRIZIONE = R.id.riga_listview_descrizione;
//ArrayList<String> IMMAGINE; //lista dei titoli
ArrayList<String> namefile;
ArrayList<String> velocita;
ArrayList<String> time;
ArrayList<String> dimtot;
ArrayList<String> dimrim;
ArrayList<String> percentuale;
ArrayList<String> percento;
//ArrayList<String> descrizioni;
//lista delle descrizioni
Context c; //context
LayoutInflater inflater; //layout inflater
public MYArrayAdapter(Context context, ArrayList<String> namefile, ArrayList<String> velocita,ArrayList<String> time,ArrayList<String> dimtot,ArrayList<String> dimrim,ArrayList<String> percentuale)
super(context,NAMEFILE);
this.c = context;
this.namefile = namefile;
this.velocita = velocita;
this.time = time;
this.dimtot = dimtot;
this.dimrim = dimrim;
this.percentuale = percentuale;
this.percento = percento;
this.inflater = LayoutInflater.from(c);
@Override
public int getCount()
return namefile.size(); //ritorno lunghezza lista ( = numero dei titoli)
//quando la lista richiede una view
@Override
public View getView(int pos,View view,ViewGroup parent)
CacheRiga cache; //cache
if(view==null)//se � la prima volta che viene richiesta la view
// creo la view ma non l'attacco alla lista in quanto devo ancora modificare
// i testi delle textview
view = inflater.inflate(LAYOUT, parent,false);
cache = new CacheRiga(); //inizializzo la cache
cache.namefile = (TextView) view.findViewById(NAMEFILE);
cache.velocita = (TextView) view.findViewById(VELOCITA);
cache.time = (TextView) view.findViewById(TIME);
cache.dimtot = (TextView) view.findViewById(DIMTOT);
cache.dimrim = (TextView) view.findViewById(DIMRIM);
cache.percentuale = (TextView) view.findViewById(PERCENTUALE);
cache.immagine = (ImageView) view.findViewById(IMMAGINE);
cache.progress = (ProgressBar) view.findViewById(Progress);
view.setTag(cache);//collego view con cache
else
cache = (CacheRiga) view.getTag(); //altrimenti prendo la cache dalla view
cache.namefile.setText(namefile.get(pos)); //imposto il titolo
cache.velocita.setText(velocita.get(pos)); // e la descrizione
cache.time.setText(time.get(pos)); //imposto il titolo
cache.dimtot.setText(dimtot.get(pos)); // e la descrizione
cache.dimrim.setText(dimrim.get(pos)); //imposto il titolo
cache.percentuale.setText(percentuale.get(pos)); // e la descrizione
cache.immagine.setImageResource(R.drawable.file); //imposto il titolo
cache.progress.setProgress((int) Tab_Download.progresso[pos]); // e la descrizione
return view;
private class CacheRiga // classe per la cache delle righe
public TextView namefile; // cache titolo
public TextView velocita; // cache descrizione
public TextView time; // cache titolo
public TextView dimtot;
public TextView dimrim; // cache titolo
public TextView percentuale;
public ImageView immagine; // cache titolo
public ProgressBar progress;
这是无效的 onProgressUpdate (AsyncTask):
speed[cont] = NANOS_PER_SECOND / BYTES_PER_MIB * totalRead[cont] / (System.nanoTime() - start[cont] + 1);
dimrim[cont] = ((((file_sizes[cont] * 1024) * 1024) - ((int) (totalRead[cont]))) / 1024) / 1024;
timerimas[cont] = (int) ((dimrim[cont] ) / speed[cont]);
ore[cont] = timerimas[cont] / 3600;
minuti[cont] = (timerimas[cont] % 3600) / 60;
secondi[cont] = timerimas[cont] - (ore[cont] * 3600) - (minuti[cont] * 60);
progresso[cont] = (totalRead[cont] * 100) / lenghtOfFile[cont];
velocita.set(cont,"Velocita' Download:" + df.format(speed[cont]) + "Mbyte/s");
namefile.set(cont,"Nome File:"+file_name[cont]);
time.set(cont,"Tempo Rimanente:"+ore[cont]+"H| "+ minuti[cont] +"M| " + secondi[cont]+"S ");
dimtot.set(cont,"Dimensione file:"+(file_sizes[cont]) + "MB");
dimrimas.set(cont,"Dimensione Rimanente:" + dimrim[cont] + "MB");
percentuale.set(cont, "Percentuale:" + progresso[cont] + "%");
//list.setAdapter(adapter);
adapter.notifyDataSetChanged();
【问题讨论】:
请发布一些代码,以及崩溃日志。 它不会崩溃,但我在 listview 上看不到 2 下载信息! 【参考方案1】:我在github上有一个AsyncHttpDownloader库,非常适合学习http下载。
这个库所做的正是使用 AsyncTask 管理多个下载。你可以看看代码。
第一步是创建一个图片下载回调方法并在你的适配器中下载图片。
/**
* This code is to update the progress bar in the listView
* @param view
* @param downloadUrl
* @param total
* @param progress
*/
public void updateDownloadProgress(View view, String downloadUrl, int total, int progress)
ViewHolder viewHolder = (ViewHolder)view.getTag();
DataItem dataItem = dataList.get(viewHolder.position);
// If the download urls not match, will not continue.
if (!dataItem.imageUrl.equals(downloadUrl)) return;
viewHolder.progressBar.setMax(total);
viewHolder.progressBar.setProgress(progress);
/**
* This code is to call to set the image to the view from the activity.
* @param view
* @param fileUrl
*/
public void setImageViewWhenDownloadFinished(View view, String downloadUrl, String fileUrl)
ViewHolder viewHolder = (ViewHolder)view.getTag();
// If the download urls not match, will not continue.
if (!dataItem.imageUrl.equals(downloadUrl)) return;
Bitmap bmp = BitmapFactory.decodeFile(fileUrl);
viewHolder.imageView.setImageBitmap(bmp);
@Override
public View getView(int position, View view, ViewGroup viewGroup)
// TODO Auto-generated method stub
ViewHolder viewHolder;
if (view == null)
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.example_layout, null);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView)view.findViewById(R.id.imageView);
viewHolder.progressBar = (ProgressBar)view.findViewById(R.id.progressBar);
view.setTag(viewHolder);
else
viewHolder = (ViewHolder)view.getTag();
viewHolder.position = position;
DataItem dataItem = dataList.get(position);
// Download the image file
AsyncHttpDownloader.getInstance().addDownloadTask(this, dataItem.imageUrl);
return view;
第二步是在你的活动上注册一个监听器
//Instantiate a new listener
AsyncHttpDownloaderListener downloaderListener = new AsyncHttpDownloaderListener(
new AsyncHttpDownloaderListener.Callback()
@Override
public void onProgressUpdate(String downloadUrl, int total, int completed)
// Update to progress bar
for (int i = 0; i < listView.getChildCount(); i++)
adapter.updateDownloadProgress(listView.getChildAt(i), downloadUrl, total, completed);
@Override
public void onFailed(String downloadUrl, String errorMessage)
@Override
public void onSuccess(String downloadUrl, File file)
//When the download finished, the assign the image to the imageView
for (int i = 0; i < listView.getChildCount(); i++)
adapter.setImageViewWhenDownloadFinished(listView.getChildAt(i), file.getAbsolutePath());
);
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
downloaderListener.register(this);
最后不要忘记取消注册您的活动销毁的监听器
@Override
public void onDestroy()
downloaderListener.unregister(this);
// When the activity is destroyed, cancel all running tasks if you want.
// If you don't cancel, it will run in the background until all tasks are
// done, when you open the activity again, you can still see the running task.
AsyncHttpDownloader.getInstance().cancelAllRunningTasks();
super.onDestroy();
在 *** 上写代码有点难啊。
【讨论】:
以上是关于带有 ListView Asynctask 的多下载器的主要内容,如果未能解决你的问题,请参考以下文章
AsyncTask 完成后 ListView 上的 setOnItemClickListener
即使 Activity 已销毁,AsyncTask 也不会停止