我正在制作一款塔防游戏,其中我想要单独的asyncTasks处理所有单元的移动,碰撞,损坏等;我希望GL Thread只处理绘图...
所以我在MyGLSurfaceView中有3个asynctasks扩展了glSurfaceView类。
我通过GLSurfaceView中的重写处理onTouchEvents。
一切都直接在GL线程上运行,直到是时候让小怪穿越迷宫了,在那儿我使用一系列的Handler h发布一系列“准备”的方法来为关卡装载小怪,并准备各种其他必需的实体。此过程的最后一步是编辑sharedpreferences,这将触发3个asyncTask(通过在MyGLSurfaceView中实现onSharedPreferencesChangedListenner的实现(不是我的渲染器))
在我的较旧设备(Nexus S和较旧的Samsung galaxy标签)上,这始终可以完美运行。
在我的Galaxy S4上,它只能在80-90%的时间内工作。
当它不起作用时,可能会出现各种替代结果
:
-该应用程序保持响应状态,并不断绘制屏幕上所需的所有内容,减去由asynctasks更改的所有内容;奇怪的是,我使用Log注意到异步任务似乎也正在正常运行,在日志中显示了预期值(怪物在正确的路径上正确移动,而塔正向其正确发射导弹,并且这些导弹的行为与预期的一样) (造成损坏并可能在撞击中导致生物死亡)。从视觉上看,我在起始航路点,我的塔楼,我的游戏区域,我的UI上看到一堆生物(它们始终是完全可点击的,并且只有0滞后才可交互)。 。我注意到,在观察到这种行为时,如果我按Home键触发onPause,然后返回到应用程序,触发onResume,则该操作将从头开始正常恢复(就好像我的asynctasks中所有以前的Log帖子一样)输了)。
当应用失败时,通常会发生这种情况。
是什么原因造成的?我的asyncTasks有时是否在渲染器的单独实例上工作?为什么它始终在旧设备上运行而不在新设备上始终运行?
由于我的生物数组上的指针为空,应用程序崩溃了(也许事情执行不正常)?
使用openGL es时应避免使用asynctask吗?
我应该这样做吗? (通过doInBackground更新暴民位置,并简单地绘制对象的最新坐标(由asynctask确定))
最佳答案
请勿使用AsyncTasks
。可能会出现多个问题:AsyncTasks
不能保证按启动顺序执行。
行为随着时间而改变,因此希望在不同的平台版本上遇到奇怪的事情
允许同时运行的AsyncTasks
数量有限。如果您开始更多,它们会排队等待,直到稍后才开始。更令人沮丧的是,这个数字在api版本之间发生了变化。
docs中的以下段落可能令人感兴趣:
执行顺序
首次引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,它已更改为线程池,允许多个任务并行运行。从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。
如果您确实希望并行执行,则可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。
公共最终AsyncTask executeOnExecutor
...
警告:通常并不需要从线程池中并行运行多个任务,因为未定义其操作顺序。例如,如果使用这些任务来共同修改任何状态(例如,由于单击按钮而写入文件),则不能保证修改的顺序。如果不进行仔细的工作,在极少数情况下,较新版本的数据可能会被较旧的版本覆盖,从而导致模糊的数据丢失和稳定性问题。最好以串行方式执行此类更改;为了确保无论平台版本如何都可以对这些工作进行序列化,可以将此功能与SERIAL_EXECUTOR一起使用。