精华内容
下载资源
问答
  • 极光推送原理

    2015-06-16 15:43:59
    因为手机平台本身、电量、网络流量的限制,移动互联网应用在...一种是定时去服务器上查询数据,也叫Polling,还有一种手机跟服务器之间维护一个 TCP 长连接,当服务器有数据时,实时推送到客户端,也就是我们说的 Pu

    因为手机平台本身、电量、网络流量的限制,移动互联网应用在设计上跟传统 PC 上的应用很大不一样,需要根据手机本身的特点,尽量的节省电量和流量,同时又要尽可能的保证数据能及时到达客户端。

    为了解决数据同步的问题,在手机平台上,常用的方法有2种。一种是定时去服务器上查询数据,也叫Polling,还有一种手机跟服务器之间维护一个 TCP 长连接,当服务器有数据时,实时推送到客户端,也就是我们说的 Push。

    从耗费的电量、流量和数据送达的及时性来说,Push 都会有明显的优势,但 Push 的实现和维护成本相对较高。在移动无线网络下维护长连接,相对也有一些技术上的难度。本文试图给大家介绍一下我们极光推送在 Android 平台上是如何维护长连接。

    移动无线网络的特点

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

    http://www.cisco.com/en/US/i/100001-200000/110001-120000/119001-120000/119935.jpg

    图片源自 cisco.com. 

    NAT 功能由图中的 GGSN 模块实现。

    大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断。

    Android 平台上长连接的实现

    为了不让 NAT 表失效,我们需要定时的发心跳,以刷新 NAT 表项,避免被淘汰。

    Android 上定时运行任务常用的方法有2种,一种方法用 Timer,另一种是AlarmManager。

    Timer

    Android 的 Timer 类可以用来计划需要循环执行的任务,Timer 的问题是它需要用 WakeLock 让 CPU 保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间。这种方式不能满足我们的需求。

    AlarmManager

    AlarmManager 是 Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。

    这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。极光推送的 Android SDK 就是基于这种技术实现的。

    服务器设计

    当有大量的手机终端需要与服务器维持长连接时,对服务器的设计会是一个很大的挑战。

    假设一台服务器维护10万个长连接,当有1000万用户量时,需要有多达100台的服务器来维护这些用户的长连接,这里还不算用于做备份的服务器,这将会是一个巨大的成本问题。那就需要我们尽可能提高单台服务器接入用户的量,也就是业界已经讨论很久了的 C10K 问题。

    C2000K

    针对这个问题,我们专门成立了一个项目,命名为C2000K,顾名思义,我们的目标是单机维持200万个长连接。最终我们采用了多消息循环、异步非阻塞的模型,在一台双核、24G内存的服务器上,实现峰值维持超过300万个长连接。

    后记

    稳定维护长连接是推送平台的一个基础,极光推送团队将会在这方面长期投入,以保证用户能有效的节省电量、流量,同时数据能实时送达。

    展开全文
  • 初接触极光推送的使用者,为了衡量消息推送的质量。经常会纠结到消息的"送达率"这个概念.那么究竟什么是消息送达率呢?或者如何正确理解消息的送达情况呢?基本概念先来看与消息送达相关的几个基本概念:iOS 目标用户...

    89221208a676997f63a5ee80295d05cf.png

    初接触极光推送的使用者,为了衡量消息推送的质量。经常会纠结到消息的"送达率"这个概念.那么究竟什么是消息送达率呢?或者如何正确理解消息的送达情况呢?

    基本概念

    先来看与消息送达相关的几个基本概念:

    iOS 目标用户数:匹配推送条件的 iOS 用户的数量。

    iOS消息推送成功数:推送到 APNS 并被 APNS 成功接收的数量。如果 device token 变更,过期或者与推送环境不匹配则不会成功。

    Android 目标用户数:匹配推送的条件的Android 用户数(1个月内与服务器有过连接的用户。如果超过1个月都没有与 JPush server 产生任何连接,那么将不向此用户推送)。

    Android 在线推送数:消息推送时,目标用户在线,通过在线下发的消息数。Android 用户长连接在线会通过在线下发,其余用户通恢复网络后触发缓存的离线消息。

    Android消息送达数:消息送达到客户端,并且服务端确认收到了客户端的应答的数量。

    点击数:本次推送被用户点击的次数。

    送达率的伪命题

    197719bb019ab590aa046c53bac0cacb.png

    如图所示,最外圈的 Total 代表全部的注册用户,即应用创建依赖所有的注册用户数。接下来是目标用户(target)所有的消息推送都会有一个目标用户,这个目标用户是指符合条件的用户,系统会根据推送条件匹配出推送的目标用户。即使作为目标用户也可能包括已经卸载了,或者以后根本不联网的用户,因为JPush 系统是无法获取这些状态的。

    每一次消息推送都会有一个送达数,当一次消息推送产生的时候,目标用户中会有一些当时在线和一些不在线的。系统会根据用户的状态立即向在线的用户进行推送, 当时不在线的用户系统会为其保存离线消息,消息有效期之内用户恢复网络后,系统会将离线消息发送到用户客户端。

    针对用户的在线和离线情况,了解了一个消息的推送可能后,再来看“送达率”:

    在线送达率=在线用户中成功接收的数量/在线用户数

    离线送达率 = 离线消息送达数/离线消息下下发数。

    只有这个送达率才是真正的送达率,至于有一部分用户虽然是目标用户,但是推送后一直离线或者已经卸载了应用,系统是不可能把消息发送给他们的。所以如果计算送达率的时候把这部分用户计算上显然无法说明什么,而且这部分用户随着一个应用的时间越来越长,数值可能会越来越大。

    如果是广播推送,目标用户数比较多,这个真正的送达比率基本上是固定在98%左右。为什么这么说,因为可以影响真是送达率的原因主要是用户网络联通的稳定性,可能发送的时候用户状态还是在线,当消息发送的时候用户已经处于离线状态了,这部分用户就需要恢复连接的时候接收离线消息了。

    送达数预期

    作为一个极光推送的使用者,通过什么数值衡量消息的推送情况呢? 在线用户数,没错就是在线用户数。因为一条消息,从产生的那一个时刻一直到消息有效期超期,在这段期间在线或者登录过的用户才会收到消息。例:一般一条广播消息的默认有效期为24小时,那么这条消息最终的送达数量应该略小于当天的天在线用户数,为什么小于是因为有一部分在线用户数是消息推送后才注册的新用户,这部分用户是不会收到之前的消息的。

    稍后极光推送会开放每条消息发送时的在线推送数统计。

    结论

    “在线用户数” 才是可以用来衡量推送成功数的值。 “消息送达 ➗ 目标总数”并不是真正的送达率,这个比率没有太多的参考意义。真正的送达率其实是一个比较稳定的值。

    作者:极光推送产品总监 吕鑫

    69cb6f1463a395931f305761116ab8fe.png

    极光推送(JPush)是独立的第三方云推送平台,核心团队由原华为、腾讯、新浪、Oracle等前员工为班底组建,致力于为全球移动应用开发者提供专业、高效的移动消息推送服务。

    极光推送当前已为超过30000家企业及个人开发商,60000多款移动应用提供稳定的毫秒级送达移动消息推送方案,服务总用户数已经超过7亿,覆盖近4亿Android和iOS终端,日活跃推送用户超过7000万。

    免费体验官网地址:www.jpush.cn        400-612-5955

    展开全文
  • JPush极光推送原理

    2020-05-09 15:29:38
    相信开发者们一定不陌生JPush极光推送,像QQ、微信的推送机制,QQ采用的是APNS推送服务,微信则采用google的GCM推送机制,很多人都说APNS是一个死流氓服务,我也没去了解,而GCM有点像IOS自带的推送,有待了解。...

     相信开发者们一定不陌生JPush极光推送,像QQ、微信的推送机制,QQ采用的是APNS推送服务,微信则采用google的GCM推送机制,很多人都说APNS是一个死流氓服务,我也没去了解,而GCM有点像IOS自带的推送,有待了解。很多项目做一些通讯功能,大部分人都会选择JPush极光推送,因为用起来简单,代码量也少,JPush官网上的开发文档也写的相当清楚,一些步骤也清晰明了。今天在这边主要就是讲一下推送的原理,以及demo测试中会遇到的问题,这也是移植到项目中易出错的地方。

    极光推送的功能:主动 即时的向用户发起交互,可以发送聊天信息等; 
    ——作用:通过向精准的目标用户推送有价值的消息,可以提供用户的忠诚度,提高留存率。

    (1)推送方式 
    ——发送通知:推送的文本内容,展示在通知栏上面; 
    ——自定义消息:推送自定义消息,给用户自行处理; 
    ——富媒体:推送的是HTML网页内容。

    (2)推送目标 
    ——广播推送:向所有用户发送广播信息; 
    ——标签推送 Tag:根据用户设置自定义的标签分组,向某一组推送消息; 
    ——别名推送 Alias:客户端绑定用户自定义的用户别名,向单个用户推送消息。

    (3)用户分群 
    ——用户分群:可以根据JPush提供的多条件组合,对用户进行群组划分,实现实时筛选推送。

    (4)推送历史 
    ——推送历史:通过WEB或者API发出的推送,都可以在推送历史记录中查询到,并可以实时显示推送结果数据。

    推送框架
    ——推送的数据源:自己开发的服务器端或者使用极光推送官网的WEB后台; 
    ——JPush API:部署在服务器端,开发者的服务器端发起推送时,将数据传到JPush API中,然后向下传递; 
    ——建立长链接:集成JPush的SDK客户端启动后会建立一个到JPush Cloud的长链接,提供App永远在线的能力(可以参考极光推送官方博客); 
    ——原理图: 


    客户端原理
    IP地址的分配原理 
    ——IP地址有限:IPv4的IP地址数量有限,运营商要动态的为手机分配IP地址,这些IP地址都是运营商的内网IP; 
    ——网络地址转换(NAT):全称Network Address Translation,网关维护一个外网IP地址,与内网的IP地址对应; 
    ——外网IP不固定:由于运营商持有的外网IP数量有限,需要动态的为分配给接入运营商的用户,因此在手机一段时间没有数据传输时会将该手机分配的外网IP地址收回,分配给其他用户; 
    ——解决方案:Android手机端想要保持长链接,首先外网IP地址不能变,不能让运营商收回这个IP地址。

    Android手机端实现方案 
    ——心跳:为了长时间保持外网IP,需要客户端定期发送心跳给运营商,以便刷新NAT列表; 
    ——Timer定时方法:该类计划循环执行定时任务,但是使用该类会使CPU保持唤醒状态,比较费电。 
    ——AlarmManager定时方法:该类封装了Android手机的RTC硬件时钟模块,可以在CPU休眠时正常运行,保持任务执行时再唤醒CPU,这样做到了电量节省。

    简单demo容易出错的地方 
    ·Appcation中初始化JPush 
    ——JPushInterface.init(this); // 初始化 JPush 
    ·启动的主程序里面一定要复写两个生命周期:

    @Override
        protected void onPause() {
            isForeground = false;
            super.onPause();
            JPushInterface.onPause(MainActivity.this);
        }

    @Override
        protected void onResume() {
            isForeground = true;
            super.onResume();
            JPushInterface.onResume(MainActivity.this);
        }

    注意:如果主程序里面的Activity继承的是InstrumentedActivity,则不需要写JPushInterface.onResume(MainActivity.this);我的MainActivity继承的是FragmentActivity,所以加上了这句。

    这是我的demo代码,贴出来大家看的比较清晰些:

    package com.lai.jpushdemo;
     
    import android.os.Bundle;
    import android.os.Handler;
    import android.support.v4.app.FragmentActivity;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.widget.Toast;
     
    import com.ms.stock.R;
     
    import java.util.LinkedHashSet;
    import java.util.Set;
     
    import cn.jpush.android.api.JPushInterface;
    import cn.jpush.android.api.TagAliasCallback;
     
     
    public class MainActivity extends FragmentActivity{
        private static final String TAG = "JPush";
     
     
        @Override
        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setTag("abc");
        }
     
        /**
         * 设置tags
         */
        private void setTag(String tag){
     
            // 检查 tag 的有效性
            if (TextUtils.isEmpty(tag)) {
                Toast.makeText(MainActivity.this,R.string.error_tag_empty, Toast.LENGTH_SHORT).show();
                return;
            }
            // ","隔开的多个 转换成 Set
            String[] sArray = tag.split(",");
            Set<String> tagSet = new LinkedHashSet<String>();
            for (String sTagItme : sArray) {
                if (!ExampleUtil.isValidTagAndAlias(sTagItme)) {
                    Toast.makeText(MainActivity.this,R.string.error_tag_gs_empty, Toast.LENGTH_SHORT).show();
                    return;
                }
                tagSet.add(sTagItme);
            }
            //调用JPush API设置Tag
            mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_TAGS, tagSet));
     
        }
     
     
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK){
                finish();
            }
            return super.onKeyDown(keyCode, event);
        }
     
     
     
     
        private final TagAliasCallback mTagsCallback = new TagAliasCallback() {
     
            @Override
            public void gotResult(int code, String alias, Set<String> tags) {
                String logs ;
                switch (code) {
                case 0:
                    logs = "设置别名和标签成功!";
                    Log.i(TAG, logs);
                    break;
     
                case 6002:
                    logs = "设置超时,60s后重试!";
                    Log.i(TAG, logs);
                    if (ExampleUtil.isConnected(getApplicationContext())) {
                        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SET_TAGS, tags), 1000 * 60);
                    } else {
                        Log.i(TAG, "没有连接网络");
                    }
                    break;
     
                default:
                    logs = "失败代码 = " + code;
                    Log.e(TAG, logs);
                }
     
                ExampleUtil.showToast(logs, getApplicationContext());
            }
     
        };
        private static final int MSG_SET_TAGS = 1002;
     
     
        private final Handler mHandler = new Handler() {
            @Override
            public void handleMessage(android.os.Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
     
                case MSG_SET_TAGS:
                    Log.d(TAG, "在handler里面设置tags");
                    JPushInterface.setAliasAndTags(getApplicationContext(), null, (Set<String>) msg.obj, mTagsCallback);
                    break;
     
                default:
                    Log.i(TAG, "handler没有内容 - " + msg.what);
                }
            }
        };
     
        public static boolean isForeground = false;
     
        @Override
        protected void onResume() {
            isForeground = true;
            super.onResume();
            JPushInterface.onResume(MainActivity.this);
        }
     
     
        @Override
        protected void onPause() {
            isForeground = false;
            super.onPause();
            JPushInterface.onPause(MainActivity.this);
        }
     
    }

    这里设置的Tag值是写死的(我项目中只用到Tag),写成动态的话,后面大家可以写到Appcation里面。

    ·别忘记添加jar包和.so文件 
      如果博友用eclipse开发的话,直接把jar和.so文件添加到libs目录中即可,如果用的是android studio,则需要把.so文件单独放进jniLibs文件夹中(注意:studio新建的文件夹自带是jni,这边的jniLibs目录是需要手动去重命名文件夹,经测试,如果是jni文件夹,项目会异常,找不到文件,所以必须是jniLibs)。

    ·AndroidManifest.xml 
      *权限(uses-permission)一定要放在appcation前面。 
    这点大家注意下,昨天因为这个问题折腾了好久,我的习惯就是先写一个demo,然后再移植到自己的项目中,这样做起来比较快,也不会太乱。恰恰这个问题让我非常痛苦,最后看了日志才发现的,值得大家注意。
    ————————————————
    版权声明:本文为CSDN博主「上士闻道~勤而行之」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/huangli1466384630/article/details/79889473

    展开全文
  • 推送原理 极光推送使用详解

    作者 : octopus_truth

    转载请注明出处http://blog.csdn.net/shulianghan/article/details/45046283


    推送技术产生场景

    -- 服务器端主动性 : 客户端与服务器交互都是客户端主动的, 服务器一般不能主动与客户端进行数据交互, 因为服务器端无法得知客户端的 IP 地址 及 状态;

    -- 数据实时性 : 如果服务器端有紧急数据要传递给客户端, 就必须主动向客户端发送数据;

    -- 基本原理 : 使客户端实时获取服务器端消息, Pull 方式, 小周期轮询, 费电费流量; 另一个就是 Push 方式, 服务器端向客户端主动推送数据, 可以省电省流量;


    示例代码下载http://download.csdn.net/detail/han1202012/8636005 



    一. 推送原理



    1. Android 推送原理简介


    (1) SMS 方式推送


    SMS 推送

    -- SMS : Short Message Service 缩写, 即短信服务;

    -- 实现方式 : 服务器端向手机端发送短信, 手机监听短信广播, 然后将拦截的短信信息进行显示;

    -- 优点 : 省电, 省流量, 在没有网络的偏远地点也能接收到推送消息;

    -- 缺点 : 费钱, 一毛钱一条;


    (2) 轮询 方式推送


    轮询推送

    -- 实现方式 : 周期性主动获取网络中的数据;

    -- 缺点 : 费电, 费流量;


    (3) 长链接 方式推送


    长链接推送 : 主流方法;

    -- 实现方式 : 手机端与服务器端建立一条长时间的数据流链接, 手机客户端一直等待服务器端的数据;

    -- 优点 : 有一条长链接, 有数据的时候才发送数据, 没有时不消耗流量, 比较省流量;

    -- 缺点 : 由于要保存一条长链接, 比较费电; 在网络不稳定的情况下, 推送容易失败;



    2. Android 推送解决方案简介


    (1) C2DM 推送 (Google)


    C2DM 推送简介 : 全称 Cloudto Device Messaging, Google 提供的 推送解决方案;

    -- 运行方式 : 提供一个轻量级机制, 允许服务器通知应用程序, 主动与客户端进行数据交互, 处理消息排队, 并向运行于目标设备的应用程序分发消息;

    -- 优点 : Google 提供的原生框架, 无需在应用中添加第三方代码 和 部署服务器端;

    -- 缺点 : 1.该推送依赖 Google 服务器, 需要绑定 Google 帐号, 目前在中国 Google 被屏蔽, 无法使用; 2. 许多手机厂商去掉了软件中的该模块;

    -- 运行机制图




    (2) MQTT 推送 (IBM)


    MQTT 推送简介 : MQTT 是轻量级的消息发布|订阅协议, 

    -- 优点 : 省电, 省流量, 轻量级, 有 C++ 版的服务器端组件 RSMB;

    -- 缺点 : RSMB 不开源, 部署成本高, 比较复杂;

    -- IBM相关MQTT官网http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 ;


    RSMB 服务器端 : 全称 Really Small Message Broker, IBM 提供;

    -- 工作方式 : 在服务器端, 接收消息, 并将 消息 传输给指定移动设备;

    -- 地址 http://www.alphaworks.ibm.com/tech/rsmb ;


    MQTT 推送示例

    -- 客户端https://github.com/tokudu/AndroidPushNotificationsDemo ;

    -- 服务器端 PHP : https://github.com/tokudu/PhpMQTTClient ;



    (3) 基于 XMPP 的 AndroidPN 推送 (开源)


    XMPP 推送简介

    -- XMPP 简介 : 全称 Extensible Messaging and Presence Protocol (可扩展通讯和表示协议), 基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测, 该协议允许因特网用户向因特网上的其他任何人发送即时消息;

    -- AndroidPN : 基于 XMPP 协议开发的 Java 开源 Android 推送通知实现, 包含了完整的客户端 和 服务器端;

    -- 项目主页http://sourceforge.net/projects/androidpn/ ;

    -- 原理图



    AndroidPN 缺陷 : 如果使用该框架进行推送, 需要在了解 XMPP 和 anroidPN 基础上进行大量的二次开发;

    -- 连接中断 : 连接时间过长, 连接会中断, 收不到消息;

    -- 稳定性差 : 该框架不是很稳定;

    -- 纠错机制 : 消息推送出去后, 不检查是否推送到客户端, 推送出去就不管了;



    3. 推送 4s 评价标准


    4S 标准Safe(安全), Stable(稳定), Save(省电省流量省成本), Slim(体积小);


    (1) Safe (安全)


    推送安全标准

    -- 透明传输 : 只负责点对点的传输的质量, 不关心中间的传输介质 与 传输业务逻辑 协议等;

    -- 加密方案 : 信息需要加密, 另外推送的 ID 系统需要独立与后台已有的 ID 系统;


    (2) Stable (稳定)


    服务器稳定 : 长链接方案对服务器开销要求很高, 服务器端开发难度很大;

    -- 在线峰值 : 同时在线连接数到达100万的稳定性;

    -- 并发时延 : 高并发时的消息平均延迟, 一分钟处理 100万 条数据;

    -- 服务器稳定 : 稳定性时延占总时间的 99.9%, 有备份和负载均衡的机制;


    客户端稳定 : 中国网络状况复杂, 手机长时间联网比较难, 稳定性比较难, 开发时要考虑每个省的每个运营商, 每款手机的机型;

    -- 联网时间 : 每日联网时间 23.5 小时以上;

    -- 消息到达率 : 消息收到后 9 小时内客户端的消息到达率;


    (3) Save (节省)


    节省评判

    -- 电量节省 : 注意 CPU 休眠率, 服务短待机时间百分比评判;

    -- 流量节省 : 处理协议 和 冗余数据包, 使用空载待机月流量评判;

    -- 成本节省 : 单服务器同时承载连接数, 同时承载连接数越多, 成本越低, 个推单服务器连接 300 万(业内顶尖水平);


    (4) Slim (体积小)


    集成 SDK 大小 : 客户端推送的 SDK 的大小尽量小, 一般要小于 300K;




    二. 极光推送概述



    1. 功能概述


    极光推送基本功能 : 主动 即时 的向用户发起交互, 可以发送聊天消息;

    -- 作用 : 通过向 精准 的目标用户推送 有价值 的消息, 可以提供用户忠诚度, 提高留存率;


    (1) 推送方式


    推送方式简介 : 

    -- 通知 : 推送文本内容, 展示在通知栏中;

    -- 自定义消息 : 推送自定义消息, 给用户自行处理;

    -- 富媒体 : 推送 HTML 页面内容;



    (2) 推送目标


    推送目标简介

    -- 广播推送 : 向所有用户发送广播消息;

    -- 标签推送 : 根据用户设置的标签分组, 向某一组推送消息;

    -- 别名推送 : 客户端绑定用户别名, 向单个用户推送信息;


    (3) 用户分群


    用户分群简介 : 可以根据 JPush 提供的 多条件组合, 对用户进行群组划分, 实现 实时筛选推送;


    (4) 推送历史


    推送历史简介 : 通过 WEB 或者 API 发出的推送, 都可以在推送历史记录中查询到, 并可以实时显示推送结果;




    2. 推送框架



    推送框架 : 

    -- 推送数据源 : 自己开发的服务器端 或者 使用 极光推送官网的 WEB 后台;

    -- JPush API : 部署在服务器端, 开发者的服务器端发起推送时, 将数据传到 JPush API 中, 然后再向下传递;

    -- 建立长链接 : 集成 JPush 的 SDK 客户端启动后会建立一个到 JPush Cloud 的长链接, 提供 App 永远在线的能力; 

    -- 原理图



    3. 极光推送原理


    参考文章(极光推送官方博客) : http://blog.jpush.cn/jpush_wireless_push_principle/ ;


    (1) 客户端原理


    IP地址 分配原理 : 

    -- IP 地址有限 : IPv4 的 IP 地址数量有限, 运营商要动态地为 手机分配 IP 地址, 这些 IP 地址都是运营商的内网 IP;

    -- 网络地址转换 (NAT) : 全称 Network Address Translation, 网关维护一个外网 IP 地址, 与 内网 IP 地址对应;

    -- 外网 IP 不固定 : 由于运营商持有的外网 IP 数量有限, 需要动态的分配给接入运营商的用户, 因此在手机一段时间没有数据传输时会将该手机分配的外网 IP 地址收回, 分配给其它用户;

    -- 解决方案 : Android 手机端想要保持长链接, 首先外网 IP 地址不能变, 不能让运营商收回 这个 IP 地址;


    Android 手机端实现方案 

    -- 心跳 : 为了长时间保持外网 IP, 需要客户端定期发送心跳给运营商, 以便刷新 NAT 列表;

    -- Timer 定时方法 : 该类计划循环执行定时任务, 但是使用该类会使 CPU 保持唤醒状态, 比较费电;

    -- AlarmManager 定时方法 : 该类封装了 Android 手机的 RTC 硬件时钟模块, 可以在 CPU 休眠时正常运行, 定时任务执行时再唤醒 CPU, 这样做到了电量节省;


    (2) 服务器原理


    C10K 问题 : 单台服务器解决 同时保持一万长链接的性能问题;




    4. Android SDK 简介


    Android SDK 本质 : JPush SDK 集成到 Android APP 中后, 作为一个 Service 在 Android 端长期运行, 始终与 服务器端 保持者长链接, 相当与永远在线;


    (1) 多平台支持


    多平台支持

    -- 手机芯片类型 : 一般的手机是 ARM 芯片, 但是有些手机是 MIPS 芯片 或者 x86 芯片;

    -- so 库支持 : 每个 CPU 芯片类型对应的 so 库, 都需要特殊编译, 无法跨平台调用, 如 ARM 平台的 so 库在 x86 平台就无法运行;


    (2) 电量与流量说明


    流量消耗 : JPush 的协议是自定义的, 协议的数据量经过了精简, 流量消耗非常少; 

    电量消耗 : JPush 心跳保持连接时可以在 CPU 不唤醒的情况下执行, 减少了不必要的代码运行, 电量非常节省;


    (3) 相关库说明


    JPush 依赖库

    -- .so 依赖库内容 : JPush 需要一个 so 动态库, 该库是 C 语言编写, 在 Linux 下进行交叉编译而来, 可以在 ARM 芯片的手机上运行;

    -- jar 依赖库内容 : 对 Java 代码的封装;



    三. 极光推送简单 Demo



    Demo 概述 : JPush 官方提供了一个简单 Demo, 向我们演示了 JPush 基本的推送流程, 基本步骤分为下面几块, 即

    -- Web 配置操作部分 : 包括 注册开发者帐号, 创建应用;

    -- 下载手机示例 : 下载系统自动生成的 Android 应用示例;

    -- 发送推送指令 : 在 Web 端发送推送指令, 手机端接收该指令;

    -- 官方地址 : 关于该模块详细信息可参考官方文档, http://docs.jpush.io/guideline/android_3m/ ;



    1. Web 配置操作



    (1) 帐号创建


    该步骤就不再赘述, 普通的帐号注册即可;


    (2) 创建应用


    创建应用步骤

    -- 创建应用界面 https://www.jpush.cn/common/apps ;

    -- 创建应用 : 点击 创建应用 按钮即可;


    -- 配置应用信息 : 输入应用名称, 上传一个图标, 然后填写一个包名, JPush 系统会在后台根据你输入的包名生成的推送的 Android 应用 Demo, 该 Demo 包含了该配置的信息;



    查看应用设置界面



    2. 下载导入 Android 应用源码


    (1) 下载 Android 应用源码


    下载源码 : 在应用设置的 Android 模块, 有 "下载 Android Example" 按钮, 点击该按钮即可下载 Android 应用;



    (2) 导入 Android 应用源码


    将下载后的源码解压, 不用任何修改, 即可导入到应用中运行;




    3. 发送推送



    (1) 不初始化推送无效


    直接在后台推送 : 我们在 Android 手机界面不做任何操作, 直接在网页后台推送消息; 

    -- 发送通知 : 在应用的 "推送" 模块, 点击发送通知按钮;


    -- 输入推送内容 : 输入任意推送内容 "Jpush Demo Send By octopus 1.", 点击页面最下方的 "立即发送" 按钮;



    -- 对话框选择 : Web 界面会弹出对话框, 提示是否发送, 选 "发送吧" 即可;


    -- 查看推送结果 : 点击之后又弹出对话框, 点击 "去看看" 可以查看推送结果;


    -- 推送结果分析 : 点击上面的 "去看看" 可以查看推送结果, 点击 "推送历史" 按钮, 也可一查看推送结果; 由于我们没有在 客户端进行初始化, 因此推送没有成功;




    (2) 初始化后推送


    初始化之后推送

    -- 手机端初始化 : 点击手机端的 "initPush" 按钮, 进行初始化;


    -- 发送消息 : 发送 "Jpush Demo Send By octopus 2." 消息, 此时连上一次推送的消息也送达, 网络不同会延迟一定时间;


    -- 查看发送结果 : 此时显示的推送, 两次都成功了;




    (3) 停止 和 恢复 推送功能


    停止恢复推送功能 : 当点击停止推送 "stopPush" 按钮时, 推送手机端就不会再接收推送内容, 当点击恢复推送时, 会将期间积攒的所有推送内容一次性推送到手机中;




    四. Android 应用集成 JPush



    1. 依赖库拷贝


    (1) SDK 简介


    SDK 下载 : 最新的 SDK 压缩包 Jpush-Android-sdk-1.7.3.zip ;

    -- JPush SDK 下载页面 : http://docs.jpush.io/resources/ ;

    -- Android SDK 下载地址 : https://www.jpush.cn/downloads/sdk/android/


    详细文件说明 : 将 Jpush-Android-sdk-1.7.3.zip 解压, 解压后的目录是 Jpush-Android-sdk;

    -- 查看文档目录 : 使用 tree -L 3 命令, 查看深度为 3 的路径结构;

    octopus@octopus:~/JPush/Jpush-Android-sdk$ tree -L 3
    .
    ├── AndroidManifest.xml
    ├── ChangeLog.txt
    ├── doc
    │   └── Jpush-sdk-集成指南.pdf
    ├── example
    │   ├── AndroidManifest.xml
    │   ├── libs
    │   │   ├── armeabi
    │   │   ├── armeabi-v7a
    │   │   └── jpush-sdk-release1.7.3.jar
    │   ├── proguard-project.txt
    │   ├── project.properties
    │   ├── res
    │   │   ├── drawable-hdpi
    │   │   ├── drawable-ldpi
    │   │   ├── drawable-mdpi
    │   │   ├── drawable-xhdpi
    │   │   ├── layout
    │   │   ├── values
    │   │   └── values-zh
    │   └── src
    │       └── com
    └── libs
        ├── armeabi
        │   └── libjpush173.so
        ├── armeabi-v7a
        │   └── libjpush173.so
        └── jpush-sdk-release1.7.3.jar

    -- AndroidManifest.xml (配置文件) : 这是 Android 应用的主要配置文件示例;

    -- ChangeLog.txt (升级说明) : SDK 版本升级的说明;

    -- doc (文档) : doc 目录下 有个 "Jpush-sdk-集成指南.pdf" 文档, 这是集成 JPush 文档;

    -- example (代码示例) : example 明显是个 Android 示例 demo;

    -- libs (依赖库) : Android 应用中相关库, 放在这个目录中, libjpush173.so 是依赖的 C 底层库, jpush-sdk-release1.7.3.jar 是依赖的 Java 库;



    (2) 拷贝 依赖库 到 Android 应用中


    执行过程

    -- 创建应用 : 创建一个空应用, 注意应用最小版本应大于 2.1, 否则不能支持极光推送, 应用的包名为 cn.org.octopus.jpush.demo 即可, 不用在后台另外创建一个

    -- 拷贝依赖库 : 在工程根目录下创建一个 libs 目录, 拷贝 jpush-sdk-release1.7.3.jar 到 libs 目录中, 将 armeabi/libjpush173.so 和 armeabi-v7a/libjpush173.so 拷贝到 libs 目录, 注意要连文件夹一起拷贝, 拷贝完后如下图;



    2. 配置 AndroidManifest.xml 文件


    (1) 权限配置


    JPush 定义权限 : JPush 定义了一个权限, 允许应用接收 JPush 代码发送的广播消息, You Package.permission.JPUSH_MESSAGE, 注意要使用你的包名替换其中的 Your Package;

    <!-- Required -->
        <permission android:name="Your Package.permission.JPUSH_MESSAGE" android:protectionLevel="signature" />


    用户权限

    <!-- Required -->
        <uses-permission android:name="You Package.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" />

    可选用户权限

        <!-- Optional. Required for location feature -->
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />


    (2) 配置 JPush 服务


    JPush 服务

    -- 推送服务

            <!-- Required -->
            <service
                android:name="cn.jpush.android.service.PushService"
                android:enabled="true"
                android:exported="false" >
                <intent-filter>
                    <action android:name="cn.jpush.android.intent.REGISTER" />
                    <action android:name="cn.jpush.android.intent.REPORT" />
                    <action android:name="cn.jpush.android.intent.PushService" />
                    <action android:name="cn.jpush.android.intent.PUSH_TIME" />
                </intent-filter>
            </service>

    -- 下载服务

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




    (3) 配置 JPush 广播接收者


    JPush 广播接收者配置

    -- 推送接收者

    <!-- Required -->
            <receiver
                android:name="cn.jpush.android.service.PushReceiver"
                android:enabled="true" >
              <intent-filter android:priority="1000"> <!--since 1.3.5 -->
                    <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> <!--since 1.3.5 -->
                    <category android:name="Your Package" /> <!--since 1.3.5 -->
                </intent-filter> <!--since 1.3.5 -->
                <intent-filter>
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                </intent-filter>
                <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核心功能-->
            <receiver android:name="cn.jpush.android.service.AlarmReceiver" />



    (4) 配置 渠道 和 推送标识


    渠道 和 AppKey 配置

            <!-- 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="Your AppKey"/> 


    (5) 最终的配置文件


    配置好的文件

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="cn.org.octopus.jpush.demo"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="17"
            android:targetSdkVersion="19" />
        
        <permission android:name="cn.org.octopus.jpush.demo.permission.JPUSH_MESSAGE" android:protectionLevel="signature" />
        
        <uses-permission android:name="cn.org.octopus.jpush.demo.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_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
            <activity
                android:name=".MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            
            <service
                android:name="cn.jpush.android.service.PushService"
                android:enabled="true"
                android:exported="false" >
                <intent-filter>
                    <action android:name="cn.jpush.android.intent.REGISTER" />
                    <action android:name="cn.jpush.android.intent.REPORT" />
                    <action android:name="cn.jpush.android.intent.PushService" />
                    <action android:name="cn.jpush.android.intent.PUSH_TIME" />
                </intent-filter>
            </service>
            
            <service
                android:name="cn.jpush.android.service.DownloadService"
                android:enabled="true"
                android:exported="false" >
            </service>
            
            <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="cn.org.octopus.jpush.demo" /> 
                </intent-filter> 
                <intent-filter>
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                </intent-filter>
                <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>
            
            <receiver android:name="cn.jpush.android.service.AlarmReceiver" />
    
            <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
            <meta-data android:name="JPUSH_APPKEY" android:value="fd5eebd555ca4a5a80c4b3d8"/> 
            
        </application>
    
    </manifest>


    3. 推送测试


    后台推送

    -- 控制台地址 : https://www.jpush.cn/common/apps/ ;

    -- 发起推送 : 进入控制台, 点击对应的应用, 进入推送页面;


    -- 查看结果


    -- 推送统计





    五. JPush 相关 API



    1. 初始化 停止 恢复 推送


    推送控制方法

    -- 初始化推送 : JPushInterface.init(Context context), 初始化之后才能接收推送消息;

    -- 恢复推送 : JPushInterface.resumePush(Context context), 停止推送后, 调用该方法, 即可恢复推送;

    -- 停止推送 : JPushInterface.stopPush(Context context), 调用该方法之后, 手机便收不到推送信息了;


    代码示例

    	public void onClick(View view) {
    		int id = view.getId();
    		switch (id) {
    		case R.id.init_jpush:
    			//初始化 JPush, 初始化之后才可以进行推送, 否则推送失败
    			JPushInterface.init(this);
    			//设置调试模式, 可以在 LogCat 中查看 JPush 日志
    			JPushInterface.setDebugMode(true);
    			break;
    		case R.id.start_jpush:
    			//恢复推送
    			JPushInterface.resumePush(getApplicationContext());	
    			break;
    		case R.id.stop_jpush:
    			//停止推送
    			JPushInterface.stopPush(getApplicationContext());
    			break;
    
    		default:
    			break;
    		}
    	}

    界面效果及说明

    -- 界面效果


    -- 按钮说明 : 点击 "初始化" 按钮就可以接收推送消息, 点击 "停止推送" 按钮手机停止接收消息推送, 点击 "恢复推送" 即开始接收推送消息;



    2. 根据 别名 和 标签 分组推送


    参考文档http://docs.jpush.cn/pages/viewpage.action?pageId=557241


    (1) 概念介绍


    别名

    -- 作用 : 别名用于代表安装了应用的用户, 每个用户对应着一个别名;

    -- 用户与别名对应性 (多对一) : 每个用户只能指定一个别名, 一个别名可以同时指定给多个用户, 给别名发消息时, 会同时给所有设置该别名的用户发消息;


    标签

    -- 作用 : 方便开发者根据标签发送推送消息;

    -- 用户与标签对应性(多对多) : 一个用户可以有多个标签, 一个标签可以设置给多个用户;



    (2) 设置别名标签接口方法


    设置别名与标签方法

    -- 方法接口

    public static void setAliasAndTags(
    	Context context, 		//上下文对象
    	String alias, 			//别名, 只能设置一个别名
    	Set<String> tags, 		//标签集合, 可设置多个标签
    	TagAliasCallback callback)	//回调接口, 其中有一个 gotResult 接口方法, 系统回传入错误码给 responseCode 参数
    -- 别名设置说明 : a. 设置 null(没有地址) 即不设值值; b. 设置 "" (初始化后) 即清空之前的设置; c. 设置会覆盖之前的设置; d. 长度 40字节 UTF8 编码;

    -- 标签设置说明a. 设置 null(没有地址) 即不设值值; b. 设置 空集合(没有数据, 已经初始化) 即清空之前的设置; c. 设置会覆盖之前的设置; d. 每个标签长度 40字节 UTF8 编码, 最多 100 个标签;


    设置别名方法

    -- 方法接口

    public static void setAlias(
    	Context context, 		//上下文对象
    	String alias, 			//别名内容
    	TagAliasCallback callback)	//回调接口

    -- 参数说明 : 该参数与 setAliasAndTags 方法参数相同;


    设置标签方法

    -- 方法接口

    public static void setTags(
    	Context context, 
    	Set<String> tags, 
    	TagAliasCallback callback)

    -- 参数说明该参数与 setAliasAndTags 方法参数相同;



    过滤无效标签 : 感觉这纯属 JPush API 定义缺陷, 这个应该对我们隐藏才对;

    -- 方法接口

    public static Set<String> filterValidTags(Set<String> tags)

    -- 作用 : 设置标签时如果 标签Set集合  中有一个是无效的, 那么整个设置都无效, 应该是设计缺陷, 后期修补 BUG 的权益之际;


    回调接口 : TagAliasCallback 回调接口;

    -- 方法接口

    public void gotResult(
    	int responseCode, 	//错误码
    	String alias, 		//别名
    	Set<String> tags);	//标签集合


    代码示例

    -- 设置方法代码

    			String alias = set_alias.getText().toString();
    			String tag = set_tag.getText().toString();
    			Set<String> set = new HashSet<String>();
    			set.add(tag);
    			JPushInterface.setAliasAndTags(
    					getApplicationContext(), 
    					alias, 
    					set, 
    					this);
    			Log.i(TAG, "已设置别名 与 标签");
    -- 回调方法

    	@Override
    	public void gotResult(int arg0, String arg1, Set<String> arg2) {
    		Log.i(TAG, "错误码 : " + arg0 + " , 别名 : " + arg1);
    	}

    -- 手机端设置


    -- 后台发送极光推送


    -- 设置标签


    -- 标签报错 : 如果设置的标签没有手机注册, 会出现如下报错;


    -- 推送结果


    -- 推送通知消息






    3. 根据 RegistrationID 进行单机推送


    参考文档 : http://docs.jpush.cn/pages/viewpage.action?pageId=8814639 


    (1) 概念介绍


    RegistrationID 简介 : 应用第一次注册到 JPush 后台时, 会生成一个唯一的设备标识 RegistrationID, 每个设备不重复; 


    (2) 获取 RegistrationID 


    方法接口

    //SDK 初次注册成功后,开发者通过在自定义的 Receiver 里监听 Action - cn.jpush.android.intent.REGISTRATION 来获取对应的 RegistrationID。注册成功后,也可以通过此函数获取
     
    public static String getRegistrationID(Context context)
    -- 获取 RegistrationID 代码

    			//获取 RegistrationID
    			String registrationid = JPushInterface.getRegistrationID(getApplicationContext());
    			tv_registrationid.setText("RegistrationID : " + registrationid);

    -- 界面示例

     

    -- 后台推送设置




    4. 清除通知



    清除通知简介

    -- 方法接口

    public static void clearAllNotifications(Context context);

    -- 代码示例

    case R.id.clear_notification:
    			//清除所有通知
    			JPushInterface.clearAllNotifications(getApplicationContext());
    			break;
    -- 效果 : 在后台发送一条消息, 点击清除按钮, 所有的推送通知都清除;





    5. 推送时间限制



    (1) 设置允许推送时间


    方法接口

    public static void setPushTime(
    	Context context, 	//上下文对象
    	Set<Integer> weekDays, 	//允许接收推送的 一周天数
    	int startHour, 		//开始时间
    	int endHour)		//结束时间
    -- 代码示例

    Set<Integer> days = new HashSet<Integer>();
    days.add(1);
    days.add(2);
    days.add(3);
    days.add(4);
    days.add(5);
    JPushInterface.setPushTime(getApplicationContext(), days, 10, 23);


    (2) 设置禁止推送时间


    方法接口

    public static void setSilenceTime(
    	Context context, 	//上下文对象
    	int startHour, 		//开始时间-小时
    	int startMinute, 	//开始时间-分钟
    	int endHour, 		//结束时间-小时
    	int endMinute)		//结束时间-分钟
    -- 代码示例

    JPushInterface.setSilenceTime(getApplicationContext(), 22, 30, 8, 30);





    作者 : octopus_truth

    转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/45046283

    展开全文
  • 推送是手机中非常常见的功能了。可是在实现上iOS和Andriod却有很大的差别。  因为iOS有强大的产品生态体系,APP从研发到审核上架,再到最后在手机端运行,都有严格的把关。所以推送功能在它这里实现起来比较简单。...
  • 推送技术产生场景: 服务器端主动发出:通常情况下,客户端与服务器交互都是客户端主动的,服务器一般不能主动与客户端进行数据交互,因为服务器端无法得知客户端的IP地址和状态。 数据实时性:如果服务器端有紧急...
  • 在Android应用开发的过程中,可能需要服务器推送消息到Android...我们这里介绍一种第三方推送平台-极光推送(JPush)。 1.极光推送(JPush)简介 极光推送(JPush) 是国内比较早提供推送服务的第三方推送平台,极光推
  • JPush极光推送原理与简单demo的实现会遇到的问题

    万次阅读 多人点赞 2016-05-04 11:15:23
    JPush极光推送原理与简单demo的实现会遇到的问题
  • 推送,极光推送

    2016-11-07 11:12:37
    推送的原理其实也很简单,拿极光推送来说,首先,APP登录的时候,调用极光的API,设置当前登录的信息到极光;服务器发送推送时,只要将需要推送的信息和相应的唯一标识传给极光,就可以了。 附上服务器端简单...
  • 极光推送经验之谈-Java后台服务器实现极光推送的两种实现方式 原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6439313.html Java后台实现极光推送有两种方式,一种是使用极光推送...
  • 1. 极光推送集成背景 最近在研究推送和长连接,研究了几家这方面的平台之后,最后综合考虑选择了极光推送。长连接保活一直是一个大问题,尤其的android方面,最近谷歌公司的几次更新,android应用保活是越来越难做...
  • 极光推送简介随着智能终端的不断普及,人们对信息实时性和交互性都提出了更高的要求,推送能力已经成为一款APP的基础功能,在满足消息推送的基础上还可以帮助提升用户活跃度,增加互动性。 极光推送正是一个整合了A...
  • 看了极光推送技术原理的几点思考 分类:android2012-11-26 20:5016586人阅读评论(18)收藏举报 目录(?)[+] 移动互联网应用现状 因为手机平台本身、电量、网络流量的限制,移动互联网应用在设计上跟传统 PC 上...
  • 极光推送

    2015-08-08 09:30:01
    1.极光推送 1.在官网注册添加应用 2.下载demo来看 3.sdk文档 2.极光推送扩展
  • 极光推送保活

    千次阅读 2019-06-13 15:33:28
    极光推送app退到后台或息屏后,收不到推送消息,在网上查资料,在不自动清理的情况下,可以一直受到消息,就是费电。 资料来源于 https://blog.csdn.net/wusj3/article/details/83269293 ... 首先,需要一个不被杀死...
  • 一般App都会有消息推送的功能,如果是原生安卓或者IOS集成消息推送很容易,各大推送平台都有相关的Sample,但是关于Xamarin....1、了解极光推送原理:https://docs.jiguang.cn/jpush/client/Android/android_sdk/ ...
  • 极光推送服务的原理

    2013-10-17 14:03:00
    http://wenku.baidu.com/view/2f5a3604844769eae009ed94.html 转载于:https://www.cnblogs.com/hewenwu/articles/3374035.html
  • 最近公司让集成极光推送,实现个人推送还有所有下载app 的推送。去极光官网看了下资料,发现极光更新了,从sdk.3.0.7 开始用新的设置别名和Tag的方法,以前的方法不再维护了。。。那肯定得研究新的方法,下面是我的...
  • 请参考这篇文章来做进一步的理解:极光推送技术原理:移动无线网络长连接。推送流程开发者集成 JPush Android SDK 到其应用里,JPush Android SDK 创建到 JPush Cloud 的长连接,为 App 提供永远在线的能力。当...
  • 极光推送JPush使用Java SDK开发

    千次阅读 2019-01-15 16:14:27
    一、极光推送是什么? 极光推送消息介绍 上面是极光官方文档的介绍说明,作为初次使用者。如果对于官方文档解释看不明白的,可以多去网上找一些通俗易懂的博客文章之类的,然后再去看官方文档,最后再按需要进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,953
精华内容 781
关键字:

极光推送原理