cocos2dx接入firebase后,点击消息通知栏闪退渲染异常

firebase正确接收到Token,需要安装谷歌三件套:

  • Google Play Store
  • Google Play services
  • Google Services Framework

推荐使用APP higoplay服务框架安装器一键安装。

小米MIUI12.5安装谷歌三件套后,打开Play商店会闪退,误解,MIUI系统的限制。

点击通知栏激活游戏闪退

less 复制代码
ActivityManager         system_process                       I  START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x14000000 pkg=com.yddm.haiwai.game cmp=com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity (has extras)} from uid 10055
zch                     com.yddm.haiwai.game                 D  MainActivity onDestroy
HostConnection          com.yddm.haiwai.game                 I  HostConnection::~HostConnection, pid=22091, tid=22157, this=0x7fff593f58c0, m_stream=0x7fff59dad240
<no-tag>                com.yddm.haiwai.game                 I  fastpipe: close connect
JniHelper               com.yddm.haiwai.game                 D  JniHelper::getJavaVM(), pthread_self() = 140734540272880
com.yddm.haiwai.game    com.yddm.haiwai.game                 I  type=1400 audit(0.0:3876): avc: denied { ioctl } for comm=474C54687265616420343535 path="/dev/fastpipe" dev="tmpfs" ino=5173 ioctlcmd=6869 scontext=u:r:untrusted_app:s0:c55,c256,c512,c768 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
WindowManager           com.yddm.haiwai.game                 E  
																android.view.WindowLeaked: Activity org.cocos2dx.lua.AppActivity has leaked window com.chsdk.moduel.floatball.view.FloatBallLayout{fe3196 V.E...... .......D 0,0-68,68} that was originally added here
																	at android.view.ViewRootImpl.<init>(ViewRootImpl.java:511)
																	at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:346)
																	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
																	at com.chsdk.moduel.floatball.control.FloatBall.addView(FloatBall.java:78)
																	at com.chsdk.moduel.floatball.control.FloatBall.show(FloatBall.java:40)
																	at com.chsdk.moduel.floatball.control.FloatBallHelper.show(FloatBallHelper.java:54)
																	at com.chsdk.internal.SdkLifeCycle.onLoginSuccess(SdkLifeCycle.java:260)
																	at com.chsdk.moduel.login.BaseLoginDialog.callbackSuccess(BaseLoginDialog.java:26)
																	at com.chsdk.moduel.login.AutoLoginDialog.loginSuccess(AutoLoginDialog.java:110)
																	at com.chsdk.moduel.login.request.BaseLoginRequest.onLoginSuccess(BaseLoginRequest.java:108)
																	at com.chsdk.moduel.login.request.BaseLoginRequest.handleLoginResult(BaseLoginRequest.java:95)
																	at com.chsdk.moduel.login.request.BaseLoginRequest.success(BaseLoginRequest.java:74)
																	at com.chsdk.moduel.login.request.BaseLoginRequest.success(BaseLoginRequest.java:23)
																	at com.chsdk.http.okhttp.BaseCallBack$1.run(BaseCallBack.java:81)
																	at android.os.Handler.handleCallback(Handler.java:873)
																	at android.os.Handler.dispatchMessage(Handler.java:99)
																	at android.os.Looper.loop(Looper.java:193)
																	at android.app.ActivityThread.main(ActivityThread.java:6825)
																	at java.lang.reflect.Method.invoke(Native Method)
																	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
																	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:860)
ActivityThread          com.yddm.haiwai.game                 W  handleWindowVisibility: no activity for token android.os.BinderProxy@2dea904
FA                      com.yddm.haiwai.game                 V  onActivityCreated
Cocos2dxActivity        com.yddm.haiwai.game                 D  model=V1824A
Cocos2dxActivity        com.yddm.haiwai.game                 D  product=V1824A
Cocos2dxActivity        com.yddm.haiwai.game                 D  isEmulator=false
EngineDataManager.cpp   com.yddm.haiwai.game                 D  nativeSetSupportOptimization: 0
FA                      com.yddm.haiwai.game                 V  Connecting to remote service
zch                     com.yddm.haiwai.game                 D  getAppID==========10100
zch                     com.yddm.haiwai.game                 D  MainActivity onStart
Cocos2dxActivity        com.yddm.haiwai.game                 D  onResume()
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  onBecameForeground
AppsFlyer_6.3.2         com.yddm.haiwai.game                 D  No deep link detected
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  Last Launch attempt: 2023/09/12 03:39:41.375 +0000;
																								Last successful Launch event: 2023/09/12 03:39:42.804 +0000;
																								Sending launch (+40573 ms)
