Android列表视图中的多个下载暂停恢复,包含进度更新

ing*_*abh 6 android download android-asynctask

我正在尝试使用progressbar下载listview中的多个文件.我所取得的成就是,我可以开始特定下载,使用AsyncTask暂停/恢复它并更新进度条(对于单个文件),这部分效果很好

我的问题是我无法同时下载多个文件,当我将listview留到另一个屏幕时,虽然我的下载是在后台进行但进度没有更新,进度条显示0进度,好像它没有下载但是已经在后台下载.

ing*_*abh 4

最后我找到了答案,比我想象的要简单得多,如下

  1. 创建一个用于下载和值的service对象(url,Asynctask)Asynctaskhashtable
  2. 单击列表项时传递值(url,Asynctask),并检查该哈希表是否已包含该值,如果是,则取消该 Asynctask 任务,如果不存在,则将其添加到哈希表并启动 Asynctask
  3. 现在为了更新我的进度,adapter我运行了一个线程,它使用 迭代hashtable并传递值BroadcastListener
  4. 并在活动中拦截broadcast并根据ListItem可见更新进度

PS:如果有人需要一些代码,我可以提供上述描述的基本代码

public class DownloadingService extends Service {
public static String PROGRESS_UPDATE_ACTION = DownloadingService.class.getName() + ".progress";

private static final long INTERVAL_BROADCAST = 800;
private long mLastUpdate = 0;
private Hashtable<String, DownloadFile> downloadTable;

private LocalBroadcastManager broadcastManager;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    MessageEntity entityRecieved = (MessageEntity) intent.getSerializableExtra("ENTITY");
    queueDownload(entityRecieved);
    return super.onStartCommand(intent, flags, startId);
}

private void queueDownload(MessageEntity entityRecieved){
    if (downloadTable.containsKey(entityRecieved.getPacketID())) {
        DownloadFile downloadFile = downloadTable.get(entityRecieved.getPacketID());
        if (downloadFile.isCancelled()) {
            downloadFile = new DownloadFile(entityRecieved);
            downloadTable.put(entityRecieved.getPacketID(), downloadFile);
            startDownloadFileTask(downloadFile);
        } else {
            downloadFile.cancel(true);
            downloadTable.remove(entityRecieved.getPacketID());
        }

    } else {
        DownloadFile downloadFile = new DownloadFile(entityRecieved);
        downloadTable.put(entityRecieved.getPacketID(), downloadFile);
        startDownloadFileTask(downloadFile);
    }
}

@Override
public void onCreate() {
    super.onCreate();
    downloadTable = new Hashtable<String, DownloadFile>();
    broadcastManager = LocalBroadcastManager.getInstance(this);
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
void startDownloadFileTask(DownloadFile asyncTask) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    else
        asyncTask.execute();
}

private void publishCurrentProgressOneShot(boolean forced) {
    if (forced || System.currentTimeMillis() - mLastUpdate > INTERVAL_BROADCAST) {
        mLastUpdate = System.currentTimeMillis();
        int[] progresses = new int[downloadTable.size()];
        String[] packetIds = new String[downloadTable.size()];
        int index = 0;
        Enumeration<String> enumKey = downloadTable.keys();
        while (enumKey.hasMoreElements()) {
            String key = enumKey.nextElement();
            int val = downloadTable.get(key).progress;
            progresses[index] = val;
            packetIds[index++] = key;
        }
    Intent i = new Intent();
    i.setAction(PROGRESS_UPDATE_ACTION);
    i.putExtra("packetIds", packetIds);
    i.putExtra("progress", progresses);
    mBroadcastManager.sendBroadcast(i);
}

class DownloadFile extends AsyncTask<Void, Integer, Void> {
    private MessageEntity entity;
    private File file;
    private int progress;

    public DownloadFile(MessageEntity entity) {
        this.entity = entity;
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        String filename = entity.getMediaURL().substring(entity.getMediaURL().lastIndexOf('/') + 1);
        file = new File(FileUtil.getAppStorageDir().getPath(), filename);
        downloadFile(entity.getMediaURL(), file); 
        return null;
    }

    public String downloadFile(String download_file_path, File file) {
        int downloadedSize = 0;
        int totalSize = 0;
        try {
            // download the file here
            while ((bufferLength = inputStream.read(buffer)) > 0 && !isCancelled()) {

                progress = percentage;
                publishCurrentProgressOneShot(true);
            }


        } catch (final Exception e) {
            return null;
        }

        return file.getPath();
    }

}
Run Code Online (Sandbox Code Playgroud)