Android中,Handler是在主线程还是其他线程中运行?

7
我有以下代码。
public class SplashScreen extends Activity {
    private int _splashTime = 5000;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                 WindowManager.LayoutParams.FLAG_FULLSCREEN);

        new Handler().postDelayed(new Thread(){
           @Override
           public void run(){
             Intent mainMenu = new Intent(SplashScreen.this, MainMenu.class);
             SplashScreen.this.startActivity(mainMenu);
             SplashScreen.this.finish();
             overridePendingTransition(R.drawable.fadein, R.drawable.fadeout);
           }
        }, _splashTime);
    }
}

我在分析这段代码时遇到了问题。据我所知,handler是在主线程中运行的。但它有一个在其他线程中运行的线程。

MainMenu.class会在主线程或第二个线程中运行吗? 如果主线程停止5秒钟,就会引发ANR。为什么当我用延迟(_splashTime)停止它时,即使我将其增加到5秒以上,ANR也不会显示?

1个回答

13
据我所知,处理程序在主线程中运行。 对象不运行于线程中,因为对象本身并不运行。方法才是运行的。 但它有一个在线程中运行的线程。 您未发布涉及任何“其他线程”的代码。上面的代码清单中的所有内容都与您进程的主要应用程序线程相关联。 MainMenu.class将在主线程或第二个线程中运行吗? 对象不运行于线程中,因为对象本身并不运行。 方法才是运行的。 MainMenu似乎是一个Activity 。活动生命周期方法(例如onCreate())在主应用程序线程上调用。 为什么当我延迟(_splashTime)停止它时,ANR不显示(即使我将其增加到5秒以上)? 您没有“延迟”主应用程序线程。您已计划一个Runnable以在延迟_splashTime毫秒后在主应用程序线程上运行。但是,postDelayed()不是阻塞调用。它只是将一个事件放在事件队列中,该事件将在_splashTime毫秒后执行。 此外,请将Thread替换为Runnable,因为postDelayed()不使用Thread。您的代码可以编译和运行,因为Thread实现了Runnable,但是如果您认为使用Thread而不是Runnable意味着您的代码将在后台线程上运行,那么您会感到困惑,并且它将不会。

谢谢Murphy先生。这表明我对Java和Android的概念理解得有多少程度 :) 我曾认为当我们在new Handler().postDelayed中使用"new Thread()"时,会创建一个新线程。 - Hesam
2
@Hesam:好的,你正在创建一个Thread对象的实例。但是,除非有人在你的Thread对象上调用了start(),否则不会创建实际的操作系统 线程 。由于postDelayed()只将该对象视为Runnable,因此postDelayed()不会调用start(),而只会调用run()。因此,你的run()代码将在主应用程序线程上执行,而不是在后台线程上执行。 - CommonsWare
一个答案中包含了如此多有用的信息。 - Fredrick Gauss
方法run()在被调用时是在不同的线程上运行还是在主应用程序线程上运行,这取决于是否使用new Thread() { }创建了一个新的线程。 - Malwinder Singh
@M.S.:如果您指的是传递给postDelayed()Runnable上的run(),它将在主应用程序线程上运行。 - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接