FA                      com.yddm.haiwai.game                 V  Activity resumed, time: 6636560
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  sendWithEvent from activity: com.cqrmw.mwsdk.CHApplication
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  Trying to fetch GAID..
zch                     com.yddm.haiwai.game                 D  MainActivity onResume
CH_SDK                  com.yddm.haiwai.game                 D  CHSdk`onResume
CH_SDK                  com.yddm.haiwai.game                 D  *SdkLifeCycle`onResumeAction`com.chsdk.moduel.pay.PayManager$1
CH_SDK                  com.yddm.haiwai.game                 D  *PayPlatform`onResume
CH_SDK                  com.yddm.haiwai.game                 D  *GooglePlayExcutor`checkPurchaseConsumeState
CH_SDK                  com.yddm.haiwai.game                 D  *ShareManager`onResume
Finsky                  com.android.vending                  I  [392] knt.a(19): com.yddm.haiwai.game: Account from first account - [wVfsS5U8pcd2pVq_EIG48CenXLX7kwuHbTaGcBOATyc]
Finsky                  com.android.vending                  I  [392] knt.a(67): Billing preferred account via installer for com.yddm.haiwai.game: [wVfsS5U8pcd2pVq_EIG48CenXLX7kwuHbTaGcBOATyc]
CH_SDK                  com.yddm.haiwai.game                 D  *GooglePlayExcutor`onQueryPurchasesResponse`Response Code: OK, Debug Message: `0
CH_SDK                  com.yddm.haiwai.game                 D  *GooglePlayExcutor`checkPurchaseConsume no need
FA                      com.yddm.haiwai.game                 V  Connection attempt already in progress
FA                      com.yddm.haiwai.game                 V  Connection attempt already in progress
EGL_adreno              com.yddm.haiwai.game                 E  tid 22159: eglSurfaceAttrib(1338): error 0x3009 (EGL_BAD_MATCH)
OpenGLRenderer          com.yddm.haiwai.game                 W  Failed to set EGL_SWAP_BEHAVIOR on surface 0x7fff595ee380, error=EGL_BAD_MATCH
HostConnection          com.yddm.haiwai.game                 I  HostConnection::HostConnection: pid=22091, tid=22295, this=0x7fff5969f260
<no-tag>                com.yddm.haiwai.game                 I  fastpipe: Connect success
HostConnection          com.yddm.haiwai.game                 D  HostRPC::connect sucess: app=com.yddm.haiwai.game, pid=22091, tid=22295, this=0x7fff481efe40
HostConnection          com.yddm.haiwai.game                 D  queryAndSetGLESMaxVersion select gles-version: 3.1 hostGLVersion:46 process:com.yddm.haiwai.game
EGL_adreno              com.yddm.haiwai.game                 I  eglCreateContext request GLES major-version=2
EGL_adreno              com.yddm.haiwai.game                 D  eglCreateContext: 0x7fff5969d100: maj 3 min 1 rcv 4
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  ******* sendTrackingWithEvent: Launch
AppsFlyer_6.3.2         com.yddm.haiwai.game                 W  Exception while collecting facebook's attribution ID. 
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  IMEI was not collected.
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  Android ID was not collected.
EGL_adreno              com.yddm.haiwai.game                 D  eglMakeCurrent: 0x7fff68837a20: ver 3 1 (tinfo 0x7fff59c544c0)
AppsFlyerOaid6.2.4      com.yddm.haiwai.game                 I  Fetch 2 ms
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  AppsFlyer: first launch date: 2023-09-11_115844+0000
AppsFlyer_6.3.2         com.yddm.haiwai.game                 D  didConfigureTokenRefreshService=false
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  AppsFlyerLib.sendWithEvent
EGL_adreno              com.yddm.haiwai.game                 D  eglMakeCurrent: 0x7fff5969d100: ver 3 1 (tinfo 0x7fff727fdbe0)
FA                      com.yddm.haiwai.game                 D  Connected to remote service
FA                      com.yddm.haiwai.game                 V  Processing queued up service tasks: 3
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  url: https://launches.appsflyer.com/api/v6.3/androidevent?app_id=com.yddm.haiwai.game&buildnumber=6.3.2
cocos2d-x debug info    com.yddm.haiwai.game                 D  reload all texture
NotificationEntryMgr    com.android.systemui                 W  removeNotification for unknown key: 0|com.yddm.haiwai.game|0|FCM-Notification:6624366|10055
SurfaceFlinger          surfaceflinger                       W  Attempting to set client state on removed layer: Surface(name=AppWindowToken{e5dfebb token=Token{f85cf4a ActivityRecord{a055cb5 u0 com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity t31}}})/@0x816baaa - animation-leash#0
SurfaceFlinger          surfaceflinger                       W  Attempting to destroy on removed layer: Surface(name=AppWindowToken{e5dfebb token=Token{f85cf4a ActivityRecord{a055cb5 u0 com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity t31}}})/@0x816baaa - animation-leash#0
Cocos2dxActivity        com.yddm.haiwai.game                 D  onWindowFocusChanged() hasFocus=true
cocos2d-x debug info    com.yddm.haiwai.game                 D  Dirty Uniform and Attributes of GLProgramState
chatty                  com.yddm.haiwai.game                 I  uid=10055(com.yddm.haiwai.game) GLThread 498 identical 5 lines
cocos2d-x debug info    com.yddm.haiwai.game                 D  Dirty Uniform and Attributes of GLProgramState
AppsFlyer_6.3.2         com.yddm.haiwai.game                 I  response code: 200
AppsFlyer_6.3.2         com.yddm.haiwai.game                 D  [GCD-A01] Loading conversion data. Counter: 40
AppsFlyer_6.3.2         com.yddm.haiwai.game                 D  [GCD-A02] Calling onConversionDataSuccess with:
																								{install_time=2023-09-11 11:58:44.223, af_status=Organic, af_message=organic install, is_first_launch=false}
