【问题标题】:Why complains my code has not called Looper.prepare()为什么抱怨我的代码没有调用 Looper.prepare()
【发布时间】:2013-10-11 15:09:09
【问题描述】:

我创建了一个Looper thread类:

public class MyLooperThread extends Thread{
    private Handler mHandler;

    public void init(){
         start(); //start the thread

         synchronized (this) {
            wait(5000); //wait for run()
         }
         Log.d("DEBUG","Init Done!");

         //EXCEPTION: Can't create handler inside thread that has not called Looper.prepare()
         MyObject obj = new MyObject(mHandler);
   }

    @Override
    public void run() {
        Looper.prepare();

        mHandler = new Handler(){
           @Override
           public void handleMessage(Message msg){
            //Check installed app package names, NOTHING RELATED WITH UI                ...
            }
        };
        synchronized (this) {
            notify(); 
        }
        Looper.loop();

     }//end of run()
}

在我的Activity中,我在onCreate() 中调用了MyLooperThreadinit() 方法。此外,我有一个ToggleButton元素,当ToggleButton ToggleButton 987654327 @'s init()方法。

public class MyActivity extends Activity implements OnCheckedChangeListener{
   …
   @Override
   protected void onCreate(Bundle savedInstanceState){
      …
      myToggleButton.setOnCheckedChangeListener(this);
      myToggleButton.setChecked(true);//checked by default

      MyLooperThread myLooper = new MyLooperThread();
      myLooper.init();

   }

   @Override
   public void onCheckedChanged(CompoundButton button, boolean isChecked) {
    if(isChecked){
          MyLooperThread myLooper = new MyLooperThread();
          myLooper.init();
      }else{
          ...
      }
    }
}

启动我的应用程序时,一切正常。我的切换按钮默认显示为选中状态。当我取消选中它并再次检查时,我得到 exception:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

指向init()方法的最后一行代码MyObject obj = new MyObject(mHandler);

为什么会出现这个异常?我不明白,我的mHandler 是在我在run() 中调用Looper.prepare() 之后创建的。

【问题讨论】:

    标签: android performance android-intent looper


    【解决方案1】:

    很确定错误是说您正在尝试做一些与 UI 相关的事情,而不是在 UI 线程上。

    【讨论】:

    • 感谢您的提示,但我无法找到此提示的错误所在
    • HandleMessage() 在做什么?你得到的错误意味着线程正在尝试做一些 UI(吐司等),但不是 UI 线程。因此错误。谷歌这个错误,侧边栏充满了类似的问题,都与在非 UI 线程上做 UI 工作有关。
    • 我的 handleMessage() 方法对 UI 没有任何作用,它只是检查已安装的应用程序包名称
    【解决方案2】:

    由于您尚未在handleMessage 中发布您正在执行的任何操作,因此我假设您正在尝试更改其中一个 UI 元素。始终使用 UI 线程来更新 UI。它应该是这样的:

    handleMessage(Message msg) {
        ...
        getActivity().runOnUiThread(new Runnable {
            ...
            // update UI here
            ...
        });
        ...
    }
    

    【讨论】:

    • 我的 handleMessage() 方法对 UI 没有任何作用,它只是检查已安装的应用程序包名称
    • 您确定在handleMessage() 中没有触及任何UI 对象吗?祝酒或修改对话,也许?另外,你能把代码贴在handleMessage()里面吗?
    【解决方案3】:

    只需使用 HandlerThread():

    ht = new HandlerThread();
    ht.start();
    h = new Handler(ht.getLooper());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      • 1970-01-01
      相关资源
      最近更新 更多