UE中Activity优雅退出

背景

UE Android lib集成过程,使用普通Activity+SurfaceView的方式加载UElib,在退出游戏Activity时,出现nativeOnInputQueueDestroyed引擎的崩溃
在这里插入图片描述

原因

InputQueue处理流程

  • onDestroy()
  • onInputQueueDestroy()
    这两个里面都可以在native层处理inputQueue,主要是 AInputQueue_detachLooper取消looper绑定
    然后是在native的ondestroy中设置android_app为空(这里会把inputqueue也置为空)
  • onDetachedFromWindow中兜底将inputqueue设置为空

上面这个流程导致UE改造中出现了问题:

  1. android层post onInputQueueDestroy消息到主线程,导致onInputQueueDestroy执行在onDetachedFromWindow之后,从而导致AInputQueue_detachLooper执行时出现“pthread_mutex_lock called on a destroyed mutex (0xf698788c)”错误,也就是inputqueue对象为空导致
  2. android层post onInputQueueDestroy消息到子线程,由于主线程和子线程时序没有保证,导致偶尔出现上面的问题,inputqueue先被置为NULL,然后执行了AInputQueue_detachLooper。

解决方案

方案一

直接主线程手动调用nativeOnInputQueueDestroyed接口。
由于里面没有走AInputQueue_detachLooper(),会走在onDetachedFromWindow前面,避免出现崩溃。对于GameThread线程为子线程的场景,可能会出现其他地方释放inputqueue,目前没有找到,有一定的风险,但是简单。

方案二

仿照NativeActivity的胶水层,在处理线程同步时,采用锁同步机制

//NDK胶水层代码
//android_app_set_input方法发运行在UIThread
static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
    pthread_mutex_lock(&android_app->mutex);//加锁
    android_app->pendingInputQueue = inputQueue;
    android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);//APP_CMD_INPUT_CHANGED消息写到GameThread
    while (android_app->inputQueue != android_app->pendingInputQueue) {//等待,直到APP_CMD_INPUT_CHANGED被消费掉,detachlooper操作在消息处理时被执行
        pthread_cond_wait(&android_app->cond, &android_app->mutex);
    }
    pthread_mutex_unlock(&android_app->mutex);//解除锁,UIThread继续执行
}

我们需要仿照这样在java层post MSG_TYPE_INPUTQUEUE_DESTROY消息时加锁并wait,在消息处理后跳出等待并解锁。

方案三

生命周期相关的方法直接在主线程中执行,不需要走GameThread。 可能在engine初始化时出现耗时的问题。
Android demo中会涉及到三个线程

  1. UI Thread 应用主线程,处理非游戏UI界面逻辑。
  2. GameThread NativeActivity创建时自动创建的一个带loop的子线程,处理UE tick事件(游戏逻辑)。
  3. AndroidEventThread ,事件处理子线程,处理来自Android端的事件,包括Event事件(生命周期)和Input事件(点击)。

AndroidEventThread事件会将Event事件通过FAppEventManager::GetInstance()->EnqueueAppEvent(APP_EVENT_STATE_ON_RESUME)加入到queue中,等待GameThread中tick触发时dequeue处理消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值