Android Can';在使用AsyncTask时,在未调用Looper.prepare()的线程内创建处理程序
我的应用程序中有以下代码,可以更新应用程序。我将apk托管在一个私有服务器上,当我发布一个新版本时,我希望此代码能够运行并更新应用程序 我知道Play Store会这样做,我们对大多数客户都使用这种机制。有一些客户由于使用数据而拒绝打开后台数据。这些客户无法使用Play Store,因此我希望从我们的私有服务器获得一个优雅的更新方法 我读过一篇关于SO的帖子,总的感觉是我在调用一些应该在UI线程上调用的东西。如果我在打网络电话,它一定在BG线程上 知道我为什么会收到这个错误消息吗 提前谢谢 马特Android Can';在使用AsyncTask时,在未调用Looper.prepare()的线程内创建处理程序,android,Android,我的应用程序中有以下代码,可以更新应用程序。我将apk托管在一个私有服务器上,当我发布一个新版本时,我希望此代码能够运行并更新应用程序 我知道Play Store会这样做,我们对大多数客户都使用这种机制。有一些客户由于使用数据而拒绝打开后台数据。这些客户无法使用Play Store,因此我希望从我们的私有服务器获得一个优雅的更新方法 我读过一篇关于SO的帖子,总的感觉是我在调用一些应该在UI线程上调用的东西。如果我在打网络电话,它一定在BG线程上 知道我为什么会收到这个错误消息吗 提前谢谢 马特
私有类AsyncUpdateApp扩展了AsyncTask{
@凌驾
受保护的字符串doInBackground(字符串…参数){
字符串结果=updateApp(参数[0]);
返回结果;
}
@凌驾
受保护的void onPostExecute(字符串结果){
super.onPostExecute(结果);
if(结果等信号情况(“正常”)){
意向意向=新意向(意向.行动\视图);
intent.setDataAndType(Uri.fromFile(新文件(Environment.getExternalStorageDirectory()+“/download/”+“app.apk”),“application/vnd.android.package archive”);
intent.setFlags(intent.FLAG\u活动\u新任务);
星触觉(意向);
}否则{
Log.e(标记“result odf updateApp=ERROR”);
}
}
}
公共字符串updateApp(字符串apkurl){
试一试{
URL=新URL(apkurl);
HttpURLConnection c=(HttpURLConnection)url.openConnection();
c、 setRequestMethod(“GET”);
c、 设置输出(真);
c、 connect();
String PATH=Environment.getExternalStorageDirectory()+“/download/”;
文件=新文件(路径);
mkdirs()文件;
File outputFile=新文件(文件“app.apk”);
FileOutputStream fos=新的FileOutputStream(outputFile);
InputStream=c.getInputStream();
字节[]缓冲区=新字节[1024];
int len1=0;
而((len1=is.read(buffer))!=-1){
fos.写入(缓冲区,0,len1);
}
fos.close();
is.close();//在这里,它工作正常-.apk在下载文件中下载到我的SD卡中
返回“OK”;
}捕获(IOE异常){
Toast.makeText(getApplicationContext(),“更新错误!”,Toast.LENGTH_LONG.show();
返回“错误”;
}
}//updateApp结束
09-1014:31:04.975:E/AndroidRuntime(606):致命异常:AsyncTask#1
09-1014:31:04.975:E/AndroidRuntime(606):进程:com.carefreegroup.rr3,PID:606
09-10 14:31:04.975:E/AndroidRuntime(606):java.lang.RuntimeException:执行doInBackground()时出错
09-10 14:31:04.975:E/AndroidRuntime(606):在android.os.AsyncTask$3.done(AsyncTask.java:300)
09-1014:31:04.975:E/AndroidRuntime(606):在java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
09-1014:31:04.975:E/AndroidRuntime(606):位于java.util.concurrent.FutureTask.setException(FutureTask.java:222)
09-1014:31:04.975:E/AndroidRuntime(606):在java.util.concurrent.FutureTask.run(FutureTask.java:242)
09-10 14:31:04.975:E/AndroidRuntime(606):位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
09-10 14:31:04.975:E/AndroidRuntime(606):在java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
09-1014:31:04.975:E/AndroidRuntime(606):在java.lang.Thread.run(Thread.java:811)
09-10 14:31:04.975:E/AndroidRuntime(606):原因:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
09-1014:31:04.975:E/AndroidRuntime(606):在android.os.Handler.(Handler.java:200)
09-1014:31:04.975:E/AndroidRuntime(606):在android.os.Handler.(Handler.java:114)
09-1014:31:04.975:E/AndroidRuntime(606):在android.widget.Toast$TN.(Toast.java:327)
09-1014:31:04.975:E/AndroidRuntime(606):在android.widget.Toast(Toast.java:92)
09-1014:31:04.975:E/AndroidRuntime(606):在android.widget.Toast.makeText(Toast.java:241)
2009-10 14:31:04.975:E/AndroidRuntime(606):在com.carefreegroup.rr3.NfcscannerActivity.updateApp(NfcscannerActivity.java:6382)
2009-10 14:31:04.975:E/AndroidRuntime(606):在com.carefreegroup.rr3.NfcscannerActivity$AsyncUpdateApp.doInBackground(NfcscannerActivity.java:6320)
09-10 14:31:04.975:E/AndroidRuntime(606):在com.carefreegroup.rr3.NfcscannerActivity$AsyncUpdateApp.doInBackground(NfcscannerActivity.java:1)
09-1014:31:04.975:E/AndroidRuntime(606):在android.os.AsyncTask$2.call(AsyncTask.java:288)
09-1014:31:04.975:E/AndroidRuntime(606):在java.util.concurrent.FutureTask.run(FutureTask.java:237)
09-1014:31:04.975:E/AndroidRuntime(606):。。。3个以上
此代码块引发IOException:
try {
URL url = new URL(apkurl);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "app.apk");
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();//till here, it works fine - .apk is download to my sdcard in download file
return "OK";
}
在catch块中,您不能在doInBackground中运行任何UI操作,您必须从catch中删除此行:
Toast.makeText(getApplicationContext(), "Update error!", Toast.LENGTH_LONG).show();
您正试图在
背景线程中显示土司。这就是问题所在。您可以将toast行替换为log
// Some code...
} catch (IOException e) {
//Toast.makeText(getApplicationContext(), "Update error!", Toast.LENGTH_LONG).show();
Log.e("Error","Exception thrown");
return "ERROR";
}
try {
URL url = new URL(apkurl);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "app.apk");
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();//till here, it works fine - .apk is download to my sdcard in download file
return "OK";
}
Toast.makeText(getApplicationContext(), "Update error!", Toast.LENGTH_LONG).show();
// Some code...
} catch (IOException e) {
//Toast.makeText(getApplicationContext(), "Update error!", Toast.LENGTH_LONG).show();
Log.e("Error","Exception thrown");
return "ERROR";
}