消息推送
一、主要是两种实现方式:
* pull:轮询,轮询时间短:耗电,耗流量。时间长,不能保证消息及时。
轮询:
Timer:WakeLock 让CPU 保持唤醒,耗电量很大
AlarmManager:管理独立的硬件时钟RTC,可以在CPU休眠的时候正常运行。在预设的时间到达之后,唤醒CPU。这样CPU可以正常休眠,只需要任务到达之后醒来一段很短的时间。极光推送就是基于此实现的。
* push:SMS、长连接。
二、长连接又包括三种方式:
* GCM:google的Gcm,容易被国内厂商阉割,而且NAT(Network AddressTranslation)容易超时,长连接无法保持,造成消息推送延迟。
* 第三方推送:友盟、极光,腾讯信鸽
* 自定义长连接:长连接、心跳和推送及时率。
保持长连接,是消息及时的重要保证。发送心跳包,如果前台检测发送失败,则重新初始化一个socket。
三、把socket链接和心跳功能都放在一个Service中,为什么要放在Service中?
一般我们这种socket几乎是跟app的生命周期一样长,甚至更长。不管在不在Service中去完成操作,我们都得开异步线程,虽然Service并不是异步操作,但是为了提升我们任务的优先级,我们最好是放在Service中,因为Service是由Android系统管理的,并且拥有比较高的优先级,线程是Java中的异步任务载体,可以说android系统不太认识线程。放在Service中可以很大程度上避免任务被回收或者关闭
四、下面是android代码的具体实现:
BackSevice服务:
import android.annotation.SuppressLint; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; import java.net.Socket; import java.net.UnknownHostException; import java.util.Arrays; public class BackService extends Service { private static final String TAG = "BackService"; /** 心跳检测时间 */ private static final long HEART_BEAT_RATE = 3 * 1000; /** 主机IP地址 */ private static final String HOST = "192.168.1.104"; /** 端口号 */ public static final int PORT &