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