刘旭
刘旭
  • 发布:2016-11-30 01:09
  • 更新:2022-11-14 19:27
  • 阅读:56597

个推 解决Android应用后台运行无法接受推送的问题。

分类:HTML5+

【问题描述】

这个问题只在Andoid上出现,因为iOS端使用APNS,所以推送都能及时送达。

在使用个推推送时,一旦用户把应用切换到后台,那么推送的时候就会显示 success_offline 也就是 cilentID离线

而实际上,应用这时候还没有被系统杀死,但是再也无法接受到推送的消息。哪怕重新点开APP,也不会接受到消息,不管是之前的消息,还是从此之后推送的消息。

【解决方案】

首先,保证APP后台的进程没有被杀死。个推官方给出了各个系统的设置 点击这里查看

强烈大家先去读一读 蜡笔小鑫的《推送使用中的各种坑》 @蜡笔小鑫

  • 简单版

    如果不要求后台还能接收实时推送,只是想在用户重新点开APP时能够接受到之前的消息,并且让用户能够继续接收推送。那么只需要在APP切换到前台的时候,重新初始化个推sdk。

    代码如下:

    /**  
    * resume 应用从后台切换到前台的事件  
    */  
    document.addEventListener("resume", function() {  
    var pushManager = plus.android.importClass("com.igexin.sdk.PushManager");  
    var context = plus.android.runtimeMainActivity();  
    pushManager.getInstance().initialize(context);  
    }, false);
  • 复杂版

    如果想要后台还能实时接收推送,那么只能进行离线打包,修改项目的 AndroidManifest.xml 文件。

    增加一行代码,如下:

    <!-- 整段位置在225行左右 -->  
    <activity  
           android:name="io.dcloud.PandoraEntryActivity"  
           android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"  
           android:hardwareAccelerated="true"  
           android:label="5+Debug"  
           android:launchMode="singleTask"  
           android:screenOrientation="user"  
           android:process=":pushservice" <!-- 这一行就是增加的代码 -->  
           android:theme="@style/DCloudTheme"  
           android:windowSoftInputMode="adjustResize" >  
       </activity>

【解决过程】

原本以为是以为个推的SDK版本问题。5+SDK集成的个推版本是2.7.0.0,而现在官方发布的版本是2.9.3.0。但是把个推官方的SDK下载编译之后,后台仍然不能接受消息。

我用的开发机是小米5,在“更多应用”中检查的时候,发现当应用后台化的时候,“运行中”的应用列表中会显出APP的名字,显示“1个进程和0个服务”。 然后大概五秒钟后,应用就会从“运行中”列表消失,出现在“已缓存”的列表中。

但是个推的SDK是有一个后台服务的,名字叫做 NoticationCenter, 用来管理推送消息。也就是说,我们的应用没有成功唤起 NoticationCenter 这个服务。

但是鄙人只是了解过安卓开发的一点点知识 (web全栈就已经够费精力了好嘛~ 老板加工资好嘛~) ,只能尝试使用 Native.js 拉起个推的 PushService ,然并卵,失败了。

拉起服务的代码是这样的 :

  var main = plus.android.runtimeMainActivity();  
  var Intent = plus.android.importClass('android.content.Intent');  
  var intent = new Intent();  
  var serviceName = 'com.igexin.sdk.PushService';//把这里换成其他Service的名字,也可以实现拉取自定义的Service  
  intent.setClassName(main, serviceName);  
  main.startService(intent);

注 : 把serviceName换成 'com.igexin.sdk.PushServiceForUser', 能够拉起一个NoticationCenterForUser服务,原本以为是和PushService一样的,结果发现这个服务对于推送啥一点用都没有……

然后又进行对比,发现个推的官方Demo里,在 AndroidManifest.xml 里,对于SDK的两个activity又些许的差别。

第一部分:

 <!-- 第三方应用配置 -->  
 <activity  
     android:name=".GetuiSdkDemoActivity"  
     android:label="@string/app_name"  
     android:launchMode="singleTop" >  
     <intent-filter>  
         <action android:name="android.intent.action.MAIN" />  

         <category android:name="android.intent.category.LAUNCHER" />  
     </intent-filter>  
 </activity>

