Android中极光推送

一、 概念:

极光推送(JPush)是一个端到端的推送服务,使得服务器端消息能够及时地推送到终端用户手机上,让开发者积极地保持与用户的连接,从而提高用户活跃度、提高应用的留存率。极光推送客户端支持 Android, iOS 两个平台。

1.主要功能

1保持与服务器的长连接,以便消息能够即时推送到达客户端

2接收通知与自定义消息,并向开发者App 传递相关信息

2.主要特点

1客户端维持连接占用资源少、耗电低

2SDK丰富的接口,可定制通知栏提示样式

3服务器大容量、稳定

二、 极光推送技术原理:移动无线网络长连接

1.为了保证数据能及时到达客户端。常用的方法有2种。

1定时去服务器上查询数据,也叫Polling

2手机跟服务器之间维护一个 TCP 长连接,当服务器有数据时,实时推送到客户端,也就是我们说的 Push电量、流量和数据送达的及时性来说,Push 都会有明显的优势,Push 的实现和维护成本相对较高移动无线网络的特点

2. Android 平台上长连接的实现

因为 IP v4 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address TranslationNAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。

 

NAT 功能由图中的 GGSN 模块实现。大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断。Android 平台上长连接的实现为了不让 NAT 表失效,我们需要定时的发心跳,以刷新 NAT 表项,避免被淘汰。Android 上定时运行任务常用的方法有2种,一种方法用 Timer另一种是AlarmManagerAndroid Timer 可以用来计划需要循环执行的任务Timer 的问题是它需要用 WakeLock CPU 保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间。这种方式不能满足我们的需求。AlarmManager  Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。极光推送的 Android SDK 就是基于这种技术实现的。

3.服务器设计

当有大量的手机终端需要与服务器维持长连接时,对服务器的设计会是一个很大的挑战。针对这个问题,我们专门成立了一个项目,命名为C2000K,顾名思义,我们的目标是单机维持200万个长连接。最终我们采用了多消息循环、异步非阻塞的模型,在一台双核、24G内存的服务器上,实现峰值维持超过300万个长连接。只要 JPush 的网络连接是正常的,则:JPush 收到消息一定是及时的。其延迟是秒级的,一般在 1 秒之内。如果超过 10 秒,则一定是客户端网络出了问题。手机休眠时,也能够及时地收到推送消息。

 三、Android SDK 概述

 

开发者集成 JPush Android SDK 到其应用里,JPush Android SDK 创建到 JPush Cloud 的长连接,为 App 提供永远在线的能力。
当开发者想要及时地推送消息到达 App 时,只需要调用 JPush API 推送,或者使用其他方便的智能推送工具,即可轻松与用户交流。

图中红色部分,是 JPush App 开发者的接触点。手机客户端侧,App 需要集成 JPush SDK;服务器端部分,开发者调用 JPush REST API 来进行推送。

四、 Android SDK 集成指南

一、极光推送SDK集成步骤:

1.导入SDK开发包到你自己的应用程序项目

(1)登陆后,创建应用

 

(2)下载SDK

 

(3)创建一个新应用

 

A.SDK中的JAR包拷入项目。

 

复制动态库文件

 

复制resdrawble中的文件到项目中,复制layout文件夹下的东西到项目中。

2.配置AndroidMainfest.xml文件

A.配置权限:

<!-- Required -->
<permission
android:name="com.example.j.permission.JPUSH_MESSAGE"
android:protectionLevel="signature"
/>
<!-- Required -->
<uses-permission android:name="com.example.j.permission.JPUSH_MESSAGE"/>
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

B:配置application中的内容

<!-- Required SDK核心功能-->
<receiver
android:name="cn.jpush.android.service.PushReceiver"
android:enabled="true"
>
<intent-filter android:priority="1000">
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY"/>
<category android:name="您应用的包名"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT"/>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
<!-- Optional -->
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>

<!-- Required SDK核心功能-->
<activity
android:name="cn.jpush.android.ui.PushActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.NoTitleBar"
android:exported="false"
>
<intent-filter>
<action android:name="cn.jpush.android.ui.PushActivity"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="您应用的包名"/>
</intent-filter>
</activity>

<!-- Required SDK核心功能-->
<service
android:name="cn.jpush.android.service.DownloadService"
android:enabled="true"
android:exported="false"
>
</service>

<!-- Required SDK核心功能-->
<receiver android:name="cn.jpush.android.service.AlarmReceiver"/>

C:复制元数据部分

<!-- Required SDK核心功能-->
<receiver android:name="cn.jpush.android.service.AlarmReceiver"/>
<!-- Required. For publish channel feature -->
<!-- JPUSH_CHANNEL 是为了方便开发者统计APK分发渠道。-->
<!-- 例如: -->
<!-- 发到 Google Play 的APK可以设置为 google-play; -->
<!-- 发到其他市场的 APK 可以设置为 xxx-market。 -->
<!-- 目前这个渠道统计功能的报表还未开放。-->
<meta-data android:name="JPUSH_CHANNEL"android:value="developer-default"/>
<!-- Required. AppKey copied from Portal -->
<meta-data android:name="JPUSH_APPKEY"android:value="您应用的Appkey"/>

3.添加初始化代码

(1)创建App这个类,并在application中进行配置。

(2)配置gradle.

4.测试是否成功,

 

五、推送常识问题:

1. 正常工作的必要条件JPush SDK JPush Server 的网络保持着连接。

2.手机休眠时收不到 JPush 消息,解锁或屏幕灯亮则可以成功接收这个现象表明,手机休眠时,JPush SDK “被迫与服务器端的网络失去了连接。

3.JPush SDK 的工作原理是要确保在手机休眠时也能正常的工作,即休眠时也可以及时地收到Push消息。这个被迫,是由 Android 设备的环境所导致的。涉及的原因有如下几个方面:

1手机本身的网络设置。标准版本的 Android ROM 是没有这个设置的,但某些特殊的 ROM 可能会有这方面的设置。

2手机上的安全、省电工具软件额外做的事情.

上述的特殊机制会关闭网络。网络一旦连接上,JPush也会连接上服务器,从而Push消息就会收到。

4.有时候收到 JPush 消息很及时,有时候则要等几分钟

JPush 会监听网络切换广播。当网络关闭时,把原来JPush连接关闭。当有新的网络时,创建JPush连接。另外,RTC会定时发送心跳。如果之前的网络已经断了,则会重新连接。

应该说,当前的网络连接策略还是相对简单的,这样做的目的是:省电、省流量。不好之处就是:网络没有切换时,因为当时网络过差,JPush连接会被中断。这种情况下,就只能等 RTC 心跳去触发连接。这也是有时候JPush 无法及时接收Push消息的原因。根据网络条件的不同,出现这个情况的概率也会不同。但据我们自己的测试,90% 的时候是可以及时地收到Push消息的。

JPush 目前在网络策略方面没有像微信这种聊天工具做得积极。如果这样做到,电量和流量的消耗必然会成倍地增加。

5.完全收不到 JPush 消息

如果集成之后就完全收不到Push消息,则很有可能是某个地方配置错误。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhwadezh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值