Skip to content
isdnetworks
Go back

처음 켜자마자 전부 한꺼번에 일어났다

Cocos2d-x 로 만든 앱을 처음 켜면 몇 초 멈췄다. 어떤 Android 기기에서는 아예 죽었다.

Table of contents

Open Table of contents

시작 자리에 다 붙어 있었다

AppDelegate 의 시작 함수에 여섯 가지가 붙어 있었다. UserDefault.xml 을 읽는다. 텍스처를 전부 올린다. 소리도 전부 올린다. 그리고 서버에 두 번 붙는다.

이게 다 메인 스레드다. Android 는 입력에 5 초 넘게 응답이 없으면 ANR 로 죽인다.

GameData::getInstance()->load();
ResourceLoader::loadAll();
SoundManager::getInstance()->preload();
NetworkClient::checkVersion();
NetworkClient::sendInstallLog();

첫 실행에서는 UserDefault.xml 이 없어서 만든다. 텍스처도 CCTextureCache 에 없어서 전부 읽는다. 두 번째부터 빠른 것이 이 때문이고, 그래서 개발 중에는 이 상태를 잘 안 만난다.

각 줄의 시간을 쟀다

무엇이 오래 걸리는지 짐작하지 않고 줄마다 CCLOG 로 시간을 찍었다.

load()           31 ms
loadAll()     2,840 ms
preload()       410 ms
checkVersion()  920 ms
sendInstallLog() 880 ms

텍스처 올리는 것이 대부분이었다. HTTP 두 개가 각각 1 초 가까이 걸렸다. 재 보기 전에는 여섯 줄이 다 비슷하게 무거워 보였다.

지금 필요한 것만 먼저 했다

첫 화면에 나오는 텍스처는 몇 개 안 된다. 그것만 올리고 나머지는 화면이 뜬 뒤로 미뤘다.

ResourceLoader::loadForScene("title");

2,840 밀리초가 240 밀리초가 됐다. 나머지는 CCTextureCacheaddImageAsync 로 뒤에서 올린다. 다 올라오면 셀렉터가 불린다.

네트워크도 나눴다. 버전 확인은 결과를 기다려야 하지만 설치 기록은 기다릴 이유가 없다. 기다려야 하는 것과 안 기다려도 되는 것을 시작 자리에 같이 두면 둘 다 기다리게 된다.

돌아온 값을 안 보고 있던 것도 고쳤다. 비행기 모드에서 켜도 그냥 넘어가긴 했는데 그건 우연이었다. 되는 경우와 안 되는 경우를 다 적었다.

첫 실행의 재현과 실패 뒤

두 번째부터는 캐시가 있어 빠르니 첫 실행을 일부러 만들어야 했다.

$ adb shell pm clear <패키>
$ adb shell am start -n <패키>/.MainActivity

pm clear 는 설정에서 데이터 지우기를 누른 것과 같다. 안 먹는 기기에서는 adb uninstall 뒤에 다시 깔았다.

지우고 켜는 것을 확인 절차에 넣었다. 기기 다섯 대에서 돌려 보니 한 대가 여전히 느렸다. 저장 공간이 거의 차 있는 기기였다.

첫 실행 중간에 죽으면 다음에 어떻게 되는지도 봤다. 쓰다 만 UserDefault.xml 이 남으면 libxml2 가 그걸 읽다가 또 죽는다. 온전한지 보고 아니면 새로 만들게 했다. 한 번 죽으면 계속 죽는 것이 제일 나쁘다.

정리


Share this post on:

Previous Post
두 규칙이 서로 다른 말을 했다
Next Post
빌드가 20분 걸렸다