Discussion Forums  >  BT.com Website, Account Questions

Replies: 8    Views: 172

David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
12/02/12 01:31 AM (11 years ago)

EPIC NullPointerException Saga - Android will not win!

Hi gang. **** NERDS ONLY BEYOND THIS POINT **** Many of our Android appster's are familiar with the Epic Battle between an infamous NullPointerException issue I've been fighting for literally months. For those not aware, the "Background Image / Color" shenanigans and subsequent mystery crashes have nearly driven me to the edge. Obama found a few gray hairs in the last four years. I've found more! Details: Mysterious crashes when setting some background image / color combinations in Android. Fix Attempts: Far too many to list. But, the last one, which appears to have fixed lots of apps for lots of folks was the re-working of how each screen's data (the JSON) is passed along to a newly opening screen. We began passing JSON from the "old screen to the new screen" using Android's built in putExtra's routine. This seemed to fix it. HOWEVER... I've spent the better part of two days helping a longtime community member, fellow buzztouch enthusiast, and all around great guy (@ianjamespiano) work on an Android app. He's been working on getting an already functioning iOS app that was built with BT v1.5 running on Android. It made sense that the Android edition would also run BT v1.5. I sooooo didn't want to re-visit the older v1.5 project but have been working on this project long enough to justify NOT having a 2.0 and a 1.5 version (in his case). So, while tinkering with his older v1.5 project I ran into my NullPointerException buddy from the past. I was beyond pissed off. WOW was this frustrating. I can't imagine how many folks must have given up on this? Sigh....Anyway, I tested, debugged, broke stuff, threw my computer around and came up with yet another improvement. This goes beyond the putExtra's methodology mentioned above. ALL of this brokenness lives in the private Runnable setBackgroundImage method that begins on line 425 of the BT_activity_base.java file. The "Null pointer" is the reference to the backgroundImageView object. This is the object setup in the XML layout file that all the plugins use. On line 430 it WAS doing this: backgroundImageView = (ImageView) findViewById(R.id.backgroundImageView); In English this means: "Hey Android Activity (the one that's running), get a reference to the layout object in the .XML file and find the object with the id backgroundImageView" This was returning NULL. This is not good. You'll see on line 436 where it does: if(backgroundImage != null ) "Hey Android, if you have an image, use it to set the background image in this object." BUT, that line is only checking if the image is null, not the actual layout objet that sets the image. AND, the method in which I was getting a reference to the layout object itself could be better. The newly implemented change is: backgroundImageView = (ImageView) thisActivity.findViewById(R.id.backgroundImageView); Note the addition of "thisActivity" in this line. This is very very important (as it turns out). My assumption was that because this file extends Android Activity that this was not needed. BUT, because the setBackgroundImage method is running off the main UI thread it was indeed needed. Wow, the things we learn. This line is also changed to make sure both the image and the image layout object are not null before operating on them: if(backgroundImage != null && backgroundImageView != null) It's the 10th round, Android's no longer winning this fight. I've been punched, kicked, slapped around for darned near a year on this one single issue but never got knocked out. I came outta my corner in the 10th and smacked this thing right in the mouth. I'm soooo winning this fight. Go fix something. Out.
 
Mackimack
Apple Fan
Profile
Posts: 481
Reg: Dec 30, 2010
Sweden
14,310
like
12/02/12 02:11 AM (11 years ago)
Nice work David! You can send your gray hair to Google and write a letter "I won" :)
 
LA
Aspiring developer
Profile
Posts: 3278
Reg: Aug 16, 2012
Jerseyville, IL
42,880
like
12/02/12 07:22 AM (11 years ago)
David @buzztouch, Did you say, "winning"..lol Auh, the NullPointer Exception...seen it too many times. Out of curiosity, can you use "this", instead of "thisActivity"? Sounds like Android knocked you out in the first round, then you had a TKO in the 10th. LA
 
Sandeep
Android Fan
Profile
Posts: 1260
Reg: Feb 01, 2012
Miraj, India
25,250
like
12/02/12 08:29 AM (11 years ago)
So you are the Duracell bunny... Never Give Up... Thanks for all the effort, this is really huge achievement.
 
