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(); } }); }