android.widget.Toast类

本文介绍了 Android 中 Toast 类的使用方法,包括构造方法、显示、取消显示等基本操作,并详细解释了如何设置文本、持续时间、位置及自定义视图。

Toast类

java.lang.Object
 -android.widget.Toast
 
extends Object

Toast翻译过来是烤面包,跟其功能完全无一点关系。
Toast其实就是一个小提示,弹出后会自动消失,使用起来非常简洁方便。
其最简洁的使用方法也是最常用的使用方法如下:
Toast.makeText(getApplicationContext(), "默认样式的Toast", Toast.LENTH_SHOTR).show();
下面介绍一下Toast的几个主要方法:
#Toast
Toast(Context context);
构造方法,参数用getApplicationContext()。

#show
public void show();
将Toast显示出来,其实是添加到Toast队列中。

#cancel
public void chancel();
取消Toast的显示,或者将其从Toast队列中删除。实际该方法基本不需要用。

#makeText
public static Toast makeText(Context context, int resId, int duration);
public static Toast makeText(Context context, CharSequence text, int duration);
Toast.makeText(getApplicationContext(), "默认Toast样式", Toast.LENGTH_SHORT).show();
设置文本和持续时间,往往后面加一个show就直接显示出来了,一句话搞定。

#setDuration
void     setDuration(int duration);
设置持续时间,参数虽然是int型,实际上只能是Toast.LENGTH_LONG和Toast.LENGTH_SHORT两个,长的约4s,短的约2s。

#setGravity
void     setGravity(int gravity, int xOffset, int yOffset);
设置Toast显示位置,这个参数可就多了,后面的xOffset和yOffset就不用说了,就是横向和纵向的偏移,估计也不会用。
gravity参数有以下的值可用:
Gravity.CENTER 0x00000011 居中
Gravity.LEFT 0x00000003 靠左
Gravity.RIGHT 0x00000005 靠右
Gravity.TOP 0x00000030 靠上
Gravity.BOTTOM 0x00000050 靠下
Gravity.CENTER_HORIZONTAL 0x00000001 横向居中
Gravity.CENTER_VERTICAL 0x00000010 纵向居中
Gravity.FILL 0x00000077 占满
Gravity.FILL_HORIZONTAL 0x00000007 横向占满
Gravity.FILL_VERTICAL 0x00000070 纵向占满
Gravity.NO_GRAVITY 0x00000000 清除所有设置还原默认设置了,貌似就居中了
Gravity类下面还有一些参数,但貌似跟位置没关系,不知道干嘛的。

#setMargin
publi void setMargin(float horizontalMargin, float verticalMargin);
没太搞明白怎么个算法,反正两个参数都是小于零的数才有效的。

#setText
void     setText(int resId);

#setView
为Toast设置一个View,show的时候Toast将显示该View,用于完全的自定义Toast内容。
LayoutInflater inflater = getLayoutInflater();
                View layout = inflater.inflate(R.layout.custom,
                (ViewGroup) findViewById(R.id.llToast));
                ImageView image = (ImageView) layout.findViewById(R.id.tvImageToast);
                image.setImageResource(R.drawable.icon);

                Toast toast = new Toast(getApplicationContext());
                toast.setGravity(Gravity.RIGHT | Gravity.TOP, 12, 40);
                toast.setDuration(Toast.LENGTH_SHORT);
                toast.setView(layout);
                toast.show();

下面这些获得这获得那估计也是没啥用就不细说了。
#getDuration
#getGravity
#getHorizontalMargin
#getVerticalMargin
#getView
#getXOffset
#getYOffset

