试图让下载的文件大小,但得到一个错误 [英] Trying to get downloading file size, but get an error

查看:101
本文介绍了试图让下载的文件大小,但得到一个错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 私有类DownloadLargeFileTask扩展的AsyncTask<虚空,虚空,虚空>
{
    私人最终ProgressDialog对话框;

    公共DownloadLargeFileTask(ProgressDialog对话){
         this.dialog =对话框;
    }

    在preExecute保护无效(){
        dialog.show();
    }


    保护无效onPostExecute(作废不用){
        dialog.dismiss();
    }

    @覆盖
    保护无效doInBackground(虚空......为arg0){
        下载();
        返回null;
    }
}

私人无效下载()
{
    尝试
    {
        长的startTime = System.currentTimeMillis的();

        网址U =新的URL(http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3);
        HttpURLConnection的C =(HttpURLConnection类)u.openConnection();

        c.setRequestMethod(GET);
        c.setDoOutput(真正的);
        c.connect();
        FileOutputStream中F =新的FileOutputStream(新文件(/ SD卡/,​​my.mp3));

        在的InputStream = c.getInputStream();

        byte []的缓冲区=新的字节[1024];
        INT LEN1 = 0;
        INT downloadedSize = 0;
        而((LEN1 = in.read(缓冲液))!=  -  1)
        {
          f.write(缓冲液,0,LEN1);
          downloadedSize + = LEN1;
          ReturnDownloadedBytes(downloadedSize);
        }
        f.close();
        Log.d(ImageManager,下载准备在+((System.currentTimeMillis的() - 的startTime)/ 1000)+秒);
    }
    赶上(IOException异常E)
    {
        Log.d(ImageManager,错误+((System.currentTimeMillis的())/ 1000)+ E +SEC);
    }
}

私人无效ReturnDownloadedBytes(INT尺寸)
{
    text.setText(将String.valueOf(大小));

}
 

错误说:只有创建视图层次可以触摸其观点原来的线程。 我想这意味着我创建从一个therad的TextView,并试图从另一个(AsyncTask的)的访问,但怎么走呢? 谢谢

