Java变量范围 - 复制位图?

时间:2015-06-07 09:15:25

标签: java bitmap scope recycle

当我们在方法中执行以下操作时,我试图更好地理解Java变量范围的工作原理以及底层数据究竟发生了什么:

this.variable = variable

这条线到底是做什么的?这是我的实际问题:

我正在加载位图以在我的(Android)OpenGL ES 2.0项目中应用为纹理。它是这样的:

public loadBitmapsForTextures(){

    myBitmap = BitmapFactory.decodeResource(view.getResources(), R.drawable.testbmp, Options);

    myObject.setTexture(view, myBitmap);

    Log.v("NewTag","Recycled: Again: "+myBitmap);

    myBitmap.recycle(); //All done - no longer required.  But why is myBitmap still valid here?
}

在我的Sprite类中(myObject是一个对象),我有以下内容:

public void setTexture(GLSurfaceView view, Bitmap imgTexture){

        this.imgTexture=imgTexture;  //What exactly is this line doing?  Copying the actual data?  Just making another 'pointer' to the original data?

        iProgId = Utils.LoadProgram(strVShader, strFShader);
        iBaseMap = GLES20.glGetUniformLocation(iProgId, "u_baseMap");
        iPosition = GLES20.glGetAttribLocation(iProgId, "a_position");
        iTexCoords = GLES20.glGetAttribLocation(iProgId, "a_texCoords");
        //Return usable texture ID from Utils class
        texID = Utils.LoadTexture(view, imgTexture);

        Log.v("NewTag","Recycled: Before: "+imgTexture);
        imgTexture.recycle();
        imgTexture=null;
        Log.v("NewTag","Recycled: After"+imgTexture);           

}

setTexture方法中的日志给出了我期望的结果。第一个命名位图:

  

Recycled:Before:android.graphics.Bitmap@1111111

     

Recycled:After:null

但是,初始loadBitmapsForTextures()方法中的log语句给出了一些我没有想到的东西:

  

Recycled:再次:android.graphics.Bitmap@1111111

为什么我允许(貌似)再次回收这个位图?我只能假设我对以下几行的理解存在缺陷:

this.imgTexture=imgTexture;

那么,这条线究竟做了什么?据我所知,它将类变量应用为与局部变量(传递给方法)相同的值,但是,显然还会发生更多事情。它实际上是否创建了一个全新的位图?如果是这样,为什么在记录时名称相同?

2 个答案:

答案 0 :(得分:1)

此行设置实例成员imgTexture以引用其引用传递给方法的同一对象。

this.imgTexture=imgTexture;   

此行将传递给方法的引用设置为null,这不会更改this.imgTexture

imgTexture=null;

也许您希望用

替换它
this.imgTexture=null;

如果您希望对象不再包含对该位图的引用。

答案 1 :(得分:0)

除了简单的布尔值和数值之外的任何东西,都会通过引用传递。所以

Object o1 = new Object();

创建一个新的Object并将一个名为o1的引用分配给内存中的区域。

Object o2 = o1;

将名为o2的新引用分配给内存中的同一区域。当你用参数调用方法时会发生同样的事情;你正在处理同一个实体,而不是副本。