Android “如何避免例外情况”;只有创建视图层次结构的原始线程才能接触其视图;?

Android “如何避免例外情况”;只有创建视图层次结构的原始线程才能接触其视图;?,android,android-asynctask,Android,Android Asynctask,我正在使用AsyncTask下载视频文件,我正在AsyncTask中更新视图,但出现异常“只有创建视图层次结构的原始线程才能接触其视图”。这是我的示例代码。请检查并建议我需要更正的地方 例外情况出现在这些行中 tvPercent.setText((int)per + "%"); tvSpeed.setText(networkSpeed+"kbps"); 异步任务类 public class DownloadFileFromURL extends AsyncTask<String, Str

我正在使用
AsyncTask
下载视频文件,我正在
AsyncTask
中更新视图,但出现异常“只有创建视图层次结构的原始线程才能接触其视图”。这是我的示例代码。请检查并建议我需要更正的地方

例外情况出现在这些行中

tvPercent.setText((int)per + "%");
tvSpeed.setText(networkSpeed+"kbps");
异步任务类

public class DownloadFileFromURL extends AsyncTask<String, String, String> {

    ProgressBar ProgBar;
    TextView tvSpeed; 
    TextView tvPercent;

    int downloadedSize = 0;
    int totalSize = 0;

    private long networkSpeed;      
    private long previousTime;
    private long totalTime;

//  public DownloadFileFromURL(ProgressBar pb)
//  {
//      ProgBar = pb;
//      
//  }

    public DownloadFileFromURL(ProgressBar pb, TextView speed, TextView per)
    {
        ProgBar = pb;
        tvSpeed = speed;
        tvPercent = per;
    }


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

        ProgBar.setProgress(0);
        //ProgBar.setMax(100);

        previousTime = System.currentTimeMillis();
    }


    @Override
    protected String doInBackground(String... videoURL) 
    {
        try 
        {

            URL url = new URL(videoURL[0]);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);

            //connect
            urlConnection.connect();

            File file = getOutputMediaFile(videoURL[0]);

            FileOutputStream fileOutput = new FileOutputStream(file);

            //Stream used for reading the data from the internet
            InputStream inputStream = urlConnection.getInputStream();

            //this is the total size of the file which we are downloading
            totalSize = urlConnection.getContentLength();

            Log.e("Download", ""+totalSize);

            ProgBar.setMax(totalSize);




          //create a buffer...
            byte[] buffer = new byte[1024];
            int bufferLength = 0;

            while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
            {
                fileOutput.write(buffer, 0, bufferLength);
                downloadedSize += bufferLength;



                // update the progressbar //
                ProgBar.setProgress(downloadedSize);



                float per = ((float)downloadedSize/totalSize) * 100;
                // update the progress in percentage //
                tvPercent.setText((int)per + "%");


                totalTime = System.currentTimeMillis() - previousTime;
                networkSpeed = downloadedSize / totalTime;

                 // update network speed //
                tvSpeed.setText(networkSpeed+"kbps");




            }

          //close the output stream when complete //
            fileOutput.close();
            downloadedSize = 0;
            totalSize = 0;




        } 
        catch (final MalformedURLException e) 
        {       
            e.printStackTrace();
        } 
        catch (final IOException e) 
        {         
            e.printStackTrace();
        }
        catch (final Exception e) 
        {
            e.printStackTrace();
        } 

        return null;
    }


    protected void onProgressUpdate(String... progress) 
    {
        // setting progress percentage
        //ProgBar.setProgress(Integer.parseInt(progress[0]));
    }


    @Override
    protected void onPostExecute(String file_url)
    {

    }




}
public类下载filefromURL扩展异步任务{
ProgressBar-ProgBar;
TextView-tvSpeed;
文本视图百分比;
int downloadedSize=0;
int totalSize=0;
专用长网络速度;
私人长时间;
私人长时间;
//从URL公开下载文件(ProgressBar pb)
//  {
//ProgBar=pb;
//      
//  }
从URL公开下载文件(进度条pb、文本查看速度、文本查看速度)
{
ProgBar=pb;
tvSpeed=速度;
tv百分比=每;
}
@凌驾
受保护的void onPreExecute()
{
super.onPreExecute();
ProgBar.setProgress(0);
//程序设置最大值(100);
previousTime=System.currentTimeMillis();
}
@凌驾
受保护的字符串doInBackground(字符串…视频URL)
{
尝试
{
URL=新URL(videoURL[0]);
HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod(“GET”);
urlConnection.setDoOutput(true);
//连接
urlConnection.connect();
File File=getOutputMediaFile(videoURL[0]);
FileOutputStream fileOutput=新的FileOutputStream(文件);
//用于从internet读取数据的流
InputStream InputStream=urlConnection.getInputStream();
//这是我们正在下载的文件的总大小
totalSize=urlConnection.getContentLength();
Log.e(“下载”和“+totalSize”);
ProgBar.setMax(总尺寸);
//创建一个缓冲区。。。
字节[]缓冲区=新字节[1024];
int bufferLength=0;
而((bufferLength=inputStream.read(buffer))>0)
{
fileOutput.write(buffer,0,bufferLength);
downloadedSize+=缓冲区长度;
//更新进度条//
ProgBar.setProgress(下载大小);
每个浮动=((浮动)下载大小/总大小)*100;
//按百分比更新进度//
tvPercent.setText((int)per+“%”);
totalTime=System.currentTimeMillis()-上一个时间;
网络速度=下载大小/总时间;
//更新网络速度//
tvSpeed.setText(网络速度+“kbps”);
}
//完成后关闭输出流//
fileOutput.close();
下载大小=0;
totalSize=0;
} 
捕获(最终格式错误)
{       
e、 printStackTrace();
} 
捕获(最终IOE例外)
{         
e、 printStackTrace();
}
捕获(最终异常e)
{
e、 printStackTrace();
} 
返回null;
}
受保护的void onProgressUpdate(字符串…进度)
{
//设置进度百分比
//ProgBar.setProgress(Integer.parseInt(progress[0]));
}
@凌驾
受保护的void onPostExecute(字符串文件\u url)
{
}
}

您只能从主线程更新UI。移动
tvPercent.setText((int)per+“%”)
onProgressUpdate
并在
doInBackground
中调用
publishProgress(.)
,无论何时您想要更新文本。

我多次遇到相同的问题,最后我得到了这个问题的最终解决方案。
从后台方法中删除所有更改xml或更新布局xml文件的代码,在后期执行方法中执行。

AsyncTask在单独的线程上执行其主要工作(在doInBackground方法中),但只有主线程可以访问用户界面。doInBackground中的代码无法访问用户界面

在主线程上调用onPreExecute、onProgressUpdate和onPostExecute方法。使用这些方法访问用户界面

在doInBackground中调用publishProgress以在主线程上调用onProgressUpdate


您应该
setText
TextView
onProgressUpdate
onPostExecute
中,我将TextView放在onProgressUpdate()中,但TextView不在方法中更新。从doInBackground()中删除TextView时,请阅读asynctask的文档并相应更改方法,然后在doInBackground()方法内部很好地更新progressBar。ProgBar.setProgress(下载大小);