目录
相关视频:
相关文章:
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都没搞懂,拿什么去跳槽啊?!
用一句话概括Handler,并简述其原理
答: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是一种极端的情况,这个不仔细分析源码是不知道的。
答:只能有一个Looper,不然调用Looper.prepare()会抛出运行时异常,提示“Only one Looper may be created per thread”
可以创建无数个Handler,但是他们使用的消息队列都是同一个,也就是同一个Looper
一个线程可以有几个Looper?几个Handler?
要想在子线程中创建Handler对象就必须在创建之前手动调用Looper.prepare()方法,否则就会报错。
Handler面试题一:可以在子线程直接new一个Handler吗?那该怎么做?(自己的)
如何在子线程中直接new Handler
在子线程中new一个Handler
Message可以如何创建?哪种效果更好,为什么?
主线程中Looper的轮询死循环为何没有阻塞主线程?
Handler面试题二:使用Hanlder的postDealy()后消息队列会发生什么变化?
点击页面上的按钮后更新TextView的内容,谈谈你的理解?
什么是生产者/消费者模式?
某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。结构图如下:
java设计模式之生产者/消费者模式
源码分析Android Handler是如何实现线程间通信的
跟HashMap类似,为什么不直接用HashMap呢?
原因:
1、HashMap太大了,太臃肿了。ThreadLocal的key值只有Thread,而HashMap的key值则可以
是string、int等数据类型,我们可以不用考虑这些数据类型;
2、线程隔离:我们的线程是系统中唯一的,用ThreadLocal来管理这些唯一的线程和其
对应的value值会非常方便,
3、ThreadLocal参照了HashMap,简化了HashMap,便于我们使用。
在new Message的时候我们不直接new,而是调用obtain()方法,就是使用到了享元设计模式。
享元模式主要解决的就是减少相同对象的创建,以便节省内存空间,从而提高系统的性能。
设计模式——享元模式