Android的主线程与子线程

在上一篇文章Android的进程、线程与优先级中我们提到:

  • 线程(thread):是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程至少对应一个线程。

  • CPU轮流为每个任务分配其占用时间。每个任务都觉得自己在一直占用CPU,但事实上CPU时间是划分成片段分配给了所有任务。

因而使用线程的行为应当受到限制:

  • 进程资源有限,不能无限制地创建线程(创建和销毁线程都会有相应的开销)。

  • CPU的数量和轮转能力有限,过多的线程将导致CPU轮转周期变长,系统处理速度变慢。

在Android中,线程有更多一些的细分名目:主线程、子线程、HandlerThread、IntentService、AsyncTask。

  • 主线程:进程拥有的默认线程。Androidd的UI访问是没有加锁的,这样在多个线程访问UI是不安全的。所以Android中规定只能在UI线程中访问UI,故而主线程的响应速度不应该受到影响,所以所有耗时操作都应该放置到子线程中进行。

  • 子线程:进程中手动创建的线程,用于执行耗时任务。

  • HandlerThread:内部封装了Handler机制的子线程。运行时自动启动与子线程绑定的Looper。

  • IntentService:内部封装了HandlerThread的特殊Service。由于Service的优先级更高,所以适合执行一些高优先级的后台任务。

  • AsyncTask:一种内部封装了子线程和Handler机制的轻量级异步任务。


主线程(UI线程)

创建主线程:Android应用程序的入口

我们说“线程是程序执行的最小单元,主线程是进程拥有的默认线程”,那么创建进程的工作就必然包含了创建主线程的部分。同时,我们知道主线程的ID值与进程的进程号相同,因此可以推断:主线程就是进程默认的可执行部分,或者说:如果进程中总是只有一个线程,那么主线程就是进程本身。

既然我们希望了解主线程的创建过程的原因更多的是想知道应用程序从哪里开始运行。因此相比于了解创建主线程的过程,我们更应该关心的问题是:Android的应用程序入口在哪里?

我们知道Java中main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法。而Android应用程序的main()方法则在ActivityThread类中

但并不是说,直到ActivityThread.main()方法得到执行,新起的应用程序才开始运行。上面我们提到线程是进程的一个实体,在执行main()方法前,系统已经将应用的进程率先孵化出来,并在内部初始化了运行时库,并启动了Binder线程池。

事实上,直到一个新的应用程序进程创建完毕之后,才调用RuntimeInit类的静态成员函数invokeStaticMain将ActivityThread类的静态成员函数main设置为新创建的应用程序的入口函数。

ActivityThrad管理主线程的执行,并根据AMS的要求(使用Binder机制通信,AMS为客户端,ActivityThread.ApplicationThread为服务端)通过Handler消息机制调度并执行Activity、BroadCast等组件以及其它操作(在我们关心的范围内,可以认为ActivityThread等同于主线程)。

            \android\app\ActivityThread.main()

            public static void main(String[] args) {
            SamplingProfilerIntegration.start();
            … …
            // 创建/绑定主线程的Looper
            // Looper、Handler是构成Android应用消息循环机制的主要部分
            Looper.prepareMainLooper();

            // 创建ActivityThread的实例
            ActivityThread thread = new ActivityThread();

            //建立Binder通道 (创建新线程)
            thread.attach(false);

            // 创建一个Handler
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }

            // 开启Looper循环,这是一个死循环
            Looper.loop();

            // 除非Looper出现异常,否则该语句永远得不到执行
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }

主线程如何在死循环中处理任务

新建一个应用,主Activity的代码如下:

        public class MainActivity extends Activity {
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                // 发送一个Message,what=1
                handler.sendEmptyMessage(1);
                Log.d("GooDong","Exit onCreat------");
            }
            @Override
            protected void onResume() {
                super.onResume();
                // 发送一个Message,what=2
                handler.sendEmptyMessage(2);
                Log.d("GooDong&
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值