CH_SDK                  com.yddm.haiwai.game                 D  *AppsFlyer`onConversionDataSuccess`{install_time=2023-09-11 11:58:44.223, af_status=Organic, af_message=organic install, is_first_launch=false}
cocos2d-x debug info    com.yddm.haiwai.game                 D  Dirty Uniform and Attributes of GLProgramState
HostConnection          com.yddm.haiwai.game                 D  glGetError exceeded.
eglCodecCommon          com.yddm.haiwai.game                 E  removeVertexArrayObject: ERROR: cannot delete VAO 0!
chatty                  com.yddm.haiwai.game                 I  uid=10055(com.yddm.haiwai.game) GLThread 498 identical 2 lines
eglCodecCommon          com.yddm.haiwai.game                 E  removeVertexArrayObject: ERROR: cannot delete VAO 0!
system_server           system_process                       W  Failed to determine oat file name for dex location /data/app/com.yddm.haiwai.game-ZKTqcH16Y0TqYn-Fr7JM9w==/base.apk: Dalvik cache directory does not exist
ActivityManager         system_process                       I  Displayed com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity: +1s25ms
EngineDataManager.cpp   com.yddm.haiwai.game                 D  setAnimationInterval by engine: 0.0333
EngineDataManager.cpp   com.yddm.haiwai.game                 D  JNI setAnimationInterval: 0.033333
cocos2d-x debug info    com.yddm.haiwai.game                 D  [LUA-print] onEnterForeground
cocos2d-x debug info    com.yddm.haiwai.game                 D  [LUA-print] 发现新版本
cocos2d-x debug info    com.yddm.haiwai.game                 D  [LUA-print] ---new version found--> old:2.0.0.28, new:1.0.0.30
cocos2d-x debug info    com.yddm.haiwai.game                 D  [LUA-print] 本地版本高,不需要更新
GLESv2_enc              com.yddm.haiwai.game                 E  device/leidian/ldopengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBindVertexArray:4499 GL error 0x502
SurfaceFlinger          surfaceflinger                       W  Attempting to set client state on removed layer: Splash Screen com.yddm.haiwai.game#0
SurfaceFlinger          surfaceflinger                       W  Attempting to destroy on removed layer: Splash Screen com.yddm.haiwai.game#0
libc                    com.yddm.haiwai.game                 A  Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 22295 (GLThread 498), pid 22091 (ddm.haiwai.game)
ActivityManager         system_process                       W    Force finishing activity com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity
InputDispatcher         system_process                       W  channel 'ba35995 com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
---------------------------- PROCESS ENDED (22091) for package com.yddm.haiwai.game ----------------------------
InputDispatcher         system_process                       E  channel 'ba35995 com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
ActivityManager         system_process                       I  Process com.yddm.haiwai.game (pid 22091) has died: vis  +99TOP 
WindowManager           system_process                       I  WIN DEATH: Window{ba35995 u0 com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity}
InputDispatcher         system_process                       W  Attempted to unregister already unregistered input channel 'ba35995 com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity (server)'
SurfaceFlinger          surfaceflinger                       W  Attempting to set client state on removed layer: com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity#0
SurfaceFlinger          surfaceflinger                       W  Attempting to destroy on removed layer: com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity#0
SurfaceFlinger          surfaceflinger                       W  Attempting to destroy on removed layer: AppWindowToken{e5dfebb token=Token{f85cf4a ActivityRecord{a055cb5 u0 com.yddm.haiwai.game/org.cocos2dx.lua.AppActivity t31}}}#0
CoreService             com.android.coreservice              I  notifyClosing notify tab closed taskPackageName:com.yddm.haiwai.game

