Android面试题:Handler

目录

相关视频:

相关文章:

Q1:用一句话概括Handler,并简述其原理。

Q2:为什么系统不建议在子线程访问UI?(为什么不能在子线程更新UI?)

Q3:一个Thread可以有几个Looper?几个Handler?

Q4:可以在子线程直接new一个Handler吗?那该怎么做?

Q5:Message可以如何创建?哪种效果更好,为什么?

Q6:主线程中Looper的轮询死循环为何没有阻塞主线程?

Q7:使用Hanlder的postDealy()后消息队列会发生什么变化?

Q8:点击页面上的按钮后更新TextView的内容,谈谈你的理解?(阿里面试题)

Q9:生产者-消费者设计模式懂不?

Q10:Handler是如何完成子线程和主线程通信的?

Q11:关于ThreadLocal,谈谈你的理解?

Q12:享元设计模式有用到吗?


相关视频:

Android面试常客Handler详解

相关文章:

要点提炼|开发艺术之消息机制

Handler都没搞懂,拿什么去跳槽啊?!

 

Q1:用一句话概括Handler,并简述其原理。

 用一句话概括Handler,并简述其原理 

Q2:为什么系统不建议在子线程访问UI?(为什么不能在子线程更新UI?)

答:Android的UI访问是没有加锁的,多个线程可以同时访问更新操作同一个UI控件。也就是说访问UI的时候,android系统当中的控件都不是线程安全的,这将导致在多线程模式下,当多个线程共同访问更新操作同一个UI控件时容易发生不可控的错误,而这是致命的。所以Android中规定只能在UI线程中访问UI,这相当于从另一个角度给Android的UI访问加上锁,一个伪锁。

Android中子线程真的不能更新UI吗?(1.3w阅读量  30赞 阅读更舒服)

为什么不能在子线程中更新UI(3000阅读量  12赞)

为什么不能在子线程中更新UI(补充)(自己的)

看过以上文章,我们发现在子线程中其实是可以更新UI的,但是这是一种极端情况:

即在onCreate()中新建子线程并更新UI,例如:

public class MainActivity extends AppCompatActivity {
    private TextView main_tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        main_tv = (TextView) findViewById(R.id.main_tv);
        new Thread(new Runnable() {
            @Override
            public void run() {
                main_tv.setText("子线程中访问");
            }
        }).start();
    }

}

但是如果这段代码放在onResume()方法中,或者在setText()方法之前加入Thread.sleep(100);就会报异常。

ViewRootImpl的创建在onResume方法回调之后,而我们一开篇是在onCreate方法中创建了子线程并访问UI,在那个时刻,ViewRootImpl是没有创建的,无法检测当前线程是否是UI线程,所以程序没有崩溃一样能跑起来,而之后修改了程序,让线程休眠了200毫秒后,程序就崩了。很明显200毫秒后ViewRootImpl已经创建了,可以执行checkThread方法检查当前线程。

这篇博客的分析如题目一样,Android中子线程真的不能更新UI吗?在onCreate方法中创建的子线程访问UI是一种极端的情况,这个不仔细分析源码是不知道的。

Q3:一个Thread可以有几个Looper?几个Handler?

答:只能有一个Looper,不然调用Looper.prepare()会抛出运行时异常,提示“Only one Looper may be created per thread”

可以创建无数个Handler,但是他们使用的消息队列都是同一个,也就是同一个Looper

一个线程可以有几个Looper?几个Handler?


Q4:可以在子线程直接new一个Handler吗?那该怎么做?

要想在子线程中创建Handler对象就必须在创建之前手动调用Looper.prepare()方法,否则就会报错。

Handler面试题一:可以在子线程直接new一个Handler吗?那该怎么做?(自己的)

如何在子线程中直接new Handler

在子线程中new一个Handler

Q5:Message可以如何创建?哪种效果更好,为什么?

Message可以如何创建?哪种效果更好,为什么?


Q6:主线程中Looper的轮询死循环为何没有阻塞主线程?

主线程中Looper的轮询死循环为何没有阻塞主线程?


Q7:使用Hanlder的postDealy()后消息队列会发生什么变化?

Handler面试题二:使用Hanlder的postDealy()后消息队列会发生什么变化?

Q8:点击页面上的按钮后更新TextView的内容,谈谈你的理解?(阿里面试题)

点击页面上的按钮后更新TextView的内容,谈谈你的理解?

Q9:生产者-消费者设计模式懂不?

什么是生产者/消费者模式?

某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。结构图如下:

java设计模式之生产者/消费者模式

Q10:Handler是如何完成子线程和主线程通信的?

源码分析Android Handler是如何实现线程间通信的

Q11:关于ThreadLocal,谈谈你的理解?

跟HashMap类似,为什么不直接用HashMap呢?
原因:
1、HashMap太大了,太臃肿了。ThreadLocal的key值只有Thread,而HashMap的key值则可以
是string、int等数据类型,我们可以不用考虑这些数据类型;
2、线程隔离:我们的线程是系统中唯一的,用ThreadLocal来管理这些唯一的线程和其
对应的value值会非常方便,
3、ThreadLocal参照了HashMap,简化了HashMap,便于我们使用。

Q12:享元设计模式有用到吗?

在new Message的时候我们不直接new,而是调用obtain()方法,就是使用到了享元设计模式。

享元模式主要解决的就是减少相同对象的创建,以便节省内存空间,从而提高系统的性能。

设计模式——享元模式

你可能感兴趣的:(Andorid:面试,Android:Handler)