第二部分

<activity  
     android:name="com.igexin.sdk.GActivity"  
     android:excludeFromRecents="true"  
     android:exported="true"  
     android:process=":pushservice"  <!--就是这里,process属性-->  
     android:taskAffinity="com.igexin.sdk.PushActivityTask"  
     android:theme="@android:style/Theme.Translucent.NoTitleBar"/>

这里的process属性的名字和核心推送服务一样

  <!-- 配置SDK核心服务 -->  
  <service  
      android:name="com.igexin.sdk.PushService"  
      android:exported="true"  
      android:label="NotificationCenter"  
      android:process=":pushservice"> <!-- 这里也有process属性 -->  
      <intent-filter>  
          <action android:name="com.igexin.sdk.action.service.message"/>  
      </intent-filter>  
  </service>

然后我google了一下,这个属性的作用是:

  android:process  

  应在其中运行 Activity 的进程的名称。正常情况下,应用的所有组件都在为应用创建的默认进程名称内运行,您无需使用该属性。 但在必要时,您可以使用该属性替换默认进程名称,以便让应用组件散布到多个进程中。  
  如果为该属性分配的名称以冒号(“:”)开头,则会在需要时创建应用专用的新进程,并且 Activity 会在该进程中运行。如果进程名称以小写字符开头,Activity 将在该名称的全局进程中运行,前提是它拥有相应的权限。这可以让不同应用中的组件共享一个进程,从而减少资源占用。  

  <application> 元素的 process 属性可为所有组件设置一个不同的默认进程名称。

点击这里可以查看官方文档

所以,进行猜测,就因为主activity没有跑在 pushservice 进程里,才导致后台推送服务不能成功启动。

给主activity添加了

android:process=":pushservice"

这个属性,发现 NoticationCenter 进程正常启动了。并且应用后台化之后,服务正常运行,也能正常收到推送信息。

问题解决,不过不是很了解安卓开发,不知道这样会有什么副作用。不过目前看来,内存消耗和网络连接都正常,还没观察到什么严重后果。

前前后后花费了两个通宵和一个白天的时间,程序猿没人权啊~

14 关注 分享
wenju gaus l***@sina.com lubg lianxia wen如故i 4***@qq.com skysowe 4***@qq.com 闭目狂奔 漠 太烏 老火 gadget2k

要回复文章请先登录注册

河南dev

河南dev

在线帮解决安卓平台,华为小米手机在线和离线推送各种问题,只需帮我头条点点赞,评论,就能获得我的从零到一的完美解决,欢迎加q 476988188
2020-06-03 15:33
8***@qq.com

8***@qq.com

回复 4***@qq.com :
https://blog.csdn.net/qq_39702364/article/details/80324662,不知道你是否还需要,你可以看下这条链接是否能帮助到你
2019-06-12 11:00
4***@qq.com

4***@qq.com

回复 8***@qq.com :
哥们,过了一年了,webapp实现了么?
2019-05-07 17:29
3***@qq.com

3***@qq.com

这个文章发自2016年 然而现在2018年了 官方还是没解决这个问题 。。。。。。
2018-12-10 08:15
8***@qq.com

8***@qq.com

悲剧,webapp有人知道怎么实现吗?
2018-05-08 09:48
edobnet

edobnet

支持云打包,离线太麻烦了,
2017-12-29 18:45
5***@qq.com

5***@qq.com

楼主尝试过离线状态下如何实现推送吗?
2017-11-28 17:01
h***@163.com

h***@163.com

mark
2017-11-23 14:02
4***@qq.com

4***@qq.com

完美解决
2017-09-01 14:28
个推

个推

博主文章里说的sdk版本过老了,个推目前使用的是2.10.2.0版本的sdk,新版本处理了文中提到的问题,建议尝试接入测试看看
2017-06-27 16:40