Android Service中使用Toast无法正常显示问题的解决方法
作者:pku_android 发布时间:2022-01-23 08:38:12
本文实例讲述了Android Service中使用Toast无法正常显示问题的解决方法。分享给大家供大家参考,具体如下:
在做Service简单练习时,在Service中的OnCreate、OnStart、OnDestroy三个方法中都像在Activity中同样的方法调用了Toast.makeText,并在Acitivy中通过两个按钮来调用该服务的onStart和onDestroy方法:
DemoService代码如下:
@Override
public void onCreate()
{
super.onCreate();
Toast.makeText(getApplicationContext(), "Service is created!", Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent,int startId)
{
super.onStart(intent, startId);
Toast.makeText(getApplicationContext(), "Service is on!", Toast.LENGTH_LONG).show();
}
@Override
public void onDestroy(){
super.onDestroy();
Toast.makeText(getApplicationContext(), "Service is off!", Toast.LENGTH_LONG).show();
}
运行之后,DemoService中的信息都没有显示出来。
刚开始以为所得到的Context不正确,在Service直接调用getApplicationContext()得到的是Service的Context,但是细究来看,Toast应该得到主UI的Context才能显示,所以找了一下,Google对Toast的说明中,有一句:
“A toast can be created and displayed from an Activity or Service. If you create a toast notification from a Service,it appears in front of the Activity currently in focus.”
(http://developer.Android.com/guide/topics/ui/notifiers/toasts.html)
那么按照这句来看,service中创建的toast会在Acivity的UI前面聚焦显示。但为什么运行没有效果呢?再来查看一下makeText方法。
果然还是Context的问题,所以想要toast能够正常工作,需要在Activity的主线程上运行才行,那么如何得到主线程UI的Context呢?可以通过Handler将一个自定义的线程运行于主线程之上。
再来看一下Toast.show方法的src:
public void show() {
...
service.enqueueToast(pkg, tn, mDuration); //将该toast插入到一个消息队列中
...
}
原理上看,Android中大致上是消息队列和消息循环,主线程从消息队列中取得消息并处理。而Handler看作是一个工具类,用来向消息队列中插入消息。所以我们重构原来的代码:
@Override
public void onCreate()
{
super.onCreate();
handler=new Handler(Looper.getMainLooper());
handler.post(new Runnable(){
public void run(){
Toast.makeText(getApplicationContext(), "Service is created!", Toast.LENGTH_LONG).show();
}
});
}
@Override
public void onStart(Intent intent,int startId)
{
super.onStart(intent, startId);
handler=new Handler(Looper.getMainLooper());
handler.post(new Runnable(){
public void run(){
Toast.makeText(getApplicationContext(), "Service is on!", Toast.LENGTH_LONG).show();
}
});
}
@Override
public void onDestroy(){
super.onDestroy();
handler=new Handler(Looper.getMainLooper());
handler.post(new Runnable(){
public void run(){
Toast.makeText(getApplicationContext(), "Service is off!", Toast.LENGTH_LONG).show();
}
});
}
运行之后的效果如下:
总结:在Android的Framework中使用Toast,要将Toast添加到主线程里才能正常工作。
希望本文所述对大家Android程序设计有所帮助。


猜你喜欢
- 本文实例讲述了Android编程实现XML解析与保存的三种方法。分享给大家供大家参考,具体如下:简介在Android开发中,关于XML解析有
- 公司的服务器需要实时监控,而且当用户空间已经满了,操作失败,或者出现程序Exception的时候就需要实时提醒,便于网管和程序员调式,这样就
- private void btnSetOk_Click(object sender, EventArgs e) &nb
- Android 通过Base64上传图片到服务器之前做上传图片是采用HttpServlet上传,不过用了一下Base64上传图片后,感觉比H
- Android 3.0引入了CursorLoader实现异步加载数据,为了避免同步查询数据库时阻塞UI线程的问题。在API 11之前可以通过
- 前言我们在很多博客中都有发现,Seata AT模式里面的全局锁其实是行锁,这也是Seata AT模式和XA模式在锁粒度上的最大区别。我们可以
- 介绍INI文件格式由节、键、值组成。节[section]参数(键=值)name=value1.创建一个ini文件在Debug目录下创建一个i
- 问题描述springcloud项目部署或调试时,占用的内存特别多。当部署到服务器上去后,有可能导致服务器内存占用过多而崩溃。解决方案&nbs
- 本文实例讲述了Android实现Service重启的方法。分享给大家供大家参考。具体如下:做APP的时候,我们可能需要一个后台服务一直在运行
- 本文主要介绍了隐式Intent匹配目标组件的规则,若有叙述不清晰或是不准确的地方希望大家指出,谢谢大家: )1. Intent简
- 一、常用操作NextDouble():返回0-1.0之间的随机数Next():返回非负随机整数(0-216)Next(i):返回一个小于i的
- Double显示转换int static void Main(string[] args) { Console.WriteLine(&quo
- 场景很多情况下,查单条记录也用通用查询接口,但是输入的条件却能确定唯一性。如果我们要确定list中只有一条记录,如下写法:// 记录不为空
- 主要有四个:public——成员可以由任何代码访问。private——成员只能由类中的代码访问(如果没有使用任何关键字,就默认使用这个关键字
- 委托(delegate)是一种可以把引用存储为函数的类型,这类似于c++中的函数指针。回调函数c++中的回调函数,就是用函数指针来实现的。类
- 一、ViewPageIndicator开源框架的基本用法 我们先得去Github上面下载这个库,下载地址:https://github.co
- 开源配置中心 - ApolloApollo(阿波罗)是携程框架部门研发的配置管理平台,能够集中化管理应用不同环境、不同集群的配置,配置修改后
- 一、国际化准备资源文件,资源文件的命名格式如下:baseName_language_country.propertiesbaseName_l
- AIDL:Android Interface Definition Language,它是一种android内部进程通信接口的描述语言,通过
- 由于工作原因,需要将工程传递给一些新人小朋友,交互过程中,发现有几个典型的问题值得记录分享一下,以资来者。Androdi Studio 导入