简体   繁体   English

具有ListView Asynctask的多下载器

[英]Multi Downloader With ListView Asynctask

I'm trying to achieve as a downloader app for Android, only that I can not do a thing. 我试图实现作为Android的下载器应用程序,只是我不能做任何事情。 I would like to download multiple files at a time and to display the status of under each in a listview. 我想一次下载多个文件,并在列表视图中显示每个文件的状态。

I created an Adapter and configuring it all, but when I go to download the files first everything works when unloading the second, the first crashes, at least by the idea that, because the data on the listview of the first download are locked. 我创建了一个Adapter并对其进行了全部配置,但是当我首先下载文件时,卸载第二个文件时一切正常,第一个崩溃,至少是因为这样的想法,因为第一次下载的listview上的数据已锁定。 I would like to manage multiple downloads using AsyncTask in a listview. 我想在列表视图中使用AsyncTask管理多个下载。 I tried but I can not. 我尝试过,但不能。

I also created arrays for the variables used in the AsyncTask. 我还为AsyncTask中使用的变量创建了数组。 If you want to place the pieces of the source. 如果要放置源的碎片。 Let me know which part you want. 让我知道你想要哪一部分。

THis is my ArrayAdapter for Listview: 这是我的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;
    }

} This is void onProgressUpdate (AsyncTask): 这是无效的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();

I have a AsyncHttpDownloader library on github, it is a very example to learn http downloads. 我在github上有一个AsyncHttpDownloader库,这是学习http下载的一个很好的例子。

What this library does is exactly to manage multiple downloads using AsyncTask. 该库的作用是使用AsyncTask来管理多个下载。 You can have a look at the code. 您可以看一下代码。

First step is create an image download callback method and download the image inside your adapter. 第一步是创建映像下载回调方法,然后在适配器中下载映像。

    /**
     * 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;
    }

Second step is register a listener on your activity 第二步是注册活动监听器

//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);
}

and finally don't forget to unregister the listener on your activity destroy 最后不要忘了取消注册,以免破坏活动

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

Writing codes on Stackoverflow is kind of hard huh. 在Stackoverflow上编写代码有点困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM