在一般的软件开发中,子线程中是不能更改UI主线程中创建的UI控件的。之前的理解是Toast也不能在子线程中创建。事实上并不是这样子的。

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "test", Toast.LENGTH_LONG).show();
}}).start();
}

在Activity的onCreate中写入以上代码运行。LogCat中会抱错

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

不看这个错误信息第一反应肯定是UI控件不能在子线程调用
事实上并不是这样的

我们可以查看Toast的源码

public Toast(Context context) {
mContext = context;
mTN = new TN();
mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
} /**
* Show the view for the specified duration.
*/
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
} INotificationManager service = getService();
String pkg = mContext.getPackageName();
TN tn = mTN;
tn.mNextView = mNextView;
try {
service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// Empty
}
}

看这个mTN = new TN();构造函数

final Handler mHandler = new Handler();    

Handler的构造函数

public Handler(Callback callback, boolean async) {
...
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
...
}

而Looper.myLooper()

 /**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static Looper myLooper() {
return sThreadLocal.get();
}

android中的子线程默认ThreadLocal中未设置Looper,所有会抛出这个异常,至于Looper是啥,可以参考我另一篇文章:http://www.cnblogs.com/cqcmdwym/archive/2013/05/12/3074138.html

解决方法

new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare();
Toast.makeText(MainActivity.this, "test", Toast.LENGTH_LONG).show();
Looper.loop();
}}).start();

或者在主线程中声明一个Handler,然后在run方法中hanlder.post(new Runnable(){})一下。

同样AlertDialog也是如此,他包含一个AlertController字段,其内部也需要创建一个Handler.

参考网址:http://www.oschina.net/question/163910_31439

Toast,AlertDialog的误解的更多相关文章

  1. Android支付接入(四):联通VAC计费

    原地址:http://blog.csdn.net/simdanfeg/article/details/9012031 注意事项: 1.联通支付是不需要自己标识软硬计费点的,当平台申请计费点的时候会提交 ...

  2. Android开发2:事件处理及实现简单的对话框(Toast,AlertDialog,Snackbar,TextInputLayout的使用)

    前言 啦啦啦~又要和大家一起学习Android开发啦,博主心里好激动哒~ 在上篇博文中,我们通过线性布局和基础组件的使用,完成了一个简单的学生课外体育积分电子认证系统的界面,本篇博文,将和大家一起熟悉 ...

  3. Android checkbox和radiobutton 以及Toast和AlertDialog的使用

    package com.example.radiobutton_01; import android.app.Activity; import android.os.Bundle; import an ...

  4. android中的 Toast 和 AlertDialog

    Toast 一般用来显示一些不需要用户操作的提示信息,举个栗子: public void toast(String msg) { //---创建并设置显示的内容和显示时长 Toast toast = ...

  5. Android界面设计之对话框——定制Toast、AlertDialog

    一.概述 在界面设计中需要根据用户操作显示提示信息.出错信息等,就要用到对话框.Android实现提示信息显示常用有两种方式 1.Toast 2.AlertDialog 二.Toast Android ...

  6. 中级实训Android学习记录——Toast、AlertDialog、ProgressBar

    学习记录 2020/11/22 Toast Toast Toast是一个消息提示组件 我们可以设置其显示的位置 自定义其显示的内容 对Toast的简单封装可以达到不同的目的 Toast的默认用法 To ...

  7. Android中的AlertDialog使用示例五(自定义对话框)

    在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,AlertDialog实现方法为建造者模式. ...

  8. Android AlertDialog去除黑边白边自定义布局(转)

    LayoutInflater inflater = this.getLayoutInflater(); View view = inflater.inflate(R.layout.test_alert ...

  9. Android中的AlertDialog使用示例四(多项选择确定对话框)

    在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,AlertDialog实现方法为建造者模式. ...

随机推荐

  1. Codeforces 383C . Propagating tree【树阵,dfs】

    标题效果: 有一棵树,有两种操作模式对本树:1:表示为(1 x val),在NOx加在节点上val,然后x每个节点加上儿子- val.给每个儿子一个儿子在一起-(- val),加到没有儿子为止.2:表 ...

  2. Android 源码编译

    Google官方资料参考 http://source.android.com/source/building-running.html 1. 环境设置, 下载好源码后,进入源码目录,即之前执行 rep ...

  3. JS数据绑定模板artTemplate试用

    之前写JS绑定数据曾经用过tmpl库,虽然功能比较强大但是感觉不是很轻量,对于相对简单的数据需求显得有些臃肿.而Ajax返回数据自己拼接html的方式又显得不够高端,因此今天看了一篇介绍artTemp ...

  4. JQUERY 选择

    jQuery 选择器 jQuery 采用 CSS 一个选择选择 HTML 元素. $("p") 选取 <p> 元素. $("p.intro") 选取 ...

  5. Mybatis 构造resultMap 搜sql

    映射配置文件 <!-- type:映射数据类型的实体类 id:resultMap的唯一标识 --> <resultMap type="person" id=&qu ...

  6. unity3d NGUI入门(描述和使用插件参数)

    我用NGUI它是3.5.4,Unity3d版本号是4.3.4f需要 NGUI3.5.4 下载NGUI,这是破解版的,用于学习.假设是商用.请支持正版 插件的导入 1.NGUI的导入,双击NGUI Ne ...

  7. RPC框架实现

    转载RPC框架实现 RPC(Remote Procedure Call,远程过程调用)框架是分布式服务的基石,实现RPC框架需要考虑方方面面.其对业务隐藏了底层通信过程(TCP/UDP.打包/解包.序 ...

  8. IntelliJIDEA Getting+Started+with+Spring+MVC,+Hibernate+and+JSON

    https://confluence.jetbrains.com/display/IntelliJIDEA/Getting+Started+with+Spring+MVC,+Hibernate+and ...

  9. hdu 4915 Parenthese sequence(模拟)2014多培训学校5现场

    Parenthese sequence                                                                     Time Limit: ...

  10. Angularjs -- 核心概念

     angularjs旨在减轻使用AJAX开发应用程序的复杂度,使得程序的创建.測试.扩展和维护变得easy.以下是angularjs中的一些核心概念. 1. client模板      多页面的应用通 ...