2

我试图实现作为 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();
4

1 回答 1

0

我在 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();
}

在 Stackoverflow 上写代码有点难啊。

于 2015-09-06T09:41:37.607 回答