Android 中即时聊天或者后台任务需要发送消息的一种解决方案.

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。          在即时聊天中可能会存在一个隐藏的Bug,这个Bug根据手机的网速和性能有关系,比如你即时聊天中,你发送一消息,你的网络情况不是很好,这个时候你发送的消息一直处于发送状态,然后你不想看了,就按退出,这个时候Activity或者Fragment被销毁的时候就导致了这个消息被强行GC了,所以为了解决这个方

    

    在即时聊天中可能会存在一个隐藏的Bug,这个Bug根据手机的网速和性能有关系,比如你即时聊天中,你发送一消息,你的网络情况不是很好,这个时候你发送的消息一直处于发送状态,然后你不想看了,就按退出,这个时候Activity或者Fragment被销毁的时候就导致了这个消息被强行GC了,所以为了解决这个方案,我们可以使用IntentService,什么是IntentService?

[java]  view plain copy
  1. /*IntentService is a base class for {@link Service}s that handle asynchronous  
  2. requests (expressed as {@link Intent}s) on demand. Clients send requests  
  3. through {@link android.content.Context#startService(Intent)} calls; the  
  4. service is started as needed, handles each Intent in turn using a worker  
  5. thread, and stops itself when it runs out of work.*/  


    从这个解释中可以看出来是一个异步服务,而且不用担心他自己的生命周期.所以我们就可以使用它去发送消息,当然消息发送完毕后,我们肯定要通知界面更新UI,这个时候我们就需要使用广播比较方便些.我们可以这样写一个IntentService:

