我正在尝试创建一个定期查看下载缓冲区的计时器线程,并查看我为下载文件而创建的线程中有多少字节。但是,我总是得到这样的消息:无法在未调用Looper.prepare()的线程内创建处理程序
我的代码:
private class DownloadPdfTask extends AsyncTask<String, Integer, String> {
private PowerManager.WakeLock mWakeLock;
@Override
protected String doInBackground(String... params) {
// ... code
try {
// Create the URL, needs java.net.URL
URL mUrl;
mUrl = new URL(params[0]);
// Variable to measure Latency (until first byte is received)
long beforeConnect = System.currentTimeMillis();
// Open connection to the URL
mConnection = (HttpURLConnection) mUrl.openConnection();
mConnection.connect();
long afterConnect = System.currentTimeMillis();
mLatency = afterConnect - beforeConnect;
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (mConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + mConnection.getResponseCode()
+ " " + mConnection.getResponseMessage();
}
fileLength = mConnection.getContentLength();
// Download the file
is = mConnection.getInputStream();
final File osFile = new File("sdcard/filename.pdf");
if (!osFile.exists())
{
try
{
osFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
return e.toString();
}
}
os = new FileOutputStream(osFile);
final byte data[] = new byte[4096];
int count;
// Create timer thread to peek buffer and see how many bytes are there
final Handler mHandler = new Handler();
Runnable mHandlerTask = new Runnable() {
@Override
public void run() {
mThroughputEverySecond += " " + total;
// Run timer task every second
mHandler.postDelayed(this, 1000);
}
};
while ((count = is.read(data)) != -1) {
// Allow canceling with back button
if (isCancelled()) {
is.close();
return null;
}
total += count;
// Publishing the progress
if (fileLength > 0) { // Only if total length is known
publishProgress((int) (total * 100 / fileLength));
}
os.write(data, 0, count);
}
// Stop timer task after download is completed
mHandler.removeCallbacks(mHandlerTask);
} catch (Exception e) {
return e.toString();
答案 0 :(得分:3)
尝试使用new Handler(Looper.getMainLooper())
来实例化您的处理程序。
答案 1 :(得分:2)
可以在任何线程上实例化handler
,但该线程必须具有looper对象。如何制作一个活套?致电looper.prepare();
然后你必须创建你的处理程序,然后调用Looper.loop();
看看这个:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
}
};
Looper.loop();
}
}
Ui线程有一个looper对象,所以你不需要在创建处理程序之前调用looper.prepar()
,但是对于其他线程,你必须按照我的编码。