Android: Declaring static bitmaps? Or or not?

Someone recently commented on my code where I am declaring the following:

private Bitmap splashBackground;
private Bitmap lightDot;
private static Bitmap scaledBackground;
private static Bitmap scaledLightDot;

      

They advised me to opt out of declaring bitmaps.

However, I've tried everything and my code doesn't work unless I declare them static.

Also, "public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)" seems to show up on the official Android developers site, so I'm a bit confused about what I should and shouldn't do.

Any pointers would be appreciated - thanks

Edit: for clarification:

When I remove the static from my ad, by the time I get to my onDraw () method, the scaled bitmap is null. (I create a scaled bitmap object in the initialise () method, and once it has been instantiated it is valid (i.e. not null), but then it seems like it became null in onDraw unless I declare it static ...

I am calling my initialise () method from my activity class.

Edit: More code as requested.

My OnCreate method: As you can see, I am passing in the screen height and width to create my scaled bitmaps.

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        displaySplashScreen= new SplashScreen(this);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // set View
        setContentView(new SplashScreen(this));
        WindowManager w = getWindowManager();   
        Display d = w.getDefaultDisplay();
        int width=d.getWidth();
        int height=d.getHeight();
        displaySplashScreen.initialise(width, height);
}

      

My initalise method:

 public void initialise(int w, int h)
 {       
     //Get width and height (passed in from Activity)

     vwidth=w;
     vheight=h;

     //Create pre-scaled bitmaps

    scaledBackground = Bitmap.createScaledBitmap(splashBackground,  vwidth, vheight, true);
    scaledLightDot = Bitmap.createScaledBitmap(lightDot, vwidth, vheight, true);

 }

      

I could also add that if I use a standard variable in the same way (like int number;) and set it to initalise (number = 5;) then the number is only 5 in my initialization method. If I register it with onDraw () it will always re-return '0' !! This is puzzling.

Thanks everyone so far, please let me know if more code is required ......

+3


source to share


4 answers


In general, using static

for Bitmap

is a very bad idea. There are many good reasons for this, mostly related to preventing memory leaks.

Also, "public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)" appears to appear on the official Android developer site ...

It is not static Bitmap

. This is a method call to a class method. Static doesn't work the same and the return type ( Bitmap

) is not static. This means that the method is static and does not require an instance call. It will return a bitmap which will be placed in the appropriate variable of your choice.

I am calling my method initialise()

from my activity class.

This statement is completely useless. Where is he called in the class? This onCreate()

, onStart()

, onResume()

, any other custom method? Where and when you choose to do certain things can have a huge impact on how successful they are.

... but then it seems to become null on onDraw unless I declare it static.

This could be for several possible reasons, and since we don't have any code, there isn't really a qualified answer. Here are a few things to watch out for.

  • This may be due to the activity being recreated.
  • It can also be caused by the fact that some method that appears to be unbound is actually called. It will probably be somewhere when you manually set it to null

    .
  • This could be due to incorrect use of the method createScaledBitmap()

    .
  • Bitmap can be reworked due to low memory (this actually happens more often than you might think)

EDIT: after looking at the code

It looks like it might be the culprit. Above, you have ...

displaySplashScreen= new SplashScreen(this);

      



Below you add ...

setContentView(new SplashScreen(this));

      

This means you create two Splashscreens . One of the reasons you get a null pointer when you are not using static

may be because further down the line you are using ...

displaySplashScreen.initialise(width, height);

      

But since your contentView is set to the new SplashScreen, you are not actually using that view. To solve this problem, make sure you are talking to the same object . I.e.

setContentView(displaySplashScreen);

      

At the very least, make sure you are looking at the same object. You may need to readjust a little depending on what else is going on. For example,

setContentView(displaySplashScreen);

      

... might appear below ...

 displaySplashScreen.initialise(width, height);

      

This is something you might have to play with, but I don't see anything else that gives any other immediate guidance. Be aware that troubleshooting nullpointer errors often results in more errors in your code being found first. Stay informed and solve each one in order.

+2


source


This line is wrong:

    // set View
    setContentView(new SplashScreen(this));        // This line is wrong.

      

Should be:



    // set View
    setContentView(displaySplashScreen);        // displaySplashScreen is created earlier.

      

Two copies are created SplashScreen

. You must keep using the same instance.

+1


source


I vote no, it's a static variable

private Bitmap splashBackground;
private Bitmap lightDot;
private static Bitmap scaledBackground;
private static Bitmap scaledLightDot;

      

and this is a static method

public static Bitmap createScaledBitmap (Bitmap src, 
     int dstWidth, int dstHeight, boolean filter)

      

Static variable

usually declared to be a constant and the variable belongs to the class not object as an example if you have a class

public class car {
      private static colorOfCar;
      private numberOfDoor;
}

      

let's say you have a class car and have 2 variables colorOfCar and numberOfDoor, when you create porsche and ferrari object from car class, if you change door number then OKOFDoor in your porsche object and ferrari object will be different, but if you change colorOfCar. then both the porsche object and the ferrari colorOfCar object will be changed because colorOfCar is a static object that belongs to the class, not an object.

I hope you can understand my explanation. If you find my answer, please help you, please vote and accept my answer and if you have any other questions feel free to ask in the comment, thanks :)

0


source


Without your code, it seems like you are using your view that is created more than once Possibly in duplicate of the view, or possibly in the same view that is being recreated (reloading the activity). The first time, initialize () is called before onDraw (), making your static Drawable initialized and valid. The second time, onDraw () works before initialize () (which works when Drawable is static). This is most likely due to the fact that you inflate the view and call initialize () afterwards (meaning the view is already in the layout). i.e.

public void onCreate(Bundle savedInstanceState) {
  setContentView(R.layout.mylayout); //the view is added to layout, onDraw() may be called
  MyView view = (MyView)findViewById(R.id.myview);
  view.initialize();  //initializing the drawable from null
  //no guarentee that initialize was called before onDraw()
}

      

This works fine when your Drawable is static, because when the second view is drawn, it uses the same Drawable that was initialized by the first view. When you delete a static file, you need to make sure that initialization is always called before onDraw ().

Instead of calling the initialize () function from your activity, why not call it from the View constructor? I often use the following pattern:

public class MyView extends View {

  private Bitmap splashBackground;
  private Bitmap lightDot;
  private Bitmap scaledBackground;
  private Bitmap scaledLightDot;

  public MyView(Context context) {
    super(context);
    init();
  }

  public MyView(AttributeSet attr, Context context) {
    super(attr, context);
    //parse attr for xml attributes
    init();
  }

  private void init() {
    splashBackground = getResources().getDrawable(R.drawable.splash_background);
    lightDot = getResources().getDrawable(R.drawable.light_dot);
    scaledLightDot = Bitmap.createScaledBitmap(lightDot, getDPI(32), getDPI(32), false);
  }

  public void onSizeChanged(int width, int height) {
    scaledBackground =  Bitmap.createScaledBitmap (splashBackground, width, height, false);
  }

  /**
   * Convert pixel value to device independent pixels (DPI)
   * @params pixels  Value for pixel size for MDPI screens
   */
  private int getDPI(int pixels) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, pixels, getResources().getDisplayMetrics());
  }

  public void onDraw(Canvas canvas) {
    //non-static drawables are guaranteed to be not-null
    canvas.draw(scaledBackground, 0, 0, null);
    canvas.draw(scaledLightDot, 10, 10, null);
  }
}

      

You set everything

0


source







All Articles