Android : NullPointerException while adding Resources - android

I'm getting a NullPointerException when running this bit of code
abstract class thing extends Drawable(){
Bitmap sprite;
int spriteResource;
public thing(){
setResources();
sprite=Bitmap.createBitmap(sprite,src.left,src.top,(src.right-src.left),(src.bottom-src.top),m,true);
}
#Override
public void draw(Canvas c){
bit= Bitmap.createBitmap(sprite,0,0,45, 45);// Generates the exception
c.drawBitmap(bit, x, y, null);
}
abstract void setResource();
}
class otherThing extends thing(){
#Override
public void setResource(){
spriteResource=R.drawable.otherThing_sprite;
}
}
Basically i'm trying to load different sprites into different classes by using the method of the parent class. But the spriteResource doesn't get set and I can't understand why?
I set up the log which returned the Resource as 0. Any ideas why this is happening or how to resolve it???
Thanks

When createBitmap in thing() is trying to give the sprite variable a value, sprite is one of its in-parameters, this means that you are trying to use sprite before it is created and you get a null pointer exception.

Related

Getting Image w/ BitmapFactory

I'm not sure why this is not getting my image. This is my first time working with android apps with java so idk what to do.
public class Player {
private GameView view;
private Bitmap bmp;
public int x, y;
public Player(GameView view) {
this.view = view;
}
public void tick() {
//This is my error here//
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
public void onDraw(Canvas c) {
c.drawBitmap(bmp, x, y, null);
}
}
I'm getting an error when trying to set bmp equal to what I want it to be in my tick method for getResources(). I don't know why getResources() is wrong.
Thanks
getResources() is a method on Context. Your call to getResources() is not in a Java class that inherits from Context. You probably copied this code from some class that does inherit from Context, like Activity.
Your onDraw() method suggests that you are trying to create some custom View. If so, Player would need to inherit from View, and then you could use getContext() in order to retrieve a Context to use for getResources() (e.g., getContext().getResources().

Passing Android Acceleromter values from MainActivity to My GameView class

I am working on a game involving measuring accelerometer values and manipulating my character's position based on those values. I am only working with the X axis. I initiate my accelerometer manager in my main activity, but I need to use these values in another class. Obviously these values are constantly changing. How could I pass these values to my GameView class?
You can save them as static members of your activity, or pass them to GameView class each time there's a change in them (new value)
If you've used a sensorlistener you might think about moving that logic to the GameView class. Not totally sure without looking at your code though. Do you have any samples?
Why not do it the Android way? :)
When you implement a touch listener, you do something set like this:
myView.setOnTouchlistener(this):
This tells the view to call you back when it's touched. Here's how to do your own:
Define an interface and use a callback to let the class know that a value has changed.
public interface AccelerometerUpdateListener {
void onUpdate(int arg1, string arg2); ..<----add arguments you want to pass back
}
In your Activity:
public class MainActivity extends Activity implements AccelerometerUpdateListener {
ArrayList<AccelerometerUpdateListener > listeners = new ArrayList<AccelerometerUpdateListener >();
...
#Override
public void onCreate(Bundle savedInstanceState)
{
...
myGameClass.setResponseReceivedistener(this);
...
}
public void setUpdateListener(AccelerometerUpdateListener listener){
if (!listeners.contains(listener){
listeners.add(listener);
}
}
public void removeUpdateListener(AccelerometerUpdateListener listener){
if (listeners.contains(listener){
listeners.remove(listener);
}
}
When you update the values
for (AccelerometerUpdateListener listener:listeners){
listener.onUpdate(arg1, arg2);
}
In your receiving class:
public class MyGameClass implements AccelerometerUpdateListener {
...
#Override
public void onUpdate(int arg1, string arg2){
// do whatever you need to do
}
All from memory so please excuse typos.

Android: Declaring static bitmaps? Yay or nay?

Somebody recently commented on my code where I declare the following:
private Bitmap splashBackground;
private Bitmap lightDot;
private static Bitmap scaledBackground;
private static Bitmap scaledLightDot;
They advised me against declaring satic Bitmaps.
However, I've tried everything and my code doesn't work unless I declare them as static.
Also, "public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)" seems to appear on the official Android Developer site so I'm a bit confused about what I should and shouldn't be doing.
Any pointers would be appreciated - thank you
Edit: For clarification:
When I remove the static from my declaration, then by the time I get to my onDraw() method, the scaled bitmap is null. (I am creating the scaled bitmap object in an initialise() method and once it's been created, it is valid (ie, not null) - but then seems to become null at onDraw unless I declare it as static.
I am calling my initialise() method from my activity class.
Edit: More code as requested.
My OnCreate method: As you can see, I'm passing my screen height and width over so I can 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 add also that if I use a standard variable in the same way (say int number;) and set it in initalise (number = 5;), then number is only equal to 5in my initialise method. If I log it from onDraw() it will always repeatedly return '0'!! It's baffling.
Thanks everyone so far, please let me know if more code is required......
In general, utilizing static for Bitmaps is a very bad idea. There are a lot of good reasons for this, mostly having to do with avoiding memory leaks.
Also, "public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)" seems to appear on the official Android Developer site ...
This is not a static Bitmap. This is a method call to a class method. Static does not work the same and the return type (Bitmap) is not static. What this means is that the method is static and does not require an instance to be called. It will return a Bitmap to be placed in an appropriate variable of your choice.
I am calling my initialise() method from my activity class.
This statement is quite unhelpful. From where in the class is it being called? Is it in onCreate(), onStart(), onResume(), some other custom method? Where and when you choose to do certain things can have a huge effect as to how successful they are.
... but then seems to become null at onDraw unless I declare it as static.
This could be for several possible reasons, and since we don't have any of your code there really isn't a qualified answer. Here are some things to look at.
This could be because the Activity is getting recreated.
This could also be because some method that seems unrelated is actually getting called. This would probably be somewhere that you are manually setting it to null.
This might be due to improper use of the createScaledBitmap() method.
The Bitmap might be getting recycled due to low memory (this actually happens more often than one would think)
EDIT: After reviewing your code
This looks like it may be the culprit. Above, you have...
displaySplashScreen= new SplashScreen(this);
Below, you add...
setContentView(new SplashScreen(this));
This means that you are creating two Splashscreens. One reason why you are getting a null pointer when you are not using static may be because further down the line you use...
displaySplashScreen.initialise(width, height);
But since your contentView is set to a new SplashScreen, you are not actually utilizing that View. To resolve this, make sure you are talking to the same view object. I.E.
setContentView(displaySplashScreen);
This will at least make sure you are looking at the same object. It is possible that you may have to reorganize a bit depending upon what other things are happening. For instance,
setContentView(displaySplashScreen);
... may have to appear below ...
displaySplashScreen.initialise(width, height);
This is something that you might have to toy with, but I don't see anything else that gives any other immediate indication. Be aware that resolving nullpointerexceptions will often result in revealing more errors in code, at first. Stay the course and resolve each in order.
This line is wrong:
// set View
setContentView(new SplashScreen(this)); // This line is wrong.
Should be this:
// set View
setContentView(displaySplashScreen); // displaySplashScreen is created earlier.
You are created two instances of SplashScreen. You should keep using the same instance.
I vote for nay,
this one is a static variable
private Bitmap splashBackground;
private Bitmap lightDot;
private static Bitmap scaledBackground;
private static Bitmap scaledLightDot;
and this one is a static method
public static Bitmap createScaledBitmap (Bitmap src,
int dstWidth, int dstHeight, boolean filter)
static variable is usually declared for a constant and the variable belongs to 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 variable colorOfCar and numberOfDoor when you create an object porsche and ferrari from car class if you change the number of door it's OK the numberOfDoor in your porsche object and ferrari object will be different, but if you change the colorOfCar both porsche object and ferrari object colorOfCar will be changed because the colorOfCar is a static object that belong to the class not the object.
I hope you understand my explanation. If you find my answer helping you please vote and accept my answer and if you have any other question feel free to ask in the comment, thank you :)
Without your code, it seems you are using your view is being created more than once. Maybe in two instances of the view, or maybe the same view being recreated (Activity restarting). In the first time around, initialize() is being called before onDraw(), making your static Drawable initialized and valid. The second time around, onDraw() is running before initialize() (which works when Drawable is static). This is most likely due to you inflating the view and calling initialize() afterwards (this means 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 runs ok when your Drawable is static because when the second view is drawn, it is using the same Drawable which was initialized by the first view. When you remove the static, you need to make sure initialize is always called before onDraw().
Instead of calling initialize() from your activity, why not invoke it from the View's 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'll be all set

ActivityInstrumentationTestCase2 and use of static finals: fields become null after first test

This is really looks like some magic is going on and I'm interested to understand why that happens :)
Here's the unit-test I have:
public class SelectThemeActivityTest
extends ActivityInstrumentationTestCase2<SelectThemeActivity> {
private final static int[] STATIC_ARRAY = { 0, 1, 2 };
public SelectThemeActivityTest() {
super("com.the7art.simplewallpaper", SelectThemeActivity.class);
}
#Override
protected void setUp() throws Exception {
super.setUp();
// some array usage here - will throw NullPointerEcxeption on second test
// see description below
STATIC_ARRAY[0] = 2;
}
#Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testFirst() {
}
public void testSecond() {
}
public void testThird() {
}
}
If I run this test case the first test completes successfully and all the rest fail by throwing NullPointerException from setUp() - the line which tries to access STATIC_ARRAY.
What puzzles me even more is the fact that if I change the test case to extend AndroidTestCase instead of ActivityInstrumentationTestCase2, then all tests complete successfully! Magic! :-)
Also if I remove 'static' keyword from STATIC_ARRAY, tests succeed too.
So it's clear that something is modifying my STATIC_ARRAY by making it null between a test runs, most probably in tearDown() and that something has to do with ActivityInstrumentationTestCase2, but how to track that something? :-) Any ideas?
The reason is scrubClass() method called from super.tearDown(): google-groups discussion. A solution is - overriding this method.
Put a watch point on STATIC_ARRAY and see who modifies it, although there are not too many candidates (since the field is private, there is pretty much only one candidate, the class you just posted, so something is missing from the picture.

How can I pass an int to my onDraw(Canvas canvas) in Android?

I use a surfaceview to draw a pie chart in Android. In order to know how big the pie slice should be I need to pass a parameter to the onDraw() method. How can I do this? Inside the onDraw() I make a query to a datahelper-class that fetches the right data.
I tried to call a static function in one Activity from the onDraw, and which function returned an integer. But I want something more dynamic, so I can send the integers I need to from the Activity to the onDraw and just get the result in form of a pie chart.
Any suggestions?
One of solutions can be like this:
public class MySurfaceView extends SurfaceView
{
private MyParameter parameter;
public void setParameter(MyParameter parameter)
{
this.parameter=parameter;
}
#Override
public void onDraw(Canvas canvas)
{
if(this.parameter==null)
return; //nothing to draw...
//draw here...
}
}
//somewhere in code
MySurfaceView sView=(SurfaceView )findViewById(R.id.pie_chart);
//
sView.setParameter(new MyParameter(100,2000, false));
}

Categories

Resources