David @ buzztouch
buzztouch Evangelist
Profile
Posts: 6866
Reg: Jan 01, 2010
Monterey, CA
78,840
like
12/02/12 04:22 PM (11 years ago)
@LA: Tough to explain all the concepts here but I'll give it a go. In Java "this" refers to the instance of a particular object you're working with. In this case (no pun intended), "this" would refer to the Activity class. Or, more specifically: An instance of BT_activity_base. Because all the classes for the plugins extend this class, all the plugins can use methods in that base class. This is why you can do something like showProgress() in one of the plugins without actually writing the showProgress() method in each plugin - it's written in the parent class. BT_activity_base. And, showProgress() and this.showProgress() would do the same thing. In the case of the NullPointerException, "this" would refer to the Android Activity that's running. In almost all cases this would be OK. And, omitting the "this" would be the same thing. backgroundImageView = (ImageView) findViewById(R.id.backgroundImageView); would be the same thing as: backgroundImageView = (ImageView) this.findViewById(R.id.backgroundImageView); Where "this" would be referring to the currently running activity. BUT, because the background image is being downloaded and configured in a thread that's off the main UI thread (so the main UI thread doesn't lock while it downloads), we were losing a reference (a pointer) to "this." Imagine launching an Activity that used a background image. The background image begins to configure itself in a background thread. Then, you move away from this Activity. The background process is still running. When the image tries to apply itself to the background Image View it's gone! It's gone because we moved away from the screen that started the background process. So, "this" is NULL. The solution was to introduce a Instance Variable (sometimes called fields in java) in the parent class. Have a look at line 58 in BT_activity_base.java, you'll see: public static Activity thisActivity = null; This is an instance variable named "thisActivity" (it could have been named anything) with an object type of Activity. In the onCreate method we save a reference to "this" meaning the value of thisActivity will be equal to the Activity itself. Again, hard to explain. The difference here is that because we are remembering this pointer / reference in a variable named "thisActivity" we can refer to it in the background thread that handles the image, even if the Activity has been pushed off the screen. backgroundImageView = (ImageView) thisActivity.findViewById(R.id.backgroundImageView); Notice the "thisActivity" in that line. It's saying, hey, the Activity that ran the onCreate is the Activity that we were configuring the background for. Hope this helps. This, that. self, pointers, references, it's all terribly confusing for non-programmers and hard to explain for anyone!
 
LA
Aspiring developer
Profile
Posts: 3278
Reg: Aug 16, 2012
Jerseyville, IL
42,880
like
12/02/12 04:34 PM (11 years ago)
Very well explained. Thank you. LA
 
GoNorthWest
buzztouch Evangelist
Profile
Posts: 8197
Reg: Jun 24, 2011
Oro Valley, AZ
1,000,000
like
12/02/12 09:59 PM (11 years ago)
Excellent sleuthing, @David! Nice that this is resolved now. Java is such a pain in the butt! Mark
 
ianJamesPiano
Code is Art
Profile
Posts: 2661
Reg: Feb 13, 2011
Palm Springs, C...
37,010
like
12/02/12 11:52 PM (11 years ago)
What a pain in @ss I am. At least not as much as Android!... Thanks for the hard work David. Ps. everyone. David does not sleep. no kidding. Helping me with my Android woes till the sun comes up!! Cheers and Well Wishes ian At least I have IOS v1.5 apps fully operational in Xcode 4.5 & IOS 6. I will be sending my findings to add t the How To sections:)
 
ATRAIN53
Code is Art
Profile
Posts: 1755
Reg: Nov 17, 2011
Chicago
26,450
like
12/03/12 07:45 AM (11 years ago)
So this nullpointerException is only occuring on 1.5 apps? I've never come across it, but all my Android apps are SH 2.0. plenty of other 2.0 Android bugs, but thankfully not this one it seems! On a birthday weekend too! David - Hope you are not too burned out, I just finished some cool plugins I was gonna submit this week! Just another great example of BT support that any future customers may not realize occurs.
 

Login + Screen Name Required to Post

pointerLogin to participate so you can start earning points. Once you're logged in (and have a screen name entered in your profile), you can subscribe to topics, follow users, and start learning how to make apps like the pros.