修改
这里是所有code。但即使我发送 publishProgress(downloadedSize)int值= 10 它alwys在输出text.setText(将String.valueOf(进度)); 不同的值,例如 [Ljava.lang.float; @ 43ed62f78

 公共类列表扩展活动{

私人TextView的文字;



@覆盖
公共无效的onCreate(包冰柱)
{
    super.onCreate(冰柱);
    的setContentView(R.layout.main);

    文=(TextView的)findViewById(R.id.result);
}

公共无效selfDestruct(查看视图){

    ProgressDialog对话框=新ProgressDialog(本);
    dialog.setMessage(???????? ????? ......。);
    新DownloadLargeFileTask(对话).execute();

}


私有类DownloadLargeFileTask扩展的AsyncTask<太虚,整型,太虚>
{
    私人最终ProgressDialog对话框;

    公共DownloadLargeFileTask(ProgressDialog对话){
         this.dialog =对话框;
    }

    在preExecute保护无效(){
        dialog.show();
    }


    保护无效onPostExecute(作废不用){
        dialog.dismiss();
    }

    保护无效onProgressUpdate(整数...进度){

        text.setText(将String.valueOf(进度));

    }

    @覆盖
    保护无效doInBackground(虚空......为arg0){
        尝试
        {
            长的startTime = System.currentTimeMillis的();

            网址U =新的URL(http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3);
            HttpURLConnection的C =(HttpURLConnection类)u.openConnection();

            c.setRequestMethod(GET);
            c.setDoOutput(真正的);
            c.connect();
            FileOutputStream中F =新的FileOutputStream(新文件(/ SD卡/,​​my.mp3));

            在的InputStream = c.getInputStream();

            byte []的缓冲区=新的字节[1024];
            INT LEN1 = 0;
            INT downloadedSize = 10;
            而((LEN1 = in.read(缓冲液))!=  -  1)
            {
              f.write(缓冲液,0,LEN1);
              // downloadedSize + = LEN1;
              ** publishProgress(downloadedSize)**
            }
            f.close();
            Log.d(ImageManager,下载准备在+((System.currentTimeMillis的() - 的startTime)/ 1000)+秒);
        }
        赶上(IOException异常E)
        {
            Log.d(ImageManager,错误+((System.currentTimeMillis的())/ 1000)+ E +SEC);
        }
        返回null;
    }
}
 

解决方案

您在你的错误的评估是正确的。我假设文本是在活动定义的<一个的TextView 对象/ code>,因此它在UI线程创建的。在运行的code doInBackground()运行在一个单独的线程。只有UI线程可以执行更新UI元素,所以当你试图调用的setText 您得到您报告的错误消息。

阿比纳夫也是如何解决的问题,因为的AsyncTask 有,你可以调用从后台线程到UI线程发送更新的方法正确: publishProgress ,要求 onProgressUpdate()

添加此方法的的AsyncTask

  @覆盖
保护无效onProgressUpdate(整数...整数){
    text.setText(整数[0]的ToString());
}
 

和修改,而环路下载()

 ,而((LEN1 = in.read(缓冲))!= -1)
{
  f.write(缓冲液,0,LEN1);
  downloadedSize + = LEN1;
  publishProgress(downloadedSize);
}
 

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 onPostExecute(Void unused) {
        dialog.dismiss();
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        download();
        return null;
    }
}

private void download ()
{
    try 
    {
        long startTime = System.currentTimeMillis();

        URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
        HttpURLConnection c = (HttpURLConnection) u.openConnection();

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

        InputStream in = c.getInputStream();

        byte[] buffer = new byte[1024];
        int len1 = 0;
        int downloadedSize = 0;
        while ( (len1 = in.read(buffer)) != -1 ) 
        {
          f.write(buffer,0, len1);
          downloadedSize += len1; 
          ReturnDownloadedBytes(downloadedSize);
        }
        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");
    }
}

private void ReturnDownloadedBytes(int size)
{
    text.setText(String.valueOf(size));

}

Error says: Only the original thread that created a view hierarchy can touch its views. i think this means that i create textview from one therad and trying to get access from another one (AsyncTask) but how to get it? Thanks

EDIT
here is the all code. but even if i send in publishProgress(downloadedSize) int value = 10 it alwys outputs in text.setText(String.valueOf(progress)); different values like [Ljava.lang.float;@43ed62f78

public class list extends Activity {

private TextView text;



@Override
public void onCreate(Bundle icicle)
{
    super.onCreate(icicle);
    setContentView(R.layout.main);

    text = (TextView)findViewById(R.id.result);
}

public void selfDestruct(View view) {

    ProgressDialog dialog = new ProgressDialog(this);
    dialog.setMessage("????????. ?????...");
    new DownloadLargeFileTask(dialog).execute();

}


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

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

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


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

    protected void onProgressUpdate(Integer...progress) {

        text.setText(String.valueOf(progress));

    }

    @Override
    protected Void doInBackground(Void... arg0) {
        try 
        {
            long startTime = System.currentTimeMillis();

            URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
            HttpURLConnection c = (HttpURLConnection) u.openConnection();

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

            InputStream in = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            int downloadedSize = 10;
            while ( (len1 = in.read(buffer)) != -1 ) 
            {
              f.write(buffer,0, len1);
              //downloadedSize += len1; 
              **publishProgress(downloadedSize);**
            }
            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");
        }
        return null;
    }
}

解决方案

You are correct in your assessment of the error. I'm assuming that text is a TextView object that is defined in your Activity, and as such it is created in the UI thread. The code that runs within doInBackground() runs in a separate thread. Only the UI thread can perform updates to UI elements, so when you try to call setText you get the error message that you reported.

Abhinav is also correct in how to fix the issue, as AsyncTask has a method that you can call to send updates from the background thread to the UI thread: publishProgress, which calls onProgressUpdate().

Add this method to your AsyncTask:

@Override
protected void onProgressUpdate(Integer... integer){
    text.setText(integer[0].toString());
}

And change the while loop in download():

while ( (len1 = in.read(buffer)) != -1 ) 
{
  f.write(buffer,0, len1);
  downloadedSize += len1; 
  publishProgress(downloadedSize);
}

这篇关于试图让下载的文件大小,但得到一个错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