IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> UE中Activity优雅退出 -> 正文阅读

[移动开发]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处理消息。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-19 01:17:18  更:2022-02-19 01:17:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 14:37:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码