我可以使用Context从其他线程返回的AssetManager吗?

时间:2018-01-24 23:30:01

标签: android

我正在构建自己的2D游戏引擎。我正在实现一个基于GLSurfaceView的游戏视图,所以我也在实现它的Renderer类。文档说该接口由一个单独的线程使用(根据堆栈跟踪“GLThread”)。我认为我可以通过放置锁和使用处理程序来同时处理几乎所有内容,除了...资产加载。

我不确定我是否可以在GL线程上使用AssetManager返回的Context.getAssets()实例。没有人,甚至没有文档说它可以从另一个线程(主线程除外)使用。我甚至编写了一个测试,它使用多个线程中的一个AsssetManager实例。

  • 我可以使用AssetManager从其他帖子返回的Context.getAssets()吗? (假设它一次只能被一个线程使用,而不能在onDestroy()调用后使用)

根据Context.getAssets()每次调用返回相同实例的事实判断,它似乎只返回内部成员。但我不知道这是否意味着我应该锁定它。

额外位

我尝试使用HandlerFutureTask在GL线程和主线程之间建立此“资源请求”通道。但是,我发现没有办法以我能想到的任何方式同步这两个线程。在这种情况下,活动正在运行onDestroy()并且GL线程正在等待主线程返回{{1上的FutureTask中的来自主线程的InputStream打开的资源AssetManager.open() }}。当发生这种情况时,实际上没有办法同步。活动只是等待GL线程返回到消息泵,因此它可能会在操作系统杀死应用程序之前永远卡住。

GL线程可以在多个处理程序消息上逐个加载资产,但这只是浪费CPU时间。我想在onSurfaceCreated()回调中加载所有资源。如果可能,分享onSurfaceCreated()似乎是唯一最好的选择。

1 个答案:

答案 0 :(得分:0)

由于AssetManager负责提供对应用程序原始资产文件的访问权限,因此如果没有像锁这样的基本并发原语(我相信操作系统自然会实现),它自然不会是Threadsafe。因此,将AssetManager加载项放在单独的线程上不会成为问题。

我个人利用 Executors.newSingleThreadedExecutor()确保在后台线程上进行工作,然而,它是按顺序完成的,以防止任何竞争条件。 如果同时对单独的文件执行读/写操作,Executors.newCachedThreadPool()不应该是一个问题。

您提到的Handler线程原语也可以使用