在IntentService中使用Toast与在Service中使用Toast的异同

1. 表象



Service中可以正常显示Toast,IntentService中不能正常显示Toast,在2.3系统上,不显示toast,在4.3系统上,toast显示,但是不会消失。

2. 问题分析



查阅Android官方文档可以发现:

Public Constructors

public Toast (Context context)

Since: API Level 1

Construct an empty Toast object. You must call setView(View) before
you can call show().

Parameters
context The context to use. Usually your Application or Activity object.

从上面可以看出:

Toast要求运行在UI主线程中,所以要想Toast能够正常工作那个必须把它发到UI线程中。

Service运行在主线程中,因此Toast是正常的。

IntentService运行在独立的线程中,因此Toast不正常。

3. 在IntentService中显示Toast



利用Handler,将显示Toast的工作,放在主线程中来做。具体有两个实现方式。

方法一:Handler的post方式实现,这个方式比较简单。

private void showToastByRunnable(final IntentService context, final CharSequence text, final int duration) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(context, text, duration).show();
        }
    });
}

方法二:Handler的msg方式实现,这个方式比较复杂。

Handler msgHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        Toast.makeText(ToastIntentService.this,msg.getData().getString("Text"), Toast.LENGTH_SHORT).show();
        super.handleMessage(msg);
    }
};
private void showToastByMsg(final IntentService context, final CharSequence text, final int duration) {
    Bundle data = new Bundle();
    data.putString("Text", text.toString());
    Message msg = new Message();
    msg.setData(data);
    msgHandler.sendMessage(msg);
}

4. 关于耗时操作



Service中如果有耗时的操作,要开启一个Thread来做。

IntentService是在独立的线程中,所以可以进行一些耗时操作。

5. 考虑AsyncTask与Service的使用区别



如果是全后台的工作,使用Service,结果的提示可以使用Notification。

如果是异步工作,工作结束后需要更新UI,那么最好使用Thread或者AsyncTask。

6. 应用实例



@Override
protected void onHandleIntent(Intent intent) {
         // TODO Auto-generated method stub
         sendList=intent.getStringArrayListExtra("sendList");
         String content=intent.getStringExtra("content");
         for (String number : sendList)
         {
                   // 创建一个PendingIntent对象
                   PendingIntent pi = PendingIntent.getActivity(
                            SendService.this, 0, new Intent(), 0);
                   SmsManager sManager=SmsManager.getDefault();
                   // 发送短信
                   sManager.sendTextMessage(number, null,content, pi, null);
                   count++;
                   showMsg("发送给:"+number+"的短信已完成");
         }
         // 提示短信群发完成
         showMsg("短信群发完成");
}
//利用Handler,将显示Toast的工作,放在主(UI)线程中来做
public void showMsg(final String msg) {
         // TODO Auto-generated method stub
          Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(SendService.this,msg,Toast.LENGTH_SHORT).show();
            }
        });
}
时间: 2024-10-13 16:27:24

在IntentService中使用Toast与在Service中使用Toast的异同的相关文章

(原创)在service中定时执行网络操作的几点说明

执行网络操作是耗时操作,即便是在service中也要放到子线程中执行 这里我用到了async-http-client框架来执行异步请求操作 计时用的java原生Timer和TimerTask类 本来这两者分开操作各没有问题 但是如果把异步操作写到TimerTask的run方法里就会出错 E/AndroidRuntime(5799): java.lang.IllegalArgumentException: Synchronous ResponseHandler used in AsyncHttpC

Service中事务不能回滚的解决方式(转)

1.在service方法里面如果对异常进行了捕获的话,该事务是不会进行回滚的        默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚.          spring aop  异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过配置来捕获特定的异常并回滚,换句话说在service的方法中不使用try catch 或者在catc

如何从python代码中直接访问Android的Service

在Kivy中,通过pyjnius扩展可以间接调用Java代码,而pyjnius利用的是Java的反射机制.但是在Python对象和Java对象中转来转去总让人感觉到十分别扭.好在android提供了binder这个进程间通信的功能,Java中的Service也是基于Binder的C++代码封装来实现进程间通信的,这也为从Python代码中绕开pyjnius直接访问Java代码提供了可能,既然Java的Service是基于C++的封装来实现的,也同样可以在Python中封装同样的C++代码,这篇文

我的Android进阶之旅------>如何解决Android 5.0中出现的警告: Service Intent must be explicit:

1.错误描述 今天在Android4.4 的小米4手机上运行我的程序的时候没有报错,而在Android 5.1的华为P7上运行我的程序的时候报了以下的错误,错误提示如下: E/AndroidRuntime(12500): FATAL EXCEPTION: main E/AndroidRuntime(12500): Process: com.xtc.watch, PID: 12500 E/AndroidRuntime(12500): java.lang.IllegalArgumentExcepti

关于Service中bindService注意的几个问题

最近有用到Activity需要不断的从Service中获取数据,第一个想法肯定就是通过bind回调机制了,有几点概念模糊特此记录下: 单独使用bindService(),unbindService()会经历:->onCreate()->onBind()->Service running->onUnbind() -> onDestroy() . 单独使用startService(),stopService()会经历:->onCreate()->onStartComm

如何在Service中更新Activity的UI?

============问题描述============ 如何在Service中更新Activity的UI? 不想用广播.  有人说用接口,具体如何实现我一直不懂? 请赐教. ============解决方案1============ 将activity 实例传过来不就OK 了?然后调用其方法更新UI ============解决方案2============ 一般都用广播,否则在Activity也创建一个Messenger,也就是AIDL方式通信. ============解决方案3=====

MySQL5.7 安装过程中出现 attempting to start service 过不去

MySQL5.7 安装过程中出现 attempting to start service 过不去. 1,机制打开服务,把MySql服务名启动(我的是MySqlAliyun) 启动失败:提示1067错误. 2,在mysql安装目录(C:\Program Files\MySQL\MySQL Server 5.7)下把my-default.ini复制为my.ini 在my.ini取消basedir和datadir的注释: #设置basedir指向mysql的安装路径 basedir= C:\Progr

ionic中将service中异步返回的数据赋值给controller的$scope

1.service中异步获取数据实例 angular.module('starter.services', []) .factory('Chats', function($http,$q) {//定义Chats的service return { all: function() {//all方法异步获取数据 var deferred=$q.defer(); //定义deferred var promise=deferred.promise;//定义promise $http.get('http:/

在Oracle/SQL Service中通过Function返回Table

本函数用途:返回一个Table 在Oracle中实现,范例: 1 --在Types中: 2 create or replace type objTable as object 3 ( 4 s_usercode varchar2(32767), 5 s_username varchar2(32767) 6 ); 7 8 CREATE OR REPLACE TYPE tabTemp AS TABLE OF objtable; 9 10 11 --在Function中: 12 --使用Pipeline