firebase正确接收到Token,需要安装谷歌三件套:
- Google Play Store
- Google Play services
- Google Services Framework
推荐使用APP higoplay服务框架安装器一键安装。
小米
MIUI12.5
安装谷歌三件套后,打开Play商店会闪退,误解,MIUI系统的限制。
点击通知栏激活游戏闪退
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
log("ok")
并没有发生崩溃,说明游戏裸包是没有任何问题
lua框架
尝试仅加载游戏框架,屏幕没有任何渲染,发现也没有崩溃和异常,说明lua framework也没有问题
log("hello game lua") require "config" require "cocos.init" log("ok")
渲染Sprite时也发生了崩溃
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时,发生了崩溃
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的消息,如下:
// 在处理Firebase通知栏消息时,创建Intent对象 Intent intent = new Intent(this, YourActivity.class); // YourActivity是您要启动的Activity intent.putExtra("fromNotification", true); // 添加一个标志,表示是Firebase通知栏消息启动的 // 启动Activity startActivity(intent);
在AppActivity里面
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); boolean fromNotification = getIntent().getBooleanExtra("fromNotification", false); if (fromNotification) { // 这是从Firebase通知栏消息打开的应用程序 // 在这里处理相应的逻辑 } else { // 这不是从Firebase通知栏消息打开的应用程序 // 在这里执行其他代码 } }
但是感觉这样有点麻烦,继续排查,我们可以尝试着将intent的透传参数打印出来
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传递过来的参数有:
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,也会报错
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,最后也稳定复现了:
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标志的代码:
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
<activity android:name=".YourActivity" android:launchMode="singleInstance"> </activity>
- SingleTask 启动模式:当启动一个拥有 singleTask 启动模式的 Activity 时,系统会检查是否已经存在具有相同任务栈的实例。如果存在,则该实例将被调出前台并接收新的 Intent,而不会创建新的实例。如果不存在具有相同任务栈的实例,则会创建新的实例并将其置于新的任务栈中。
- SingleInstance 启动模式:这是一种特殊的 singleTask 模式,它会为目标 Activity 创建一个单独的任务栈,并且该任务栈只包含该 Activity 的实例。当启动一个拥有 singleInstance 启动模式的 Activity 时,系统会为其创建一个新的任务栈,并将该 Activity 放置在新的任务栈中。无论后续的 Intent 如何,都不会在同一个任务栈中创建其他 Activity 的实例。
后续问题追踪
如果sdk有操作game activity,singleInstance会导致cocos渲染异常,后来改为singleTask就正常了