我正在制作Android游戏时遇到了问题。在游戏中“敌人太空飞船”将随机拍摄激光爆炸。因此,为了做到这一点,我决定创建一个生成随机数的方法,如果生成的数字是4,那么将填充LaserBlasts的ArrayList。
以下是方法:
// generates random number which later is used to decide if shoot ot not
public static void generateRandomNumber(ArrayList<EnemyShipLaserBlast> listOfLaserBlasts) {
Random random = new Random();
int number = random.nextInt(30);
switch (number) {
case 1:
break;
case 2:
break;
case 3:
listOfLaserBlasts.add(new EnemyShipLaserBlast(5, 3));
Log.i("LASER BLAST WAS ADDED", "**************");
Log.i("size laser blasts " + listOfLaserBlasts.size(), "--------");
break;
case 4:
break;
}
但是,当我从run()
方法(由Thread运行)调用此方法时,我得到了
java.lang.RuntimeException:无法在线程内创建处理程序 没有调用Looper.prepare()。
我的run()
方法如下所示:
@Override
public void run() {
int frames = 0;
long startTime = System.nanoTime();
long currTime = 0;
long lastTime = System.nanoTime();
while (playing)
{
currTime = System.nanoTime();
update((currTime - lastTime)/ 1000000000.0f); //updates the game data
draw(); //draws the screen based on the game data
control(); //controls how long is it until the run() method is called again
lastTime = currTime;
frames = frames + 1;
if (System.nanoTime() - startTime > 100000000)
{
framesPerSecond = frames;
frames = 0;
startTime = System.nanoTime();
}
}
}
所以我想问你们,我是否应该把这个方法放在其他地方,或者是否有另一种方法来解决这类问题?
答案 0 :(得分:1)
Handler.java
是一个由android框架提供的类,用于从主线程以外的线程更新GUI。
在android中,所有GUI都在主线程中更新并执行。该线程有一个与其自身关联的特殊对象,即Looper
对象。 Looper负责使用事件队列并执行队列中的操作。
主线程通过调用Looper.prepare()
来设置Looper的对象。任何线程都可以通过调用Looper.prepare()
来关联Looper的对象。
如果在主线程以外的线程中创建了Handler对象,而该线程中没有与之关联的Looper对象,则处理程序的Object非常无用(因为它无法执行预期的任务)去做)。它的handleMessage
方法不会按照框架的规范调用。“
如果您希望从主线程以外的线程(从您创建的线程)更新GUI,您可以通过创建Handler对象来完成此操作。应该在主线程的执行流路径中创建处理程序对象(而不是从除主线程以外的任何线程的run方法开始的任何其他路径)。您现在可以使用此Handler对象来调用sendMessage方法(有各种重载方法,您可以在Android开发人员站点中阅读)。处理程序对象接收回调handleMessage
,您可以在其中更新GUI。
如果您真的想挖掘更多,那么我建议您查看代码并阅读有关Handlers,Looper和ThreadLocal的内容。这些内部用于android内部的Handler实现。
请参阅https://developer.android.com/training/multiple-threads/communicate-ui.html#Handler
答案 1 :(得分:0)
您正在调用更新并从工作线程中进行绘制。您需要从主线程中调用更新,绘制(以及处理UI的大多数其他函数)。
你怎么称呼你的可运行的?
您应该将此参数添加到Handler对象:
while(str[i] != '\0')
因此,您的处理程序初始化将类似于:
Looper.getMainLooper()