Android Libgdx在创建参与者时内存泄漏

Android Libgdx在创建参与者时内存泄漏,android,memory-leaks,libgdx,Android,Memory Leaks,Libgdx,我已经创建了一个Android应用程序,使用Libgdx modelBuilder显示大约一百个point对象。它工作良好,模型渲染没有任何问题,但我需要为每个点模型添加一个标记。为了做到这一点,我从Actor开始扩展,在这个类中,我创建了两个纹理,分别表示用户单击对象时在普通模式和选定模式下的标记。以下是已为每个点模型实例化的LabelActor类 public class LabelActor extends Actor { Texture texture; Texture

我已经创建了一个Android应用程序,使用Libgdx modelBuilder显示大约一百个point对象。它工作良好,模型渲染没有任何问题,但我需要为每个点模型添加一个标记。为了做到这一点,我从Actor开始扩展,在这个类中,我创建了两个纹理,分别表示用户单击对象时在普通模式和选定模式下的标记。以下是已为每个点模型实例化的LabelActor类

public class LabelActor extends Actor {

    Texture texture;
    Texture selectedTexture;
    Sprite sprite;
    private Vector3 distVector = new Vector3();

    public LabelActor( String markerColor){

        String path = "markers/point_marker_" + markerColor + ".png"";
        String selected_path = "markers/point_marker_select.png";
        texture = new Texture(Gdx.files.internal(path));
        selectedTexture = new Texture(Gdx.files.internal(selected_path));
        sprite = new Sprite(texture);
        setBounds(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
    }

    @Override
    protected void positionChanged() {
        sprite.setPosition(getX(),getY());
        super.positionChanged();
    }


    @Override
    public void draw(Batch batch, float parentAlpha) {

         if (selected){
            batch.draw(selectedTexture, getX()-sprite.getWidth()/2, getY());
        } else {
            batch.draw(texture, getX()-sprite.getWidth()/2, getY());
        }
    }

}
在为这些对象使用标记时会出现问题,这会导致大量内存使用。为每个点对象加载球体模型需要大约14米的图形内存,但加载纹理标记需要500米的设备内存。我使用了位于资源文件夹中的png图标来创建纹理,但没有使用Libgdx图集。是否有机会为这些数量的点对象创建标记以消耗少量内存

下面是表示标记和点模型视图的图像

编辑1:
我使用AssetManager在主屏幕中加载纹理并创建它们的HashMap,然后按照Retron的建议将两个纹理数组传递给每个LabelActor类,但内存仍然超载

public class LabelActor extends Actor {

    Texture texture;
    Texture selectedTexture;
    Sprite sprite;
    private Vector3 distVector = new Vector3();

    public LabelActor(Texture[] textures){

        texture = textures[0];
        selectedTexture = textures[1];
        sprite = new Sprite(texture);
        setBounds(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
    }

    @Override
    protected void positionChanged() {
        sprite.setPosition(getX(),getY());
        super.positionChanged();
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {

         if (selected){
            batch.draw(selectedTexture, getX()-sprite.getWidth()/2, getY());
            infoWindow.draw(batch, parentAlpha);
        } else {
            batch.draw(texture, getX()-sprite.getWidth()/2, getY());
        }
    }
}
使用AssetManager加载纹理的主屏幕的一部分:

@Override
public void create() {

    ...
    environment = new Environment();
    environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1.0f));
    pointLight = new PointLight().set(0.8f, 0.8f, 0.8f, 2f, 0f, 0f, 500f);
    environment.add(pointLight);

    assetManager =  new AssetManager();
    textureTitleList = new ArrayList<>();
    for (FileHandle f: Gdx.files.internal("markers").list()){
        assetManager.load("markers/" + f.name(), Texture.class);
        textureTitleList.add(f.name());
    }
}

private void loadModel() {

    textureMap = new HashMap<>();
    for (String fName: textureTitleList){
        textureMap.put(fName, assetManager.get("markers/" + fName, Texture.class));
    }
}

@Override
public void render() {

    if (!isLoaded && assetManager.update()) {
        loadModel();
        isLoaded = true;
    }
    ...
}
@覆盖
公共void create(){
...
环境=新环境();
set(新的ColorAttribute(ColorAttribute.AmbientLight,0.4f,0.4f,0.4f,1.0f));
点光源=新点光源().设置(0.8f、0.8f、0.8f、2f、0f、0f、500f);
添加(点光源);
assetManager=新建assetManager();
textureTitleList=新的ArrayList();
对于(文件句柄f:Gdx.files.internal(“markers”).list()){
load(“markers/”+f.name(),Texture.class);
添加(f.name());
}
}
私有void loadModel(){
textureMap=newHashMap();
用于(字符串fName:textureTitleList){
textureMap.put(fName,assetManager.get(“markers/”+fName,Texture.class));
}
}
@凌驾
公共无效呈现(){
如果(!isLoaded&&assetManager.update()){
loadModel();
isLoaded=true;
}
...
}

您必须使用AssetManager并从asset加载一个纹理,而不是为每个新参与者创建新纹理。

是否可以在用户交互上更改每个标记的颜色?使用AssetManager时,并非所有标记都可以?当然可以。在资源中,需要加载所需所有颜色的标记图像,并以编程方式调用所需颜色的标记。资产类别必须在游戏开始时创建一次。然后在切换到新屏幕时,在参数中传递此类。因此,您的内存不会过载。在新屏幕中,您转到已加载的资产类并获取所需的纹理。我已使用AssetManager在主屏幕中加载所有纹理,并创建纹理的HashMap。然后使用HashMap将纹理传递给LabelActor类,而不是在Actor类中创建纹理,但内存仍然超载。