libgdx / assets什么算作"非静态"?

时间:2017-08-26 10:14:06

标签: android static libgdx

最近我一直在努力让一些libgdx项目在Android上运行。 我已经读过,AssetManager永远不应该被声明为静态,因为这会导致暂停/恢复时出现问题。

但你究竟能逃脱什么呢?

public  AssetManager assetsmanager;
static public  AssetManager assets;

private void setup() {

    assetsmanager = new AssetManager();
    assets=assetsmanager;
    ....

似乎很容易?

2 个答案:

答案 0 :(得分:2)

实际上可以对资产进行静态引用,但这是不鼓励的,因为绝大多数新用户不能很好地理解Android应用程序生命周期,而不会造成内存泄漏或丢失“已加载”资产。这里和LibGDX论坛上经常有一些问题,其中一些错误是由不正确使用静态引用引起的。 (但是如果你的应用程序有动态壁纸,那么绝对不能使用静态引用,因为由于动态壁纸预览,可能会同时运行LibGDX服务实例。)

您发布的代码无关紧要,因为没有足够的上下文来查看您是否做错了。

我认为无论如何都应该避免使用静态引用,因为它们可能会创建难以调试的容易出错的代码。通常,人们想要使用它们的唯一原因是避免一点点键入来传递对象引用。在我看来,这不是一个合理的理由。它会花费你更多的时间来寻找bug,而不是你在打字时节省的时间。

静态引用资产的主要问题是:

  1. 许多资产类型(纹理,着色器程序,网格)使用本机(JNI)内存,垃圾收集器不会自动清理它。
  2. Android应用程序可以在同一个应用程序进程中运行多个活动。如果您通过退出活动来关闭游戏,那么通常当您再次打开游戏时,新的活动将在同一个应用程序进程中运行,因此上一个会话的静态引用仍然保留。
  3. 人们似乎最常犯的错误是使用单例作为资产或SpriteBatch(也包含一些本机内存对象)。单例模式通常延迟加载对象。因此,如果游戏关闭并重新打开,资产将不会重新加载,并且会导致视觉错误,以及从之前加载的活动中泄漏资产内存。但是,可以通过在dispose()方法中正确处理所有资源并使静态引用归零来调整单例模式,以便在下次打开游戏时加载新对象。在调用dispose()之后,必须注意不要访问单个对象。

答案 1 :(得分:1)

如果你不能使它静止,那么你必须做以下两件事之一:

  1. 创建AssetManager,然后在屏幕之间传递参考
  2. OR

    1. 在每个屏幕上创建一个新的AssetManager,并在创建屏幕时仅为每个屏幕加载相关资源。
    2. 我更喜欢在主类中创建一个AssetManager并加载所有资源。将您的Main课程的参考传递给其他屏幕,以便我可以访问那里的资产管理员。

      public class Main extends Game {
      
         public AssetManager assetManager;  // for loading all assets
      
         @Override
         public void create(){
              assetManager = new AssetManager();
              assetManager.load("assets/data/yourSkin", Skin.class);
              assetManager.finishLoading();  // load assets (not asynchron for this example)
              setScreen(new GameScreen(this));
         }
      
         @Override
         public void dispose() {
            assetManager.dispose();   // disposes all assets when the game exits
         }
      }
      

      Gdx.app.getApplicationListener()返回ApplicationListener个实例。所以你可以对你实现的类进行类型转换,然后轻松访问该类的任何方法或数据成员。

      这样:

      ((Main)Gdx.app.getApplicationListener()).assetManager  // <-- You can use from where you want