我正在构建自己的2D游戏引擎。我正在实现一个基于GLSurfaceView
的游戏视图,所以我也在实现它的Renderer
类。文档说该接口由一个单独的线程使用(根据堆栈跟踪“GLThread”)。我认为我可以通过放置锁和使用处理程序来同时处理几乎所有内容,除了...资产加载。
我不确定我是否可以在GL线程上使用AssetManager
返回的Context.getAssets()
实例。没有人,甚至没有文档说它可以从另一个线程(主线程除外)使用。我甚至编写了一个测试,它使用多个线程中的一个AsssetManager实例。
AssetManager
从其他帖子返回的Context.getAssets()
吗? (假设它一次只能被一个线程使用,而不能在onDestroy()
调用后使用)根据Context.getAssets()
每次调用返回相同实例的事实判断,它似乎只返回内部成员。但我不知道这是否意味着我应该锁定它。
额外位
我尝试使用Handler
和FutureTask
在GL线程和主线程之间建立此“资源请求”通道。但是,我发现没有办法以我能想到的任何方式同步这两个线程。在这种情况下,活动正在运行onDestroy()
并且GL线程正在等待主线程返回{{1上的FutureTask中的来自主线程的InputStream
打开的资源AssetManager.open()
}}。当发生这种情况时,实际上没有办法同步。活动只是等待GL线程返回到消息泵,因此它可能会在操作系统杀死应用程序之前永远卡住。
GL线程可以在多个处理程序消息上逐个加载资产,但这只是浪费CPU时间。我想在onSurfaceCreated()
回调中加载所有资源。如果可能,分享onSurfaceCreated()
似乎是唯一最好的选择。
答案 0 :(得分:0)
由于AssetManager
负责提供对应用程序原始资产文件的访问权限,因此如果没有像锁这样的基本并发原语(我相信操作系统自然会实现),它自然不会是Threadsafe。因此,将AssetManager
加载项放在单独的线程上不会成为问题。
我个人利用
Executors.newSingleThreadedExecutor()
确保在后台线程上进行工作,然而,它是按顺序完成的,以防止任何竞争条件。
如果同时对单独的文件执行读/写操作,Executors.newCachedThreadPool()
不应该是一个问题。
您提到的Handler
线程原语也可以使用