繁体   English   中英

Android-在4.0+设备AsyncTask上下载失败

[英]Android - download failed at 4.0+ devices AsyncTask

我有一个AsyncTask来一步一步下载文件,当它在android 2.x上运行时,我将它作为队列。 在android 4.0+中,它停止工作。 在这里,我向AsyncTask传递了一个ProgressBar,因此它将更新加载进度栏,并指示其位置。

奇怪的是进度条会非常快地100%匹配文件的实际大小。 而且logcat中文件输出的长度也出错了...

所有任务将串行执行,因此不会损害SDK 11上方的并行限制。我想问题可能出在下载部分,只是不知道它在哪里。

public function download ()
{
    .....
    if (task != null) {
        task.cancel (true);
    }
    task = new OnlineDownloadTask (progress);
    task.execute (url, path);
    .....
}

class OnlineDownloadTask extends AsyncTask<String, String, String> {

        private final WeakReference<OfflineQueueIndicatorView> progressbarReference;

        public OnlineDownloadTask(OfflineQueueIndicatorView progress) {
            progressbarReference = new WeakReference<OfflineQueueIndicatorView>(
                    progress);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... aurl) {
            int count;

            try {

                URL url = new URL(aurl[0]);
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(10000);
                conn.setRequestMethod("GET");
                conn.setAllowUserInteraction(false);
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.connect();

                int lengthOfFile = conn.getContentLength();

                android.util.Log.v("offline.downloader", lengthOfFile + "");
                InputStream input = new BufferedInputStream(url.openStream());
                OutputStream output = new FileOutputStream(aurl[1]);

                try {
                    byte data[] = new byte[1024];

                    long total = 0;

                    while ((count = input.read(data)) != -1) {
                        total += count;
                        publishProgress(""
                                + (int) ((total * 100) / lengthOfFile));

                        if (stopoffline) {
                            android.util.Log.v("file.downloader", "stopped");
                            break;
                        }
                        output.write(data, 0, count);
                    }

                    if (stopoffline) {
                        output.flush();
                        output.close();
                        input.close();
                        conn.disconnect();
                        File file = new File(aurl[1]);

                        if (file.exists()) {
                            file.delete();
                        }

                        stopoffline = false;
                        return null;
                    } else {
                        output.flush();
                        output.close();
                        input.close();
                        conn.disconnect();

                        if (DiskCache.getInstance().offlineDirectoryExist(
                                DiskCache.getInstance().offlineCurrentFolder)) {

                        } else {
                            if (!DiskCache
                                    .getInstance()
                                    .makeOfflineFolder(
                                            DiskCache.getInstance().offlineCurrentFolder)) {
                                return null;
                            }
                        }

                        android.util.Log.v("offline",
                                DiskCache.getInstance().offlineCurrentFolder);
                        unzip(aurl[1],
                                DiskCache.getInstance().offlineCurrentFolder);
                        DiskCache.getInstance().deleteFile(aurl[1]);
                        return "succ";
                    }

                } finally {

                    if (output != null) {
                        output.flush();
                        output.close();
                    }

                    if (input != null) {

                        input.close();
                    }

                    if (conn != null) {
                        conn.disconnect();
                    }
                }
            } catch (Exception e) {

                e.printStackTrace();

            }
            return null;

        }

        protected void onProgressUpdate(String... progress) {
            try {
                if (progressbarReference != null) {
                    OfflineQueueIndicatorView p = progressbarReference.get();

                    if (p != null) {
                        int i = Integer.parseInt(progress[0]);
                        p.setProgress(i);
                    }
                }
            }

            catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onPostExecute(String ret) {

            try {
                if (progressbarReference != null) {

                    if (ret != null) {
                        queue.get(currentId).put("state", "complete");
                    } else {
                        if (queue != null) {
                            if (currentId != null) {
                                queue.get(currentId).put("state", "failed");
                            }
                        }
                    }

                }
            }

            catch (Exception e) {
                e.printStackTrace();
            }

            download();

        }
    }

Android 4.0中较新版本的HttpUrlConnection可能导致服务器使用Chunked Transfer Encoding (在HTTP / 1.1中受支持)。 Android 2.x版本可能不支持CTE。 当发送带有CTE的响应时(例如,在文件/视频流期间),服务器将不返回内容长度。 因此,当内容长度不可用时,您可能想显示一个不确定的ProgressBar

在删除conn.setDoOutput(true) ,我终于找到了问题conn.setDoOutput(true) ,它在android 2.x和4.x模拟器上都能正常工作,我认为acj也很重要,有时Chunked Transfer Encoding也是原因。

暂无
暂无

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

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