扩展HandlerThread以及何时调用getLooper()

时间:2014-12-05 23:19:13

标签: java android multithreading handler

我有一个简单的Activity,上面有一个按钮。在按钮的onClick方法中,我想在另一个线程中运行一些代码,获取一个HandlerThread的Looper对象,然后将Runnable发布到与之关联的Handler。
我的目标是使用Handler从另一个线程调用一个线程的方法(并从它自己的线程运行)(可能是一个坏主意,但我想学习这个而不是滥用静态方法)

所以我决定扩展HandlerThread。新课程并没有做太多。

public class EpicThread extends HandlerThread {
    public EpicThread(String name) {
        super(name);
    }
}

活动也没有那么多。我做了一些测试。

public class MainActivity extends Activity {
    EpicThread et;
    Looper l;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EpicThread et = new EpicThread("The epic thread");
        et.start();
    }

    public void click(View v) {
        l = et.getLooper();
        Handler h = new Handler(l);
        h.post(new Runnable() {
            @Override
            public void run() {
                System.out.println("This is running on the epic thread");
            }
        });
    }
}

所以我按下按钮来测试它,这在调用getLooper()时给了我一个InvocationTargetException:

E/AndroidRuntime(23262): FATAL EXCEPTION: main
E/AndroidRuntime(23262): java.lang.IllegalStateException: Could not execute method of the activity
E/AndroidRuntime(23262):    at android.view.View$1.onClick(View.java:3660)
E/AndroidRuntime(23262):    at android.view.View.performClick(View.java:4162)
E/AndroidRuntime(23262):    at android.view.View$PerformClick.run(View.java:17088)
E/AndroidRuntime(23262):    at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime(23262):    at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(23262):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(23262):    at android.app.ActivityThread.main(ActivityThread.java:4867)
E/AndroidRuntime(23262):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23262):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(23262):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
E/AndroidRuntime(23262):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
E/AndroidRuntime(23262):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(23262): Caused by: java.lang.reflect.InvocationTargetException
E/AndroidRuntime(23262):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23262):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(23262):    at android.view.View$1.onClick(View.java:3655)
E/AndroidRuntime(23262):    ... 11 more
E/AndroidRuntime(23262): Caused by: java.lang.NullPointerException
E/AndroidRuntime(23262):    at com.asdf.qwert.MainActivity.click(MainActivity.java:49)
E/AndroidRuntime(23262):    ... 14 more

稍微调整一下这段代码,我注意到了:

  • l = et.getLooper();之后创建线程后立即使用et.start();获取Looper。
  • 如果我直接使用HandlerThread而不是EpicThread,无论何时调用getLooper(),它都能正常工作。

所以我不知道为什么抛出这个异常,为什么仅仅通过不使用子类开始工作。

0 个答案:

没有答案