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

个推 解决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

要回复文章请先登录注册

上上

上上

回复 上上 :
关闭应用后还是不行,这个有方案吗
2022-11-14 19:27
上上

上上

解决了挂在后台锁屏还能收到推送。关闭应用
2022-11-14 19:27
simiii

simiii

回复 有问 :
如今都2022了,这个问题还是在帮助大家有通宵熬。
2022-05-26 16:13
有问

有问

回复 赵明 :
一样的。就是不稳定吧。有时候突然又来消息了。也许真的就是和厂商白名单有关,没有办法解决。
2021-10-11 13:59
赵明

赵明

回复 有问 :
unipush 我是长时间以后,就算大开APP也收不到透传消息,不知道怎么回事!除非把APP杀掉,然后重新启动,才可以接到透传消息
2021-09-02 17:12
有问

有问

回复 赵明 :
没什么用,估计得和厂商沟通一下,加入白手机系统的白名单,不然就算设置了什么自启动,锁定后台也是没用的。经常会收不到,然后突然又能收到。不知道什么情况。但多数情况是时间久了,需要打开APP后才能收到。
2021-09-02 12:52
赵明

赵明

回复 有问 :
搞定了吗?我这边也是长时间就收不到透传消息了,我打开APP也接受不到透传消息,连通知都死了!反正在后台运行一段时间后(大概10分钟),推送彻底没用了
2021-09-01 11:33
有问

有问

如今2021年了,官方好像还是没有解决这个问题。。。。。。哪怕我锁定APP,不让它自动结束运行,时间一长点还是不能收到消息,打开APP才会弹出来,我发的是透传消息,按理说APP在后台不用打开也能收到,公司说要做聊天功能,消息都收不及时,难搞。
2021-08-12 11:13
1***@qq.com

1***@qq.com

回复 3***@qq.com :
如今2020年了,官方好像还没有解决问题。。。。。。个推都升级为UNIPus和了
2020-08-05 11:41
1***@qq.com

1***@qq.com

解决了吗?解决了告诉我一声
2020-08-04 17:07