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

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


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



ANDroid中IntentService有何优点

IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候). 所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。

这是一个基于消息的服务,每次启动该服务并不是马上处理你的工作,而是首先会创建对应的Looper,Handler并且在MessageQueue中添加的附带客户Intent的Message对象,当Looper发现有Message的时候接着得到Intent对象通过在onHandleIntent((Intent)msg.obj)中调用你的处理程序.处理完后即会停止自己的服务.意思是Intent的生命周期跟你的处理的任务是一致的.所以这个类用下载任务中非常好,下载任务结束后服务自身就会结束退出.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好,如果您想在 IntentService 使用 MQTT 协议进行消息传输,可以使用 Eclipse Paho Android 客户端库。以下是在 IntentService 使用 Paho Android 客户端库实现 MQTT 的基本步骤: 1. 添加 Paho Android 客户端库到您的项目。 2. 在 IntentService 的 `onCreate()` 方法创建 MQTT 客户端并连接到 MQTT 代理服务器。您需要指定代理服务器的地址和端口号。可以使用 `MqttConnectOptions` 类设置连接选项,例如设置连接的用户名和密码、清除会话标志等。 3. 在 `onHandleIntent()` 方法订阅主题、发布消息和处理接收到的消息。您需要实现 `MqttCallback` 接口,并在回调方法处理接收到的消息。 以下是在 IntentService 连接到 MQTT 代理服务器的示例代码: ```java public class MyIntentService extends IntentService { private static final String TAG = MyIntentService.class.getSimpleName(); private MqttAndroidClient client; public MyIntentService() { super(TAG); } @Override public void onCreate() { super.onCreate(); String brokerUrl = "tcp://mqtt.eclipse.org:1883"; String clientId = MqttClient.generateClientId(); client = new MqttAndroidClient(this, brokerUrl, clientId); MqttConnectOptions options = new MqttConnectOptions(); options.setUserName("username"); options.setPassword("password".toCharArray()); options.setCleanSession(true); try { IMqttToken token = client.connect(options); token.waitForCompletion(); } catch (MqttException e) { Log.e(TAG, "Failed to connect to MQTT broker", e); } } @Override protected void onHandleIntent(Intent intent) { // 在这里订阅主题、发布消息和处理接收到的消息 // ... // 订阅主题 String topic = "my/topic"; int qos = 1; try { IMqttToken token = client.subscribe(topic, qos); token.waitForCompletion(); } catch (MqttException e) { Log.e(TAG, "Failed to subscribe to topic: " + topic, e); } // 发布消息 String message = "Hello, MQTT!"; try { client.publish(topic, message.getBytes(), qos, false); } catch (MqttException e) { Log.e(TAG, "Failed to publish message: " + message, e); } } @Override public void onDestroy() { super.onDestroy(); try { IMqttToken token = client.disconnect(); token.waitForCompletion(); } catch (MqttException e) { Log.e(TAG, "Failed to disconnect from MQTT broker", e); } } } ``` 您还需要实现 `MqttCallback` 接口并在回调方法处理接收到的消息。例如: ```java client.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { // 处理连接丢失事件 } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { // 处理接收到的消息 String payload = new String(message.getPayload()); Log.d(TAG, "Received message: " + payload); } @Override public void deliveryComplete(IMqttDeliveryToken token) { // 处理消息发送完成事件 } }); ``` 在 `onDestroy()` 方法断开 MQTT 客户端与代理服务器的连接。 希望这些信息能对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值