我正在工作的安卓游戏的一些用户正在试验有时会挂起手机的严重崩溃。此错误仅在游戏结束时(当玩家死亡并且在视口之外时)发生。由于这是一个非常严重的错误,我重构了代码,现在问题已经解决了一些用户,但不是全部。
我在Google Play中收到的报告总是与此类似:
Build fingerprint: 'google/hammerhead/hammerhead:4.4.2/KOT49H/937116:user/release-keys'
Revision: '11'
pid: 30442, tid: 30464, name: Thread-458 >>> com.mygdxgame.android <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 78c0b008
r0 78c0b008 r1 42bd8500 r2 00000188 r3 00000008
r4 753669c0 r5 42bd84f8 r6 b0800005 r7 78c0b008
r8 7547db10 r9 7537fd8c sl 75366a48 fp 7547db24
ip 00000000 sp 7547dae8 lr 75347c54 pc 4009e01a cpsr 60010030
d0 4458c000445b4000 d1 7e37e43c3c000000
d2 0000000000000000 d3 0000000000000000
d4 408b780000000000 d5 bf800000c0000000
d6 0000000000000000 d7 3f80000000000000
d8 408b180000000000 d9 408b1c0000000363
d10 0000000000000000 d11 3f80000000000000
d12 00000000000000ff d13 80000000bca3d70a
d14 bf80000080000000 d15 0000000000000000
d16 409f255618c5b67c d17 414e508260000000
d18 3fe45f306dc9c883 d19 4337fffffffffff7
d20 bfdffffffd0c5e81 d21 3fa55553e1053a42
d22 3fefb9659d96e85e d23 3f33872815df26e1
d24 3ef99342e0ee5069 d25 3ed592dfbf0a142d
d26 bfc0c4d52f39a3ad d27 bf62943a05b10df4
d28 3f33872815df26e1 d29 3ec6cd878c3b46a7
d30 bea6acf61c48ffe8 d31 c00921fb54442d18
scr 20000013
backtrace:
#00 pc 0002201a /system/lib/libc.so (__memcpy_base+69)
#01 pc 00037c50 /data/app-lib/com.mygdxgame.android-1/libgdx.so (Java_com_badlogic_gdx_utils_BufferUtils_copyJni___3FLjava_nio_Buffer_2II+88)
#02 pc 0001dbcc /system/lib/libdvm.so (dvmPlatformInvoke+112)
#03 pc 0004e123 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
#04 pc 00026fe0 /system/lib/libdvm.so
#05 pc 0002dfa0 /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
#06 pc 0002b638 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
#07 pc 00060581 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)
#08 pc 000605a5 /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
#09 pc 0005528b /system/lib/libdvm.so
#10 pc 0000d170 /system/lib/libc.so (__thread_entry+72)
#11 pc 0000d308 /system/lib/libc.so (pthread_create+240)
code around pc:
4009dff8 f811cb01 f800eb01 f800cb01 ea5feb01
<lines ommited>
code around lr:
75347c34 e12fff3c e59d101c e59d2018 e1a02102
<lines ommited>
我没有获得有关此堆栈跟踪的任何信息,因此我不知道如何修复该错误。
在阅读了一些有类似错误的人的帖子后(信号11),我很确定该错误与Box2D或我使用的批次有关。
这是bug中涉及的代码的一部分。
GameScreen
public GameScreen(MyGdxGame game) {
super(game);
worldNotifier = new WorldNotifier();
worldController = new WorldController(game, worldNotifier);
worldInputProcessor = new WorldInputProcessor(worldNotifier);
worldNotifier.addListener(worldController);
worldNotifier.addListener(achievementsUnlocker);
}
@Override
public void render(float delta) {
if (!paused) {
/* Update game world */
worldController.update(delta);
}
/* Clear screen */
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
/* Render game world */
worldRenderer.render();
}
@Override
public void resize(int width, int height) {
worldRenderer.resize(width, height);
}
@Override
public void show() {
GamePreferences.getInstance().load();
worldRenderer = new WorldRenderer(worldController);
/* Initialize controller and renderer */
worldController.init();
worldRenderer.init();
Gdx.input.setCatchBackKey(true);
Gdx.input.setInputProcessor(new GestureDetector(worldInputProcessor));
}
@Override
public void hide() {
worldRenderer.dispose();
Gdx.input.setCatchBackKey(false);
}
WorldController
public WorldController(MyGdxGame, WorldNotifier worldNotifier) {
this.game = game;
this.worldNotifier = worldNotifier;
rockSpawner = new RockSpawner(this);
cameraHelper = new CameraHelper();
cameraHelper.setAxisLocked(false, true);
}
private void showScore() {
game.scoreScreen.setScore(withstoodTime);
game.setScreen(game.scoreScreen);
}
public void init() {
if (world != null) {
world.dispose();
}
world = new World(new Vector2(0, -9.81f), true);
/* Instantiate game objects */
<code omited>
/* Set up controllers, listeners and... your know, all the stuff needed */
buoyancyController = new BuoyancyController(world, water.sensor);
buoyancyController.linearDrag = Constants.WATER_DRAG_FORCE;
world.setContactListener(new WorldContactProcessor(this, worldNotifier));
rockSpawner.init();
cameraHelper.setTarget(pirate);
startTime = TimeUtils.millis();
}
public void update(float delta) {
/* Update withstood time */
withstoodTime = TimeUtils.millis() - startTime;
/* Update game objects */
<code omited>
rockSpawner.update(delta);
buoyancyController.step();
world.step(1 / 60f, 6, 2);
cameraHelper.udpate(delta);
}
@Override
public void onPlayerFalling() {
player.die();
}
@Override
public void onPlayerOutsideViewport() {
game.googlePlayServicesResolver.submitScore((int) withstoodTime);
showScore();
}
ScoreScreen
public ScoreScreen(MyGdxGamegame) {
super(game);
font = new BitmapFont();
}
@Override
public void render(float delta) {
/* Clear screen */
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
String scoreText = "Your score is: " + score;
BitmapFont.TextBounds textBounds = font.getBounds(scoreText);
font.draw(batch, scoreText, (Gdx.graphics.getWidth() - textBounds.width) / 2, Gdx.graphics.getHeight() - 20);
batch.end();
if (Gdx.input.isTouched()) {
game.setScreen(game.gameScreen);
}
}
@Override
public void show() {
batch = new SpriteBatch();
game.googlePlayServicesResolver.showAds(true);
}
@Override
public void hide() {
batch.dispose();
game.googlePlayServicesResolver.showAds(false);
}
@Override
public void dispose() {
font.dispose();
}
public void setScore(long score) {
this.score = score;
}
因此,错误发生在onPlayerOutsideViewport调用之间(在onPlayerFalling之后1或2秒)和ScoreScreen的第一次渲染之间。回调(onPlayerOutsideViewport)由Box2D ContactListener调用,后者使用另一个向所有WorldListeners发送通知的WorldNotifier类通知事件。
我省略了很多代码但是如果你需要的话我可以添加它。有什么可以解决这个烦人的错误。