【问题标题】:Problems running Android app for second+ time第二次以上运行 Android 应用程序出现问题
【发布时间】:2010-11-27 00:08:47
【问题描述】:

我是 android 新手,正在开发一个基于 AndEngine (www.andengine.org) 的小游戏。

游戏显示背景的平铺地图,带有不同类型的瓷砖(一些可移动,一些可旋转)。我还在屏幕上画了一些线条。

问题是,当游戏第一次运行时(在手机上运行,​​从 Eclipse 启动)它运行完美,但是如果我使用手机的 BACK 按钮退出游戏并从手机主屏幕图标重新启动游戏,应用程序有很多错误.线条不再出现在屏幕上,移动和旋转图块的功能只工作一次,然后游戏无法运行。它不会崩溃,但由于游戏重启引起的错误使其无用。

我已经阅读了有关应用程序生命周期的所有内容,并尝试在 onDestroy() 方法中将各种对象设置为 null,但我所做的一切都没有产生任何影响。第一次运行应用程序时,显然有些东西“徘徊”,并在第二次启动时引起问题。请帮忙,24 小时的谷歌搜索和绞尽脑汁都没有结果。

谢谢, 史蒂夫

附:在模拟器中运行时的行为相同。

更新:

我进一步调查了我的代码:

我创建了一个小程序来调查上述问题的一部分,画了一条线,并且在重新运行应用程序时没有画线。

使用 AndEngine 必须重写 onLoadScene()。在此方法中,您可以在启动时指定您想要在屏幕上显示的内容,并且该方法返回一个 Scene 对象。场景处理您在屏幕上看到的内容,因此如果您想说,向屏幕添加新行(或精灵,或其他),您调用 myScene.addEntity(myLine)。我创建了一个主要的活动类和一个名为 MyLine 的类来画线。

我的主要活动:

public class LineTest extends BaseGameActivity {

@Override
    public Scene onLoadScene() {
        scene = new Scene(1);
        myLine = new MyLine();
        myLine.displayLine();   
        return scene;
    }
}

MyLine 类:

public class MyLine {

    static final Scene SCENE = LineTest.scene;
    static final int LINE_WIDTH = 4;

    Line line = new Line(0,0,0,0);

    public MyLine() {
    }

    public void displayLine() {
        line.setLineWidth(4);
        line.setColor(1f, 0f, 0f);
        line.setPosition(10, 10, 400, 400);
        SCENE.getBottomLayer().addEntity(line); 
    } 

    public void removeLine() {
        SCENE.getBottomLayer().removeEntity(line);
    }
}

您可能会注意到上述问题,在我的辩护中,我是 Java 和 OOP 的新手。 我的活动只使用一个场景,所以我想,在我的 MyLine 类中,我可以将 SCENE 声明为静态最终,因为它不会改变。错误的! 调试程序我发现静态最终 SCENE 一旦设置,就永远不会改变,即使在程序已经停止(使用返回键)并重新启动之后。但是,当程序重新启动代码 Scene scene = new Scene(1);使用新 ID 创建一个新场景,因此静态最终 SCENE 指向旧场景而不是新场景,因此不会在新场景中创建线。

我发现有两个选项可以解决这个问题:

要么:

Scene SCENE = LineTest.scene;

或者:

static Scene SCENE;

在构造函数中:

    SCENE = LineTest.scene; //I could also pass scene as param to 
constructor which may be better OOP practice.

我怀疑我的游戏应用程序的其他问题都与在不应该的情况下将事物声明为 static 或 static final 有关。

在决定应该使用什么类型变量(和方法)时,我是否可以使用经验法则?

更新:我在我的 Game 类中声明了三个变量,它们应该只是静态的。将它们更改为静态并在构造函数中分配它们已经解决了所有问题,WOOHOO! {:-)

【问题讨论】:

  • OnDestroy 不一定会被调用。将东西设置为 null 可能会使情况变得更糟。您应该立即进行清理。没有看到代码,我们不知道如何为您提供帮助
  • 该游戏包含大约 12 个类,所以我认为发布的内容太多了。是否有我应该关注的特定领域,或者我应该发布代码 sn-ps?

标签: java android andengine


【解决方案1】:

为什么你的类中有一个特定于实例的静态字段?让它成为一个实例变量左右。

您也可以在打开应用程序时手动重置所有静态字段,但这会非常丑陋。

【讨论】:

  • 抱歉,我覆盖了一个未提交的旧问题,忘记更改标题。至于我的类设计,我有一个抽象类 GameTile,其中包含屏幕上所有图块共有的一些静态字段和方法。然后,我有许多扩展 GameTile 的不同类,例如 LaserEmitter 和 LaserSplitter,它们描述了各个图块类型的更具体的行为,这些包含实例变量。我也是 Java 新手,所以可能做错了一些事情,但它在第一次执行时运行良好。
  • 你在正确的轨道上:静态字段。我已经在上面回复了我的发现,感谢您的指点。
【解决方案2】:

在第一次运行应用程序时显然“徘徊”,并在第二次启动时导致问题。

您是否创建了自己的应用程序子类?如果您在应用程序级别对游戏进行一些初始化,然后在 Activity 级别进行其他初始化,那么前者不会重复,直到应用程序本身被杀死并重新启动。简单地使用 BACK 按钮退出并不会直接终止应用程序。

【讨论】:

  • 谢谢。不确定应用程序子类的确切含义。主要活动扩展了 BaseGameActivity(AndEngine 的一部分),我在这里或从这里调用的类中做所有事情。我已经在应用重启时运行了调试器,我编写的所有内容都会再次执行,但屏幕上的结果与第一次运行的应用明显不同。
  • 好的,如果你不知道,那么你可能不知道,我的回答不适用。基本上 public class MyClass extends Application {} 然后你在 AndroidManifest.xml 元素中使用它。在应用程序对象中声明/实例化的任何内容都将持续存在,直到应用程序本身被应用程序管理器中的“强制停止”杀死,或者如果 Android 系统需要内存。
  • 我明白了,谢谢你的解释。在我的代码中绝对没有类似的东西。此外,AndEngine 不需要像这样在清单中输入任何条目,因此在我不知情的情况下不能这样做;)
  • 如果您对调试器显示完全重新初始化感到高兴,不确定还有什么建议。我想知道当您第二次运行它时,您是否实际上正在运行活动的第二个实例,而第一个仍然“活动”,这很令人困惑。您可以尝试监听 BACK 按钮按下并显式调用 Activity 自己的 finish() 方法以使其自行终止。
  • 再次感谢。我将使用调试器仔细检查,以防我遗漏了什么,并报告回来。我确实尝试在 onKeyDown() 中调用 this.finish() (检查 KeyEvent.KEYCODE_BACK)并添加了一条调试消息以进行确认。我还在 onPause、onStop() 和 onDestroy() 中添加了调试消息。在按下返回键时调用或不调用finish() 之后总是调用onPause、onStop 和onDestroy,并且使用finish() 重新启动应用程序时的行为没有改变
【解决方案3】:

小心使用静态最终变量!!! 解决我上面的问题。

【讨论】:

    【解决方案4】:

    我也遇到了这个问题,我通过删除一些静态变量和静态方法来解决它。我知道在android中单击后退按钮时静态变量会留在内存中,但我仍然不知道为什么效果如此奇怪。 也谢谢楼上的各位!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多