我有一个带操作栏的主菜单。在创建时,我运行一个线程,命中我的服务器以获取当前状态。当完成时,线程调用一个处理程序,该处理程序启动一个循环遍历项目的持续运行的线程,并使用另一个处理程序调用来更改操作栏中的测试。问题是,当我更改视图时,我会得到android.view.WindowLeaked
或View not attached to window manager
以下是一些示例代码
public class MainMenuActivity extends ProtectedWithActionBarActivity{
private int STATUS_COUNTER;
private final int RESULT_STATUS_LOADED = 2000;
private final int RESULT_SHOW_STATUS = 2001;
private CurrentStatusModel currentStatus;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainmenu);
ActionBar footerbar = (ActionBar)findViewById(R.id.footerbar);
footerbar.setTitle("Currently connected to " + PreferencesHelper.getCurrentEnvironment().name());
STATUS_COUNTER = 0;
statusLoadThread.start();
}
Thread statusLoadThread = new Thread()
{
@Override
public void run()
{
//set currentStatus with data from server
}
};
Thread statusDisplayThread = new Thread()
{
int sleep = 5000;
boolean threadDone = false;
public void done()
{
threadDone = true;
}
@Override
public void run()
{
while(true)
{
//pick message to send to handler
//increment STATUS_COUNTER or reset to 0 when out of bounds
try
{
sleep(sleep);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what)
{
case RESULT_STATUS_LOADED:
statusDisplayThread.start();
break;
case RESULT_SHOW_STATUS:
ActionBar footerbar = (ActionBar)findViewById(R.id.footerbar);
String message = ((Object[])msg.obj)[0].toString();
OnClickListener listener = (OnClickListener)((Object[])msg.obj)[1];
footerbar.setTitle(message);
footerbar.setOnTitleClickListener(listener);
break;
case ActivityBase.RESULT_ERROR:
break;
}
}
};
}
我不确定我所做的事情是不是错了,或者是否有一些显而易见的事情让我失踪了。需要发生的是线程需要在我改变屏幕时停止。我应该在开始下一个活动之前使用Thread.interrupt();
吗?
答案 0 :(得分:1)
AsyncTasc允许您实现doInBackground()
,您的线程可以在其中执行任务。这与您从Thread
获得的功能类似。
当您覆盖onPreExecute()
和onPostExecute()
,这两者都在UI线程上执行时,会发生真正的魔力。这样可以防止您收到有关未附加活动的消息。
修改 - 此answer包含AsyncTask
的一个小代码示例,可以帮助您入门。
答案 1 :(得分:0)
您正在尝试在拥有活动已从窗口系统分离后更新UI元素。
如果你使用AsyncTask
而不是vanilla线程(不需要处理程序)和cancel()
来自Activity.onPause()
的后台任务,那么你的生活会变得更加简单。 / p>
答案 2 :(得分:0)
你不能在onPause
中设置每个Thread
检查的标志吗?如果设置了标志,则线程退出其循环。因此,每当Activity
移至后台时,您Thread
的每个都将停止。您需要处理重新启动onResume
中的线程。您也可以使用AsyncTask
方法,但不能保证在调用cancel()
方法时实际取消,只有尝试取消任务。