美文网首页
unity黑屏现状问题总结

unity黑屏现状问题总结

作者: weiinter105 | 来源:发表于2019-05-28 21:40 被阅读0次

    总结下unity的游戏接sdk时的黑屏问题现状

    现象:

    目前黑屏有两种情况:

    1. 点击登录面板,从面板中点击跳到三方界面或者跳到第三个界面;再点击返回键时会出现下面的游戏界面黑屏;

    2. 点击登录面板之后,按桌面键返回桌面;然后再从最近任务键进入会发现下面的游戏界面黑屏;

    原因:

    以第一种情况为例,一般情况下出现:

    05-28 10:27:04.642  1000  2154  3441 I am_create_activity: [0,41511060,4450,com.ss.android.ugc.aweme/.openauthorize.AwemeAuthorizedActivity,NULL,NULL,NULL,872448000]`
    
    05-28 10:27:04.642  1000  2154  3441 I wm_task_moved: [4450,0,2147483647]`
    
    05-28 10:27:04.649  1000  2154  3441 I am_pause_activity: [25025,39231624,com.hermes.fgame/com.bytedance.ttgame.sdk.module.account.login.ui.LoginActivity,userLeaving=true]`
    
    05-28 10:27:04.654 10454 25025 25025 I am_on_paused_called: [0,com.bytedance.ttgame.sdk.module.account.login.ui.LoginActivity,performPause]`
    
    05-28 10:27:04.663  1000  2154  3329 I am_proc_bound: [0,25874,com.ss.android.ugc.aweme:push]`
    
    05-28 10:27:04.715  1000  2154  3441 I configuration_changed: 536872064`
    
    05-28 10:27:04.778  1000  2154  2194 I am_stop_activity: [0,214407528,com.hermes.fgame/.SDKBridgeActivity]`
    
    05-28 10:27:04.793  1000  2154  2194 I sysui_count: [window_time_0,7]`
    
    `05-28 10:27:04.793  1000  2154  2194 I sysui_multi_action: [757,803,799,window_time_0,802,7]`
    
    05-28 10:27:04.804 10454 25025 25025 I am_on_stop_called: [0,com.hermes.fgame.SDKBridgeActivity,STOP_ACTIVITY_ITEM]`
    
    05-28 10:27:05.975 10421 25905 25905 I am_on_resume_called: [0,com.ss.android.ugc.aweme.openauthorize.AwemeAuthorizedActivity,RESUME_ACTIVITY]`
    

    黑屏的原因是游戏界面调用了onstop,则会出现黑屏;直到其重新调用onResume才能重新可见;

    想法:

    1. 在stop的时候调用onResume

    2. 想办法起到三方授权界面的时候不调用onstop

    3. 想办法只生成一个界面

    方案1已经被游戏否决了,其实也能理解;改变Activity的生命周期总是要承担很大的风险的,那么方案2和方案3

    方案2:如何使调起三方授权界面时不再调用unity游戏界面的onstop

    
    `1554    private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {`
    
    `1555        ActivityRecord prev = mPausingActivity;`
    
    `1556        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);`
    
    `1557`
    
    `1558        if (prev != null) {`
    
    `1559            prev.setWillCloseOrEnterPip(false);`
    
    `1560            final boolean wasStopping = prev.isState(STOPPING);`
    
    `1561            prev.setState(PAUSED, "completePausedLocked");`
    
    `1562            if (prev.finishing) {`
    
    `1563                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);`
    
    `1564                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,`
    
    `1565                        "completedPausedLocked");`
    
    `1566            } else if (prev.app != null) {`
    
    `1567                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev`
    
    `1568                        + " wasStopping=" + wasStopping + " visible=" + prev.visible);`
    
    `1569                if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {`
    
    `1570                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,`
    
    `1571                            "Complete pause, no longer waiting: " + prev);`
    
    `1572                }`
    
    `1573                if (prev.deferRelaunchUntilPaused) {`
    
    `1574                    // Complete the deferred relaunch that was waiting for pause to complete.`
    
    `1575                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);`
    
    `1576                    prev.relaunchActivityLocked(false /* andResume */,`
    
    `1577                            prev.preserveWindowOnDeferredRelaunch);`
    
    `1578                } else if (wasStopping) {`
    
    `1579                    // We are also stopping, the stop request must have gone soon after the pause.`
    
    `1580                    // We can't clobber it, because the stop confirmation will not be handled.`
    
    `1581                    // We don't need to schedule another stop, we only need to let it happen.`
    
    `1582                    prev.setState(STOPPING, "completePausedLocked");`
    
    `1583                } else if (!prev.visible || shouldSleepOrShutDownActivities()) {`
    
    `1584                    // Clear out any deferred client hide we might currently have.`
    
    `1585                    prev.setDeferHidingClient(false);`
    
    `1586                    // If we were visible then resumeTopActivities will release resources before`
    
    `1587                    // stopping.`
    
    `1588                    addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);`
    
    `1589                }`
    
    `1590            } else {`
    
    `1591                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);`
    
    `1592                prev = null;`
    
    `1593            }`
    
    `1594            // It is possible the activity was freezing the screen before it was paused.`
    
    `1595            // In that case go ahead and remove the freeze this activity has on the screen`
    
    `1596            // since it is no longer visible.`
    
    `1597            if (prev != null) {`
    
    `1598                prev.stopFreezingScreenLocked(true /*force*/);`
    
    `1599            }`
    
    `1600            mPausingActivity = null;`
    
    `1601        }`
    
    `1602`
    
    `1603        if (resumeNext) {`
    
    `1604            final ActivityStack topStack = mStackSupervisor.getFocusedStack();`
    
    `1605            if (!topStack.shouldSleepOrShutDownActivities()) {`
    
    `1606                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);`
    
    `1607            } else {`
    
    `1608                checkReadyForSleep();`
    
    `1609                ActivityRecord top = topStack.topRunningActivityLocked();`
    
    `1610                if (top == null || (prev != null && top != prev)) {`
    
    `1611                    // If there are no more activities available to run, do resume anyway to start`
    
    `1612                    // something. Also if the top activity on the stack is not the just paused`
    
    `1613                    // activity, we need to go ahead and resume it to ensure we complete an`
    
    `1614                    // in-flight app switch.`
    
    `1615                    mStackSupervisor.resumeFocusedStackTopActivityLocked();`
    
    `1616                }`
    
    `1617            }`
    
    `1618        }`
    
    `1619`
    
    `1620        if (prev != null) {`
    
    `1621            prev.resumeKeyDispatchingLocked();`
    
    `1622`
    
    `1623            if (prev.app != null && prev.cpuTimeAtResume > 0`
    
    `1624                    && mService.mBatteryStatsService.isOnBattery()) {`
    
    `1625                long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)`
    
    `1626                        - prev.cpuTimeAtResume;`
    
    `1627                if (diff > 0) {`
    
    `1628                    BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();`
    
    `1629                    synchronized (bsi) {`
    
    `1630                        BatteryStatsImpl.Uid.Proc ps =`
    
    `1631                                bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,`
    
    `1632                                        prev.info.packageName);`
    
    `1633                        if (ps != null) {`
    
    `1634                            ps.addForegroundTimeLocked(diff);`
    
    `1635                        }`
    
    `1636                    }`
    
    `1637                }`
    
    `1638            }`
    
    `1639            prev.cpuTimeAtResume = 0; // reset it`
    
    `1640        }`
    
    `1641`
    
    `1642        // Notify when the task stack has changed, but only if visibilities changed (not just`
    
    `1643        // focus). Also if there is an active pinned stack - we always want to notify it about`
    
    `1644        // task stack changes, because its positioning may depend on it.`
    
    `1645        if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause`
    
    `1646                || getDisplay().hasPinnedStack()) {`
    
    `1647            mService.mTaskChangeNotificationController.notifyTaskStackChanged();`
    
    `1648            mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;`
    
    `1649        }`
    
    `1650`
    
    `1651        mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);`
    
    `1652    }`
    

    想要不被stop那么不能被调用到addToStopping;这就有两种可能

    1. 使unity activity调用relaunch的逻辑

    prev.relaunchActivityLocked(false /* andResume */, prev.preserveWindowOnDeferredRelaunch);

    2. 使unity Activity的visable属性为true

    结论

    1. 经调研不太好实现,因为unity实现了对所有config change的监听以便于属性变化时及时变化游戏界面

    2. 需要三方配合;将三方授权界面Activity的fullscreen属性置为false;如写成Dialog style的形式

    经试验,方案2对情况1可行;缺点: 1. 需要授权sdk方的配合 2.对情况2还是没办法解决;

    方案3; 将游戏activity和登陆面板合并,将登陆面板以Dialog形式显示,依附于游戏unity activity,此时两种情况应该都能解决; 缺点:改动太大;对于sdk限制也太大

    业内方案:

    想了下,想要根治这个问题可能只能讲登陆面板置位dialog形式;但是这种方式局限太大了,业界的sdk不可能都是以style形式实现的吧?至少我接的uc渠道就有这个问题;

    因此用unity demo继承下uc的sdk,发现情况1和情况2都能复现

    bilibili黑屏情况1.jpg uc黑屏情况2.jpg

    因此这个问题确实也是正常的,属于AMS管理Activity的生命周期的正常逻辑

    结论:

    1. 如果要有两个Activity;那么点击登录面板之后,按桌面键返回桌面;然后再从最近任务键进入游戏界面黑屏;

    2. 如果有三个activity,且第三个activity为全屏的,那么返回时如果登陆面板不自动取消,那么就会出现unity activity的黑屏;同时,个人认为三方授权界面不要写成fullscreen格式的比较好

    相关文章

      网友评论

          本文标题:unity黑屏现状问题总结

          本文链接:https://www.haomeiwen.com/subject/jsgjtctx.html