【问题标题】:Got IllegalThreadStateException when Invoking HandlerThread.start() second time after HandlerThread.quit()在 HandlerThread.quit() 之后第二次调用 HandlerThread.start() 时出现 IllegalThreadStateException
【发布时间】:2015-08-05 13:28:52
【问题描述】:

第一次,我调用 HandlerThread.start() 来处理后台服务。在所有的东西完成后,我想通过调用 HandlerThread.quit() 来结束这个线程。

然后第二次,我启动这个Handler,检查了HandlerThread.isAlive(),isAlive()返回false,但是当我再次调用HandlerThread时,HandlerThread.start()。

但是我得到了 IllegalThreadStateException为什么

在我再次安全地调用 handlerThread.start() 之前,我如何才能真正停止 HandlerThread?

  onCreate(){
  ...............
  CurrentLocationPresenter = 
       new  CurrentLocationPresenter(getApplicationContext(),mHandler);
    }

  public void onClick(View v) {
    int id = v.getId();
    switch (id){
        case  R.id.showplacebutton:
            showPlaceInMapActivity();
            break;

        case  R.id.showgpsbutton:     

            if (mCurrentLocationPresenter.isAlive()){
                break;
            }

            mCurrentLocationPresenter.start();
            break;


    private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == CurrentLocationPresenter.WHATCODE){

            mCurrentLatlng = (LatLng) msg.obj;
            mTextView.setVisibility(View.VISIBLE);
            if (mCurrentLatlng!=null) {
                mTextView.setText(mCurrentLatlng.toString());
            }
            mCurrentLocationPresenter.getLooper().quit();
        }
    }
};

【问题讨论】:

    标签: android handler android-handlerthread


    【解决方案1】:

    如上所述,您永远不能多次调用线程对象的启动/运行/执行方法,因为您会得到IllegalThreadStateException

    但是,您可以使用诸如ExecutorService 之类的东西,这样您就可以多次使用相同的Runnable

    另外,如果你使用 ThreadPoolExecutor,它是 ExecutorService 的后代,内存和线程管理会得到照顾。

    【讨论】:

    • 谢谢,我已经通过阅读google的源代码知道了这一点,因为在这个thread.start()之后,线程已经被标记,并且无法再次启动。
    • 我也不明白你为什么要停止线程,因为 HandlerThread 的循环器将继续处理消息,直到它被告知停止。除非这是你的意图,在这种情况下,我不得不问你为什么试图停止然后重新启动 looper?
    • 如果您只想停止线程的循环器(实际处理消息的部分),那么您可以调用 mCurrentLocationPresenter.getLooper().stop();并重新启动循环器 mCurrentLocationPresenter.getLooper().loop();据我了解,你不需要重启线程,你需要重启线程中的looper。
    • 再次感谢您。这样的情况:当我单击按钮时,我启动一个 HandlerThread 向 UI 线程发送消息,但如果我想再次单击此按钮,应用程序崩溃了。那就是我的情况。现在我在第一次之后设置按钮不可点击,或者每次点击按钮然后新建这个 HandlerThread。
    【解决方案2】:

    你不能对同一个对象调用多个 asyntask.execute()。

    总是调用 MyasynTask asyntask=new MyasynTask();

     asyntask.execute();
    

    了解更多enter link description here

    【讨论】:

    • 第一次发现这个现象。但我以为每次点击这个按钮都会创建一个新对象。这会浪费太多内存吗?
    猜你喜欢
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多