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 的实例。