[java]  view plain copy
  1. package com.softtanck.intentservicedemo.service;  
  2.   
  3. import android.app.IntentService;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6.   
  7. import com.softtanck.intentservicedemo.MainActivity;  
  8.   
  9. /** 
  10.  * Created by winterfell on 11/17/2015. 
  11.  */  
  12. public class UpLoadImgService extends IntentService {  
  13.   
  14.   
  15.     public UpLoadImgService() {  
  16.         super("ceshi");  
  17.     }  
  18.   
  19.     /** 
  20.      * Creates an IntentService.  Invoked by your subclass's constructor. 
  21.      * 
  22.      * @param name Used to name the worker thread, important only for debugging. 
  23.      */  
  24.     public UpLoadImgService(String name) {  
  25.         super(name);  
  26.     }  
  27.   
  28.   
  29.     public static void startUploadImg(Context context, String path) {  
  30.         Intent intent = new Intent(context, UpLoadImgService.class);  
  31.         intent.setAction(MainActivity.UPLOAD_IMG);  
  32.         intent.putExtra(MainActivity.EXTRA_IMG_PATH, path);  
  33.         context.startService(intent);  
  34.     }  
  35.   
  36.   
  37.     @Override  
  38.     protected void onHandleIntent(Intent intent) {  
  39.   
  40.         if (null != intent) {  
  41.             String action = intent.getAction();  
  42.   
  43.             if (action.equals(MainActivity.UPLOAD_IMG)) {  
  44.                 //UpLoad file  
  45.                 uploadImg(intent.getStringExtra(MainActivity.EXTRA_IMG_PATH));  
  46.             }  
  47.         }  
  48.   
  49.     }  
  50.   
  51.     private void uploadImg(String path) {  
  52.         try {  
  53.             Thread.sleep(2000);  
  54.             Intent intent = new Intent(MainActivity.UPLOAD_IMG);  
  55.             intent.putExtra(MainActivity.EXTRA_IMG_PATH, path);  
  56.             sendBroadcast(intent);  
  57.         } catch (InterruptedException e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.     }  
  61. }  


    然后在需要的地方去调用:

[java]  view plain copy
  1. UpLoadImgService.startUploadImg(MainActivity.this"/sdcard/cache/com.softtanck.intentservice/1.png");  



    还有就是IntentService是继承的Service,那么它是怎么实现异步线程的.?我们先粗略看一下它的源码:

[java]  view plain copy
  1. /* 
  2.  * Copyright (C) 2008 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package android.app;  
  18.   
  19. import android.annotation.WorkerThread;  
  20. import android.content.Intent;  
  21. import android.os.Handler;  
  22. import android.os.HandlerThread;  
  23. import android.os.IBinder;  
  24. import android.os.Looper;  
  25. import android.os.Message;  
  26.   
  27. /** 
  28.  * IntentService is a base class for {@link Service}s that handle asynchronous 
  29.  * requests (expressed as {@link Intent}s) on demand.  Clients send requests 
  30.  * through {@link android.content.Context#startService(Intent)} calls; the 
  31.  * service is started as needed, handles each Intent in turn using a worker 
  32.  * thread, and stops itself when it runs out of work. 
  33.  * 
  34.  * <p>This "work queue processor" pattern is commonly used to offload tasks 
  35.  * from an application's main thread.  The IntentService class exists to 
  36.  * simplify this pattern and take care of the mechanics.  To use it, extend 
  37.  * IntentService and implement {@link #onHandleIntent(Intent)}.  IntentService 
  38.  * will receive the Intents, launch a worker thread, and stop the service as 
  39.  * appropriate. 
  40.  * 
  41.  * <p>All requests are handled on a single worker thread -- they may take as 
  42.  * long as necessary (and will not block the application's main loop), but 
  43.  * only one request will be processed at a time. 
  44.  * 
  45.  * <div class="special reference"> 
  46.  * <h3>Developer Guides</h3> 
  47.  * <p>For a detailed discussion about how to create services, read the 
  48.  * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a> developer guide.</p> 
  49.  * </div> 
  50.  * 
  51.  * @see android.os.AsyncTask 
  52.  */  
  53. public abstract class IntentService extends Service {  
  54.     private volatile Looper mServiceLooper;  
  55.     private volatile ServiceHandler mServiceHandler;  
  56.     private String mName;  
  57.     private boolean mRedelivery;  
  58.   
  59.     private final class ServiceHandler extends Handler {  
  60.         public ServiceHandler(Looper looper) {  
  61.             super(looper);  
  62.         }  
  63.   
  64.         @Override  
  65.         public void handleMessage(Message msg) {  
  66.             onHandleIntent((Intent)msg.obj);  
  67.             stopSelf(msg.arg1);  
  68.         }  
  69.     }  
  70.   
  71.     /** 
  72.      * Creates an IntentService.  Invoked by your subclass's constructor. 
  73.      * 
  74.      * @param name Used to name the worker thread, important only for debugging. 
  75.      */  
  76.     public IntentService(String name) {  
  77.         super();  
  78.         mName = name;  
  79.     }  
  80.   
  81.     /** 
  82.      * Sets intent redelivery preferences.  Usually called from the constructor 
  83.      * with your preferred semantics. 
  84.      * 
  85.      * <p>If enabled is true, 
  86.      * {@link #onStartCommand(Intent, int, int)} will return 
  87.      * {@link Service#START_REDELIVER_INTENT}, so if this process dies before 
  88.      * {@link #onHandleIntent(Intent)} returns, the process will be restarted 
  89.      * and the intent redelivered.  If multiple Intents have been sent, only 
  90.      * the most recent one is guaranteed to be redelivered. 
  91.      * 
  92.      * <p>If enabled is false (the default), 
  93.      * {@link #onStartCommand(Intent, int, int)} will return 
  94.      * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent 
  95.      * dies along with it. 
  96.      */  
  97.     public void setIntentRedelivery(boolean enabled) {  
  98.         mRedelivery = enabled;  
  99.     }  
  100.   
  101.     @Override  
  102.     public void onCreate() {  
  103.         // TODO: It would be nice to have an option to hold a partial wakelock  
  104.         // during processing, and to have a static startService(Context, Intent)  
  105.         // method that would launch the service & hand off a wakelock.  
  106.   
  107.         super.onCreate();  
  108.         HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");//创建了一个HandlerThread  
  109.         thread.start();  
  110.   
  111.         mServiceLooper = thread.getLooper();  
  112.         mServiceHandler = new ServiceHandler(mServiceLooper);  
  113.     }  
  114.   
  115.     @Override  
  116.     public void onStart(Intent intent, int startId) {  
  117.         Message msg = mServiceHandler.obtainMessage();  
  118.         msg.arg1 = startId;  
  119.         msg.obj = intent;  
  120.         mServiceHandler.sendMessage(msg);  
  121.     }  
  122.   
  123.     /** 
  124.      * You should not override this method for your IntentService. Instead, 
  125.      * override {@link #onHandleIntent}, which the system calls when the IntentService 
  126.      * receives a start request. 
  127.      * @see android.app.Service#onStartCommand 
  128.      */  
  129.     @Override  
  130.     public int onStartCommand(Intent intent, int flags, int startId) {  
  131.         onStart(intent, startId);  
  132.         return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;  
  133.     }  
  134.   
  135.     @Override  
  136.     public void onDestroy() {  
  137.         mServiceLooper.quit();  
  138.     }  
  139.   
  140.     /** 
  141.      * Unless you provide binding for your service, you don't need to implement this 
  142.      * method, because the default implementation returns null.  
  143.      * @see android.app.Service#onBind 
  144.      */  
  145.     @Override  
  146.     public IBinder onBind(Intent intent) {  
  147.         return null;  
  148.     }  
  149.   
  150.     /** 
  151.      * This method is invoked on the worker thread with a request to process. 
  152.      * Only one Intent is processed at a time, but the processing happens on a 
  153.      * worker thread that runs independently from other application logic. 
  154.      * So, if this code takes a long time, it will hold up other requests to 
  155.      * the same IntentService, but it will not hold up anything else. 
  156.      * When all requests have been handled, the IntentService stops itself, 
  157.      * so you should not call {@link #stopSelf}. 
  158.      * 
  159.      * @param intent The value passed to {@link 
  160.      *               android.content.Context#startService(Intent)}. 
  161.      */  
  162.     @WorkerThread  
  163.     protected abstract void onHandleIntent(Intent intent);  
  164. }  


    从源码中可以看出在OnCreat的时候初始化了一个HandlerThread,然后通过Looper的Loop去从消息队列里面去,建立了Handler的通信,而HandlerMessage中调用一个抽象的方法就是我们继承IntentService中的要实现的方法,该方法就是在线程中的,所以不需要再去开启线程.它的生命周期也是由Service是管理的.

目录
相关文章
|
XML Java Android开发
Android Studio开发APP启动程序时开屏简单动画效果快速有效解决方案
Android Studio开发APP启动程序时开屏简单动画效果快速有效解决方案
1329 0
Android Studio开发APP启动程序时开屏简单动画效果快速有效解决方案
|
1月前
|
JSON Android开发 数据格式
android 使用GSON 序列化对象出现字段被优化问题解决方案
android 使用GSON 序列化对象出现字段被优化问题解决方案
|
8月前
|
IDE Java 开发工具
Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8的解决方案
Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8的解决方案
|
7月前
|
Android开发
Android Studio 控制台中文乱码,解决方案都在这里了,完美解决
Android Studio 控制台中文乱码,解决方案都在这里了,完美解决
|
8月前
|
Android开发
Android 中ViewPager嵌套RecyclerView出现滑动冲突的解决方案
Android 中ViewPager嵌套RecyclerView出现滑动冲突的解决方案
703 0
|
8月前
|
Android开发
Android > Project with path ‘:audiovisualize‘ could not be found in project ‘:app‘. 异常解决方案
Android > Project with path ‘:audiovisualize‘ could not be found in project ‘:app‘. 异常解决方案
42 0
|
9月前
|
网络协议 Linux Android开发
Android部分手机4G网第一次请求很慢(wifi正常)解决方案
Android部分手机4G网第一次请求很慢(wifi正常)解决方案
255 0
|
10月前
|
Android开发 C++
Android 6.0以上手机报 so: has text relocations 问题的终极解决方案
Android 6.0以上手机报 so: has text relocations 问题的终极解决方案
|
安全 Java 定位技术
Android 校正系统时间的三种解决方案
Android 校正系统时间的三种解决方案
1536 0
|
JSON Android开发 数据格式
android studio中出现com.google.gson.JsonSyntaxException: com.google.gson.stream.类似错误的一种解决方案
android studio中出现com.google.gson.JsonSyntaxException: com.google.gson.stream.类似错误的一种解决方案
212 0
android studio中出现com.google.gson.JsonSyntaxException: com.google.gson.stream.类似错误的一种解决方案