Android - 更改 Activity 时的多线程问题

标签 android multithreading android-asynctask

我有一个带有操作栏的主菜单。在创建时,我运行一个线程来访问我的服务器以获取当前状态。当 Complete 时,该线程调用一个处理程序,该处理程序启动一个不断运行的线程,该线程循环遍历项目并使用另一个处理程序调用来更改操作栏中的测试。问题是,当我更改 View 时,我得到 android.view.WindowLeakedView 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;
        }
    }
    };
}

我不确定我所做的是错误的,还是我遗漏了一些显而易见的东西。需要发生的是线程需要在我更改屏幕时停止。我应该在开始下一个 Activity 之前使用 Thread.interrupt(); 吗?

最佳答案

AsyncTasc允许您实现 doInBackground(),您的线程可以在其中执行其任务。这类似于您从 Thread 获得的功能。

当您重写 onPreExecute()onPostExecute() 时,真正的魔法就会发生,它们都在 UI 线程上执行。这应该可以防止您收到有关您的 Activity 未被附加的消息。

编辑 - 这个answer包含一个可以帮助您入门的 AsyncTask 的小代码示例。

关于Android - 更改 Activity 时的多线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5196165/

相关文章:

Android 应用程序在 setText 上崩溃

multithreading - WP7 - 访问 UI 线程?

java - java中通过多线程读写文件

android - 操作栏和自定义相机 View 上的阴影

java - 如何从处理程序中删除所有回调?

android - 带有标题、图像和文本的 ListView ?

multithreading - Perl 并行 HTTP 请求 - 内存不足

android - Http 数据请求(应用程序崩溃)

android - 在 asynctask 中使用 asynctask

Android:AsyncTask 推荐:私有(private)类还是公共(public)类?