我有个活套的问题。我调用looper.prepare(),在做完某件事之后,一切都很正常。但是如果我旋转设备,我会在准备过程中得到一个异常。
07-12 16:40:09.760: E/activity(15809): java.lang.RuntimeException: Only one Looper may be created per thread我在试着退出环路,但它什么也做不了。
这是我的AsyncTask:
@Override
protected String doInBackground(String... args) {
try{Looper.prepare(); //here start the exception
try {
URL url = new URL(link);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
utente.measure(0, 0);
bmImg = decodeSampledBitmapFromResource(is,(int) utente.getMeasuredWidth(), utente.getMeasuredHeight(), link);
if(bmImg!=null){
try{
getCroppedBitmap();
}catch(Exception e){
System.out.println(e);
}
}
}
catch (IOException e)
{
Log.e("lele", "errore qui");
e.printStackTrace();
}
Looper.myLooper().quit(); //do nothings
}catch(Exception e){
Log.e("canta tu", " "+e);
}
Looper.myLooper().quit(); //do nothings
return null;
}
@Override
protected void onPostExecute(String args) {
//Looper.myLooper().quit(); //generathed an error, main thread can't stop looper
if(bmImg!=null){
try{
utente.setImageBitmap(bmImg);
ellisse.setVisibility(View.VISIBLE);
}catch(Exception e){
Log.e("lele",""+e);
Log.e("lele","errore probabile out of bound");
}
}
else {
Toast.makeText(getApplicationContext(), "Modifica la foto da \"profilo\"", Toast.LENGTH_LONG).show();
}想法?
发布于 2013-11-22 08:05:07
有两种情况需要考虑:
(1)循环线程您希望应用程序的整个生命周期,并且不要持有对视图的强引用(即使不是隐式的)
Quoting谷歌工程师Christopher Tate -你可以把这个漏洞留在那里,直到你的应用程序被销毁,然后它就会随之崩溃。你不需要担心它。
“一般来说,永远不要退出()你的循环线程。这种方法的存在主要是出于历史和测试的原因。在现实生活中的™中,我建议你在进程的生命周期中继续重用相同的循环线程,而不是创建/退出它们。”
我使用这样一个循环线程作为多用途的HandlerThread,当我想让一些东西在主线程(UI)之外运行时,就会向它发送Runnables。
引用视图的(2)循环线程
这不是Christopher Tate的建议,因为它会导致内存泄漏,例如,如果您旋转屏幕。
(您最好将处理程序线程设置为静态的,并使用弱引用-您将返回到选项#1)
要杀死它,你必须退出循环。为此,您需要在该线程的上下文上运行quit命令。
因此,创建一条消息,使用某个int作为您的msg.what,并在您的handleMessage中等待这个int,当它到达时-调用:
Looper myLooper = Looper.myLooper();
if (myLooper!=null) {
myLooper.quit();
}别忘了把对视图和活动的所有引用都设为空。
将此终止消息从您的activity onDestroy()发送到处理程序
发布于 2013-07-14 12:29:20
Looper.prepare()将Looper-instance与调用它的线程相关联,但Looper.quit()不会删除这种关联(它只是停止消息分派机制)。因此,当您第二次调用Looper.prepare时,会抛出一个RuntimeException。
一般建议不要将Looper-instances与AsyncTask-threads关联。Looper用于在线程之间传递消息,但这已经在AsyncTask中进行了内部处理,因此数据可以在onPreExecute (UI线程) -> doInBackground (工作线程) -> onPostExecute (UI线程)之间发送。
https://stackoverflow.com/questions/17617731
复制相似问题