下载android大文件

发布于 2024-10-20 18:57:33 字数 868 浏览 2 评论 0原文

当我尝试此代码时,它开始下载,但随后出现警报“强制关闭” 我应该怎么办?使用某种后台线程?

try {
    long startTime = System.currentTimeMillis();

    URL u = new URL("http://file.podfm.ru/3/33/332/3322/mp3/24785.mp3");
    HttpURLConnection c = (HttpURLConnection) u.openConnection();

    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File("/sdcard/","logo.mp3"));

    InputStream in = c.getInputStream();

    byte[] buffer = new byte[1024];
    int len1 = 0;
    while ( (len1 = in.read(buffer)) != -1 ) {
        f.write(buffer,0, len1);
    }
    f.close();

    Log.d("ImageManager", "download ready in" +
        ((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
    Log.d("ImageManager", "Error" +
        ((System.currentTimeMillis()) / 1000) + e + " sec");
}

When I try this code, it starts download but then stuck with alert "force close"
what should I do? Use some kind of background thread?

try {
    long startTime = System.currentTimeMillis();

    URL u = new URL("http://file.podfm.ru/3/33/332/3322/mp3/24785.mp3");
    HttpURLConnection c = (HttpURLConnection) u.openConnection();

    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File("/sdcard/","logo.mp3"));

    InputStream in = c.getInputStream();

    byte[] buffer = new byte[1024];
    int len1 = 0;
    while ( (len1 = in.read(buffer)) != -1 ) {
        f.write(buffer,0, len1);
    }
    f.close();

    Log.d("ImageManager", "download ready in" +
        ((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
    Log.d("ImageManager", "Error" +
        ((System.currentTimeMillis()) / 1000) + e + " sec");
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谁的年少不轻狂 2024-10-27 18:57:33

我上周正在处理类似的问题,最终使用 AsyncTask 显示进度条,因为下载文件可能需要一些时间。一种方法是将下面的类嵌套在您的 Activity 中,然后在您需要的地方调用它,就像这样:

new DownloadManager().execute("here be URL", "here be filename");

或者如果该类不在活动中并从活动调用。

new DownloadManager(this).execute("URL", "filename");

这传递了活动,因此我们可以访问方法 getSystemService();

这是完成所有肮脏工作的实际代码。您可能需要根据需要修改它。

private class DownloadManager extends AsyncTask<String, Integer, Drawable>
{

    private Drawable d;
    private HttpURLConnection conn;
    private InputStream stream; //to read
    private ByteArrayOutputStream out; //to write
    private Context mCtx;

    private double fileSize;
    private double downloaded; // number of bytes downloaded
    private int status = DOWNLOADING; //status of current process

    private ProgressDialog progressDialog;

    private static final int MAX_BUFFER_SIZE = 1024; //1kb
    private static final int DOWNLOADING = 0;
    private static final int COMPLETE = 1;

    public DownloadManager(Context ctx)
    {
        d          = null;
        conn       = null;
        fileSize   = 0;
        downloaded = 0;
        status     = DOWNLOADING;
        mCtx       = ctx;
    }

    public boolean isOnline()
    {
        try
        {
            ConnectivityManager cm = (ConnectivityManager)mCtx.getSystemService(Context.CONNECTIVITY_SERVICE);
            return cm.getActiveNetworkInfo().isConnectedOrConnecting(); 
        }
        catch (Exception e)
        {
            return false;
        }
    }

    @Override
    protected Drawable doInBackground(String... url)
    {
        try
        {
            String filename = url[1];
            if (isOnline())
            {
                conn     = (HttpURLConnection) new URL(url[0]).openConnection();
                fileSize = conn.getContentLength();
                out      = new ByteArrayOutputStream((int)fileSize);
                conn.connect();

                stream = conn.getInputStream();
                // loop with step
                while (status == DOWNLOADING)
                {
                    byte buffer[];

                    if (fileSize - downloaded > MAX_BUFFER_SIZE)
                    {
                        buffer = new byte[MAX_BUFFER_SIZE];
                    }
                    else
                    {
                        buffer = new byte[(int) (fileSize - downloaded)];
                    }
                    int read = stream.read(buffer);

                    if (read == -1)
                    {
                        publishProgress(100);
                        break;
                    }
                    // writing to buffer
                    out.write(buffer, 0, read);
                    downloaded += read;
                    // update progress bar
                    publishProgress((int) ((downloaded / fileSize) * 100));
                } // end of while

                if (status == DOWNLOADING)
                {
                    status = COMPLETE;
                }
                try
                {
                    FileOutputStream fos = new FileOutputStream(filename);
                    fos.write(out.toByteArray());
                    fos.close();
                }
                catch ( IOException e )
                {
                    e.printStackTrace();
                    return null;
                }

                d = Drawable.createFromStream((InputStream) new ByteArrayInputStream(out.toByteArray()), "filename");
                return d;
            } // end of if isOnline
            else
            {
                return null;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }// end of catch
    } // end of class DownloadManager()

    @Override
    protected void onProgressUpdate(Integer... changed)
    {
        progressDialog.setProgress(changed[0]);
    }

    @Override
    protected void onPreExecute()
    {
        progressDialog = new ProgressDialog(/*ShowContent.this*/); // your activity
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMessage("Downloading ...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected void onPostExecute(Drawable result)
    {
        progressDialog.dismiss();
        // do something
    }
}

I was dealing with similar problem last week and ended up using AsyncTask with progress bar displayed since it could take some time for the file to be downloaded. One way of doing it is to have below class nested in your Activity and just call it where you need to simply like this:

new DownloadManager().execute("here be URL", "here be filename");

Or if the class is not located within an activity and calling from an activity..

new DownloadManager(this).execute("URL", "filename");

This passes the activity so we have access to method getSystemService();

Here is the actual code doing all the dirty work. You will probably have to modify it for your needs.

private class DownloadManager extends AsyncTask<String, Integer, Drawable>
{

    private Drawable d;
    private HttpURLConnection conn;
    private InputStream stream; //to read
    private ByteArrayOutputStream out; //to write
    private Context mCtx;

    private double fileSize;
    private double downloaded; // number of bytes downloaded
    private int status = DOWNLOADING; //status of current process

    private ProgressDialog progressDialog;

    private static final int MAX_BUFFER_SIZE = 1024; //1kb
    private static final int DOWNLOADING = 0;
    private static final int COMPLETE = 1;

    public DownloadManager(Context ctx)
    {
        d          = null;
        conn       = null;
        fileSize   = 0;
        downloaded = 0;
        status     = DOWNLOADING;
        mCtx       = ctx;
    }

    public boolean isOnline()
    {
        try
        {
            ConnectivityManager cm = (ConnectivityManager)mCtx.getSystemService(Context.CONNECTIVITY_SERVICE);
            return cm.getActiveNetworkInfo().isConnectedOrConnecting(); 
        }
        catch (Exception e)
        {
            return false;
        }
    }

    @Override
    protected Drawable doInBackground(String... url)
    {
        try
        {
            String filename = url[1];
            if (isOnline())
            {
                conn     = (HttpURLConnection) new URL(url[0]).openConnection();
                fileSize = conn.getContentLength();
                out      = new ByteArrayOutputStream((int)fileSize);
                conn.connect();

                stream = conn.getInputStream();
                // loop with step
                while (status == DOWNLOADING)
                {
                    byte buffer[];

                    if (fileSize - downloaded > MAX_BUFFER_SIZE)
                    {
                        buffer = new byte[MAX_BUFFER_SIZE];
                    }
                    else
                    {
                        buffer = new byte[(int) (fileSize - downloaded)];
                    }
                    int read = stream.read(buffer);

                    if (read == -1)
                    {
                        publishProgress(100);
                        break;
                    }
                    // writing to buffer
                    out.write(buffer, 0, read);
                    downloaded += read;
                    // update progress bar
                    publishProgress((int) ((downloaded / fileSize) * 100));
                } // end of while

                if (status == DOWNLOADING)
                {
                    status = COMPLETE;
                }
                try
                {
                    FileOutputStream fos = new FileOutputStream(filename);
                    fos.write(out.toByteArray());
                    fos.close();
                }
                catch ( IOException e )
                {
                    e.printStackTrace();
                    return null;
                }

                d = Drawable.createFromStream((InputStream) new ByteArrayInputStream(out.toByteArray()), "filename");
                return d;
            } // end of if isOnline
            else
            {
                return null;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }// end of catch
    } // end of class DownloadManager()

    @Override
    protected void onProgressUpdate(Integer... changed)
    {
        progressDialog.setProgress(changed[0]);
    }

    @Override
    protected void onPreExecute()
    {
        progressDialog = new ProgressDialog(/*ShowContent.this*/); // your activity
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMessage("Downloading ...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected void onPostExecute(Drawable result)
    {
        progressDialog.dismiss();
        // do something
    }
}
七颜 2024-10-27 18:57:33

您应该尝试使用 AsyncTask。您收到强制退出对话框是因为您尝试在 UI 线程上执行过多的工作,并且 Android 判断您的应用程序已变得无响应。

这个问题的答案有一些很好的链接。

类似下面的内容将是一个好的开始:

private class DownloadLargeFileTask extends AsyncTask<Void, Void, Void> {
     private final ProgressDialog dialog;

     public DownloadLargeFileTask(ProgressDialog dialog) {
          this.dialog = dialog;
     }

     protected void onPreExecute() {
         dialog.show();
     }

     protected void doInBackground(Void... unused) {
         downloadLargeFile();
     }

     protected void onPostExecute(Void unused) {
         dialog.dismiss();
     }
 }

然后使用以下命令执行任务:

ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Loading. Please Wait...");
new DownloadLargeFileTask(dialog).execute();

You should try using an AsyncTask. You are getting the force quit dialog because you are trying to do too much work on the UI thread and Android judges that your application has become unresponsive.

The answers to this question have some good links.

Something like the following would be a good start:

private class DownloadLargeFileTask extends AsyncTask<Void, Void, Void> {
     private final ProgressDialog dialog;

     public DownloadLargeFileTask(ProgressDialog dialog) {
          this.dialog = dialog;
     }

     protected void onPreExecute() {
         dialog.show();
     }

     protected void doInBackground(Void... unused) {
         downloadLargeFile();
     }

     protected void onPostExecute(Void unused) {
         dialog.dismiss();
     }
 }

and then execute the task with:

ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Loading. Please Wait...");
new DownloadLargeFileTask(dialog).execute();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文