Android 子线程创建消息队列更新UI
来源:互联网 发布:win10笔记本修改Mac 编辑:程序博客网 时间:2024/06/05 15:23
假设这样一种产品需求:
Android主线程崩溃后,向用户弹出一个UI提醒(一个dialog或者一个toast),告知用户APP异常崩溃。
主线程崩溃后,给用户弹出一个UI提醒
一般我们的做法是这样:
CrashHandler.java
import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.os.Looper;public class CrashHandler implements Thread.UncaughtExceptionHandler { public static final String TAG = "CrashHandler"; //--------------单例begin------------- private static CrashHandler INSTANCE = new CrashHandler(); private CrashHandler() { } public static CrashHandler getInstance() { return INSTANCE; } //-------------单例end------------- private Context mContext; public void init(Context ctx) { this.mContext = ctx; Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread thread, Throwable ex) { System.out.println("uncaughtException"); new Thread() { @Override public void run() { Looper.prepare(); // new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false) .setMessage("居然崩溃了,呜呜呜...").setNeutralButton("哈哈终于崩溃了...", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); } }).create().show(); // Looper.loop(); } }.start(); }}
MainActivity.java
import android.app.Activity;import android.os.Bundle;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //传入参数必须为Activity,否则AlertDialog将不显示。 CrashHandler crashHandler = CrashHandler.getInstance(); crashHandler.init(this); }}
这里,我们注意到,异步线程居然在操作UI,为什么异步线程可以操作UI呢?
new Thread() { @Override public void run() { Looper.prepare(); // new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false) .setMessage("居然崩溃了,呜呜呜...").setNeutralButton("哈哈终于崩溃了...", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); } }).create().show(); // Looper.loop(); }}.start();
为什么异步线程可以操作UI呢?
在android.view.ViewRootImpl中有一个checkThread方法:
了解ViewRootImpl,推荐 从ViewRootImpl类分析View绘制的流程
android.view.ViewRootImpl
void checkThread() { if (mThread != Thread.currentThread()) { throw new CalledFromWrongThreadException("Only the original thread that created a view hierarchy can touch its views."); }}
checkThread方法在requestLayout、焦点变化时,被调用;
用来检查,当前线程与View的创建线程是否在同一线程;
并未进行是否为主线程的判断。
所以其实我们在子线程中也是可以更新UI的,只要将操作UI对象的代码写在Looper.prepare()和Looper.loop()之间。
当然前提还是操作的UI对象必须得是子线程自己创建的。因此即使子线程可以操作自己的UI对象,比如弹出一个Toast(使用getApplicationContext),但是子线程仍然不能直接操作主线程的UI。同理主线程也不能操作子线程创建的UI对象,想要操作也必须引用子线程中的Handler发送消息来更新。
参考:
Android使用UncaughtExceptionHandler捕获全局异常
Android消息机制浅析
0 0
- Android 子线程创建消息队列更新UI
- Android 子线程更新UI
- Android 子线程更新 UI
- Android 子线程更新UI
- Android 子线程更新UI
- android子线程更新UI
- android子线程更新UI
- android子线程更新UI
- Android 子线程操作更新UI方法
- Android 关于子线程更新UI
- Android 子线程 更新 UI 界面 总结
- Android子线程中更新UI
- Android 让子线程更新UI
- Android子线程居然可以更新UI?
- 【Android源码学习】子线程更新UI
- Android 子线程更新UI界面
- Android在子线程更新UI界面
- Android子线程更新UI的方法
- Linux(CentOS6.7) 安装MySql5.7数据库 图文教程
- 简单的数组元素交换 调试的重要性
- 通过代码看MAVLink协议 (二)
- android studio重新share Project方法
- Android图片加载框架最全解析(一),Glide的基本用法
- Android 子线程创建消息队列更新UI
- FreeMarker基础入门知识2 -表达式
- Java学习笔记(五)
- 迅雷2016研发工程师5道笔试题
- python:对象类型
- PHP的面向对象
- 查找数据结构及Mysql数据库索引原理(B-/+Tree)
- str_to_map hive 字符串转为map格式
- 装饰器模式