先写一个通知栏,发现自己写的通知栏没有任何问题,都能正常唤起APP

C++裸包正常

将游戏的脚本代码换成了只有一个文件的main.lua

arduino 复制代码
log("ok")

并没有发生崩溃,说明游戏裸包是没有任何问题

lua框架

尝试仅加载游戏框架,屏幕没有任何渲染,发现也没有崩溃和异常,说明lua framework也没有问题

lua 复制代码
log("hello game lua")
require "config"
require "cocos.init"
log("ok")

渲染Sprite时也发生了崩溃

css 复制代码
require "config"
require "cocos.init"
local scene = cc.Scene:create()
local director = cc.Director:getInstance()
director:runWithScene(scene)

local root = cc.Node:create()
root:setName("root")
scene:addChild(root)

local size = cc.Director:getInstance():getWinSize()

local spr = cc.Sprite:create("res/1.png");
spr:setPosition(cc.p(size.width / 2, size.height / 2))
root:addChild(spr)

渲染label时,发生了崩溃

lua 复制代码
require "config"
require "cocos.init"
local scene = cc.Scene:create()
local director = cc.Director:getInstance()
director:runWithScene(scene)

local root = cc.Node:create()
root:setName("root")
scene:addChild(root)

local size = cc.Director:getInstance():getWinSize()
local label = cc.Label:create();
label:setSystemFontSize(150)
label:setString("ABC")
label:setPosition(cc.p(size.width / 2, size.height / 2))
root:addChild(label)

问题定位到了,是AppActivity的Create执行了2次导致的,当App在后台时,如果点击通知栏唤起APP,会重新执行AppActivity的OnCreate()

能想到的就是自己处理firebase的消息,如下:

java 复制代码
// 在处理Firebase通知栏消息时,创建Intent对象
Intent intent = new Intent(this, YourActivity.class); // YourActivity是您要启动的Activity
intent.putExtra("fromNotification", true); // 添加一个标志,表示是Firebase通知栏消息启动的

// 启动Activity
startActivity(intent);

在AppActivity里面

java 复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    boolean fromNotification = getIntent().getBooleanExtra("fromNotification", false);
    if (fromNotification) {
        // 这是从Firebase通知栏消息打开的应用程序
        // 在这里处理相应的逻辑
    } else {
        // 这不是从Firebase通知栏消息打开的应用程序
        // 在这里执行其他代码
    }
}

但是感觉这样有点麻烦,继续排查,我们可以尝试着将intent的透传参数打印出来

java 复制代码
Intent intent = getIntent();
if (intent!=null){
    Bundle extra = intent.getExtras();
    if (extra != null){
        for(String key: extra.keySet()){
            Object value= extra.get(key);
            Log.d("intent extra","key:"+key+", value:"+value.toString());
        }
    }
}

firebase传递过来的参数有:

less 复制代码
key:google.delivered_priority, value:normal
key:google.sent_time,          value:1694586997451
key:google.ttl,                value:300
key:google.original_priority,  value:normal
key:from,                      value:185043606008
key:google.message_id,         value:0:1694586997458180%bab4c2e4bab4c2e4
key:gcm.n.analytics_data,      value:Bundle[mParcelledData.dataSize=100]
key:collapse_key,              value:com.yddm.haiwai.game

所以我们可以考虑给AppActivity里面加上intent拦截,发现仍旧报错,猜测可能是因为父类重复初始化导致的,后来尝试在Cocos2dActivity的onCreate里面拦截intent,也会报错