<think>好的,我现在需要解决用户遇到的Android应用程序崩溃问题。错误日志显示在非主线程中尝试显示Toast而没有调用Looper.prepare(),导致NullPointerException。用户可能是在后台线程中直接调用了Toast.makeText().show(),而Android的UI操作必须在主线程中进行。首先,我需要确认这个问题的根本原因。Toast的显示需要Looper,而主线程(UI线程)默认有Looper,但后台线程没有。如果用户在一个新创建的线程中直接显示Toast,就会抛出这个异常。接下来,我需要考虑几种解决方案。常见的解决方法包括使用Activity.runOnUiThread()方法、Handler.post()或者View.post()来切换到主线程执行UI操作。另外,也可以使用AsyncTask或者LiveData等架构组件来处理线程间的通信。 然后,我需要编写示例代码来展示每种解决方法,确保用户能够理解并正确实施。同时,要解释每种方法的原理,帮助用户理解为什么必须这样做。 还需要注意代码的正确性,比如在runOnUiThread中使用lambda表达式是否合适,或者Handler是否关联了主线程的Looper。此外,要提醒用户避免在后台线程中执行任何UI操作,强调Android的UI线程安全原则。最后,我需要列出相关问题,帮助用户扩展知识,比如其他常见的非UI线程操作问题、Handler的详细用法、Kotlin协程处理线程切换,以及如何全局捕获线程异常。这些问题有助于用户深入理解多线程编程在Android中的应用,避免未来出现似错误。</think>### **解决方案** #### **问题分析** 错误日志表明,你在非主线程(例如 `Thread-2`)中尝试显示 `Toast`,但未正确初始化线程的 `Looper`。Android 要求 UI 操作(如显示 Toast)必须在主线程(UI 线程)中执行,否则会抛出 `NullPointerException`。 --- ### **方法 1:切换到主线程显示 Toast** 使用 `runOnUiThread` 方法将 Toast 的显示逻辑切换到主线程。 ```java // 示例代码(在非主线程中调用) Thread thread = new Thread(() -> { // 后台任务... // 显示 Toast runOnUiThread(() -> { Toast.makeText(MainActivity.this, "操作完成", Toast.LENGTH_SHORT).show(); }); }); thread.start(); ``` #### **解释** - `runOnUiThread` 是 `Activity` 提供的方法,用于将代码块切换到主线程执行。 - 所有 UI 操作(包括 `Toast`)必须通过此方法切换到主线程。 --- ### **方法 2:使用 Handler 发送消息到主线程** 通过 `Handler` 关联主线程的 `Looper`,将显示 Toast 的逻辑发送到主线程。 ```java // 示例代码(在非主线程中调用) Handler mainHandler = new Handler(Looper.getMainLooper()); mainHandler.post(() -> { Toast.makeText(MainActivity.this, "操作完成", Toast.LENGTH_SHORT).show(); }); ``` #### **解释** - `Looper.getMainLooper()` 获取主线程的 `Looper`。 - `Handler.post()` 将代码块发送到主线程的消息队列中执行。 --- ### **方法 3:使用 AsyncTask 处理线程切换** 如果后台任务需要与 UI 交互,可以使用 `AsyncTask`(注意:已过时,但适用于简单场景)。 ```java // 示例代码 private class MyTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { // 后台任务... return null; } @Override protected void onPostExecute(Void aVoid) { // 在 UI 线程中显示 Toast Toast.makeText(MainActivity.this, "操作完成", Toast.LENGTH_SHORT).show(); } } // 启动任务 new MyTask().execute(); ``` #### **解释** - `doInBackground` 在后台线程执行耗时任务。 - `onPostExecute` 在主线程中更新 UI。 --- ### **方法 4:使用 Kotlin 协程(推荐)** 如果使用 Kotlin,协程可以简化线程切换。 ```kotlin // 示例代码(Kotlin) CoroutineScope(Dispatchers.IO).launch { // 后台任务... withContext(Dispatchers.Main) { Toast.makeText(this@MainActivity, "操作完成", Toast.LENGTH_SHORT).show() } } ``` #### **解释** - `Dispatchers.IO` 指定后台线程。 - `withContext(Dispatchers.Main)` 切换到主线程更新 UI。 --- ### **错误原因总结** - **根本问题**:在非主线程直接调用 `Toast.makeText().show()`。 - **Android 限制**:UI 操作必须在主线程执行,否则会触发 `Looper` 相关的异常。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值