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(下载大小);