java 复制代码
private void resumeIfHasFocus() {
    if(hasFocus) {
        this.hideVirtualButton();
       Cocos2dxHelper.onResume();
       mGLSurfaceView.onResume();// null
    }
}
//java.lang.NullPointerException: Attempt to invoke virtual method 'void org.cocos2dx.lib.Cocos2dxGLSurfaceView.onResume()' on a null object reference

可能是Intent的Flag导致的

  • 正常启动的flag: 268435456 FLAG_ACTIVITY_NEW_TASK
  • firebase过来的: 339738624 FLAG_ACTIVITY_BROUGHT_TO_FRONT

正常情况下,Cocos2dActivity.mGLSurfaceView是不能发现变化的。

当出现问题时,发现Cocos2dActivity.mGLSurfaceView实例发生了变化,why?

FLAG_ACTIVITY_BROUGHT_TO_FRONT

Android 中的一个标志(flag),用于控制活动(Activity)在启动时的行为。该标志用于指示要启动的活动是否应该移动到前台,而不是创建新的实例。

具体来说,当使用 startActivity() 方法启动一个活动时,可以使用 FLAG_ACTIVITY_BROUGHT_TO_FRONT 标志来修改启动行为。如果目标活动已经存在于任务堆栈中,设置了该标志的启动将会将该活动移动到前台,而不是创建新的活动实例。如果目标活动不存在,则会创建新的活动实例。

很明显目标活动不存在,重新创建了,接入firebase后,app在后台,为啥FLAG_ACTIVITY_BROUGHT_TO_FRONT会导致重新创建一个Activity呢?

后来发现这个FLAG_ACTIVITY_BROUGHT_TO_FRONT问题不大,我自己的也这么设置没有问题,尝试修改了下我的nofity,最后也稳定复现了:

ini 复制代码
Intent intent = new Intent(context, AppActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER); // 加上这个就不会重复穿件Activity

打印flag标志的代码:

java 复制代码
private void checkFlag(int flags){
    for (int i = 0; i < 32; i++) {
        int flag = 1 << i;

        if ((flags & flag) != 0) {
            printIntentFlag(flag);
        }
    }
}

public static void printIntentFlag(int flag) {
    String bin = Integer.toBinaryString(flag);
    Map<Integer,String> sysFlags=new HashMap<>();
    sysFlags.put(Intent.FLAG_ACTIVITY_NEW_TASK,"FLAG_ACTIVITY_NEW_TASK");
    sysFlags.put(Intent.FLAG_ACTIVITY_CLEAR_TOP,"FLAG_ACTIVITY_CLEAR_TOP");
    sysFlags.put(Intent.FLAG_ACTIVITY_SINGLE_TOP,"FLAG_ACTIVITY_SINGLE_TOP");
    sysFlags.put(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT,"FLAG_ACTIVITY_BROUGHT_TO_FRONT");
    sysFlags.put(Intent.FLAG_RECEIVER_REGISTERED_ONLY,"FLAG_RECEIVER_REGISTERED_ONLY");

    String name= sysFlags.get(flag);
    if(name!=null){
        Log.d("intent flag", name);
    }
}

解决办法

firebase生成的通知栏消息,点击时会根据一定条件重新创建一个Activity,内部实现机制不太了解,但是要修复这个问题只需要它不重复创建Activity即可。

无意中,ChatGPT给出了一个答案,可以修改启动模式,这么做也有弊端,就是无法再收到intent透传的参数,所以终极解决方案还是得自己处理firebase的message

xml 复制代码
<activity android:name=".YourActivity"
          android:launchMode="singleInstance">
</activity>
  • SingleTask 启动模式:当启动一个拥有 singleTask 启动模式的 Activity 时,系统会检查是否已经存在具有相同任务栈的实例。如果存在,则该实例将被调出前台并接收新的 Intent,而不会创建新的实例。如果不存在具有相同任务栈的实例,则会创建新的实例并将其置于新的任务栈中。
  • SingleInstance 启动模式:这是一种特殊的 singleTask 模式,它会为目标 Activity 创建一个单独的任务栈,并且该任务栈只包含该 Activity 的实例。当启动一个拥有 singleInstance 启动模式的 Activity 时,系统会为其创建一个新的任务栈,并将该 Activity 放置在新的任务栈中。无论后续的 Intent 如何,都不会在同一个任务栈中创建其他 Activity 的实例。
相关推荐
轻口味1 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王1 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发2 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀2 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef4 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6414 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻5 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云5 小时前
npm淘宝镜像
前端·npm·node.js