Android:如何在onPushReceive()的Context中显示自定义Toast?
问题描述
我当前的Android应用包含顶层Application类和MainActivity组件,相关代码如下:
Application.kt
class Application : android.app.Application() { // ... }
AndroidManifest.xml
<application android:name=".Application" > <activity android:name=".MainActivity" /> </application>
MainActivity.kt
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main) // ... } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
现在需要实现推送通知接收时显示自定义Toast,但在Watcher类的onPushReceive方法中遇到了问题:无法获取LayoutInflater,使用context或context.applicationContext得到的是Application对象,也无法调用findViewById()。Watcher类代码如下:
Watcher.kt
class Watcher : ParsePushBroadcastReceiver() { override fun onPushReceive(context: Context, intent: Intent) { // how to access layoutInflater here, or whatever needed to display a custom layout? } }
解决方案
1. 获取LayoutInflater
不需要依赖Activity的getLayoutInflater(),直接通过LayoutInflater.from(context)即可获取LayoutInflater实例,该方法支持传入任意Context(包括Application Context)。
2. 主线程显示Toast
注意:onPushReceive方法可能运行在后台线程,而UI操作必须在主线程执行,所以需要切换到主线程后再显示Toast。
完整代码示例
class Watcher : ParsePushBroadcastReceiver() { override fun onPushReceive(context: Context, intent: Intent) { super.onPushReceive(context, intent) // 切换到主线程执行UI操作 Handler(Looper.getMainLooper()).post { // 获取LayoutInflater实例 val inflater = LayoutInflater.from(context) // 加载自定义Toast布局 val toastView = inflater.inflate(R.layout.custom_toast, null) // 操作布局内的控件(示例:设置提示文本) val toastText = toastView.findViewById<TextView>(R.id.toast_text) toastText.text = "收到新的推送通知" // 创建并显示自定义Toast val toast = Toast(context) toast.view = toastView toast.duration = Toast.LENGTH_LONG toast.show() } } }
补充说明
- 你需要自行创建
custom_toast.xml布局文件,根据需求设计Toast的样式(比如背景、文本样式等); - inflate布局时传入
null作为父容器即可,Toast会自动处理布局适配; - 必须确保在主线程执行Toast显示操作,否则会触发UI线程异常。
内容的提问来源于stack exchange,提问作者John DoeDoe
相关产品推荐
相关产品推荐

