我已经从事Android游戏已有一段时间了。我已经实现了基本游戏,所以现在我要回去尝试优化。似乎电池消耗和CPU使用率对于我正在执行的操作来说太高了。我实际上只有我的主线程,然后所有绘图和更新都是在单独的线程上完成的。
以下是进行更新和所有绘图的实际游戏线程的代码。所有实际的代码都已删除,剩下的就是我正在尝试找出异常的CPU使用率/电池消耗的实验。
因此,基本上,如果我仅使用无限的while循环来启动以下线程,则该应用在使用30分钟后将消耗约315mAh或约9%的手机电池电量。如果我在run方法中不使用代码启动线程,以使其在运行一次后失效,则在相同的时间内它会消耗大约70mAh或2%的手机电池电量。当线程运行并仅运行无限循环时,CPU使用率也从不运行线程的2%-3%跃升至大约14%-15%。
总而言之,似乎仅使用无限while循环运行线程,什么也不做,在30分钟内将电池使用量增加了7%。我不知道这是怎么可能的,并认为我一定会丢失一些东西。我将继续努力解决这个问题,但是没有更多代码可以提取了。如果有人有任何建议或可以提供一些有关为什么发生这种情况的见解,我将不胜感激。提前致谢。
class InnerThread extends Thread
{
public InnerThread()
{
super();
}
public void run()
{
while(true){}
}
}
无延迟或无节奏的循环因占用CPU和电池而臭名昭著。仔细考虑您是否真的需要连续处理,或者每帧一次,每个任意时间间隔一次还是每次外部事件发生一次就足够了。尝试在循环中添加一个小的任意延迟,您可能会立即看到改进。
许多游戏使用主游戏循环。这是一个可搜索的术语。基本上,一个无限循环执行一些计算,绘制一个帧,然后通常休眠一段时间。 (请参阅SystemClock.sleep()与Thread.sleep()。)您的主循环可以将帧号和时间戳传递给其余代码。您可以每帧计算移动对象的位置,但是可以做更复杂的事情,例如仅在一定时间间隔或帧内更新敌人的AI。如果您使用Unity之类的游戏引擎,则主循环仍然存在,但您不必自己编写。您只需编写它调用每一帧的代码。
所以我认为这可能是问题所在。我进行了测试,它以每秒13,000帧的速度运行,这显然太高了,无法满足我的需求。理想的是使其以60 FPS的速度运行。香港专业教育学院试图使用System.nanotime来保持帧率,但在那种情况下,大多数游戏代码都以60 FPS运行,但是保持帧率的代码仍以13,000+ FPS运行。我可以尝试以其他方式保持帧速率,延迟的首选方式是什么? SystemClock.sleep?
@Envenge编辑。
非常感谢您的帮助。我有游戏循环的经验,并实现了一个游戏,我只是删除了实际的代码以尝试使循环中的代码最少,以确保我没有内存泄漏或内部某处引起CPU使用率飙升的东西。和电池消耗。对我来说,多线程是一个相当新的概念,我仍在尝试充分利用。肯定有很多东西要学习,我再次感谢您的时间和耐心来解释似乎很明显的事情。
我经历并编辑了我的代码。利用thread.sleep限制整体绘制并将代码更新为每秒60帧。我还使用了Object.wait()和Object.notify()方法来减少不必要的线程处理。我看到了巨大的进步,感谢您的帮助,我非常感谢。我的问题绝对是我在浪费电池和CPU电源处理任何事情。
while(true)是经典的无穷循环,在Java中可能不需要。
它甚至不在哪个线程上运行都很重要,它很可能会耗尽汁液。
请参见" while(true)"循环是如此糟糕吗?
嗨,while(true)循环是无限的,因此它只需做少量工作即可保持线程运行以测试线程的电池消耗。我想最大程度地减少线程正在执行的工作量,以查看我能用多低的电量消耗电池并仍然使线程运行。
@Envenge您并没有减少工作量。旋转while(true)与执行一些有用的计算一样多。
@Envenge是另一个答案,除非添加一些缓动...否则它将以最大迭代速度运行并严格消耗电池电量。这是可以在交流电源机器上执行的操作,但不能在移动设备上执行。最好只在需要时执行处理。
例如。当添加Thread.sleep(500)时,它仍然每秒迭代两次。但这是一种解决方法。重新考虑建议的基本业务逻辑。
香港专业教育学院已经玩了一点,但还没有找到最好的方法来做到这一点,而不会稍微影响游戏性能。麻烦研究一下重新组织代码,并尝试使线程定期进入睡眠状态。感谢您的快速回复!
@Envenge您需要确定您甚至需要在其中运行任何代码的频率。可能添加服务会有所帮助;这也将拥有自己的线程并继续运行。尝试使其成为基于事件的游戏,或者查看其他游戏引擎的源代码以及它们的处理方式。