0

In my updateGUI() function I update each TextView like so:

((TextView) findViewById(R.id.lbTrackerLat)).setText(String.valueOf(lat));
((TextView) findViewById(R.id.lbTrackerLong)).setText(String.valueOf(lng));
((TextView) findViewById(R.id.lbTrackerAlt)).setText(String.valueOf(alt));

When I call updateGUI() from the press of a button with the onclick assigned in the onCreate, the update ALLWAYS works.

I have a locationListener that's started when the user clicks another button, and on every update event I call updateGUI() there as well, which works until the screen is first rotated, after which the screen is not refreshed for some reason.

While trying to figure out why, I've added this code to the updateGUI() function:

TextView t = (TextView) findViewById(R.id.lbTrackerPostLastRefresh);
t.setText(formattedDate);
Log.d("H","EXIT  lbTrackerPostLastRefresh="+t.toString());

After rotation (onCreate is called again), when it's called from the button click, I get 44c76a78 as the pointer. When the locationListener update function calls findVIewByID, the pointer 44c1b518 is returned!!??

I get that the layout is destroyed and recreated, but why is findViewById returning old pointer values??

Spitballing: It's as if the first instance of the View starting with the initial onCreate continues merrily on (along with it's resources) even after a new View as been instantiated when the device was rotated. Perhaps the LocationListener is doing this because I haven't stopped it. But stopping and starting it every time the device is rotated seems stupid!

Hein du Plessis
  • 3,305
  • 6
  • 34
  • 51
  • cant you use t.getText();, try clean project and re-run? – Mohammed Azharuddin Shaikh Apr 14 '12 at 07:50
  • Why is that important for you that the id changes? Does findViewById() return different controls? – rekire Apr 14 '12 at 07:52
  • @hotveryspicy I'm trying to write to the TextView's label. – Hein du Plessis Apr 14 '12 at 07:56
  • @rekire The ID stays the same. The pointer to the TextView control changes. – Hein du Plessis Apr 14 '12 at 07:56
  • For initializing your locationManager, are you using your Activity context or your Application context? Try and always use your application context. Try this change and tell me if it works. If it does, then I'll provide the explanation. – Shubhayu Apr 14 '12 at 08:28
  • @Shubhayu Sorry - how do I specify the Application context when initialising the locationManager instance? I normally use this.getSystemService, I've left out the this. bit but still no luck. – Hein du Plessis Apr 14 '12 at 12:11
  • try getApplicationContext().getSystemService(). – Shubhayu Apr 14 '12 at 12:45
  • Hi yes I've just discovered it. I've spent the last hour trying to encapsulate my location code into a seperate class, but ran into problems. I'm now using: locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); I do this: myLocationListener = new MyLocationListener(); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, updateMS, updateM, mylocationListener); How can I make sure the old activity gets freed, while still being able to access the old myLocationListener in the new activity? (sorry comments ignore CR) – Hein du Plessis Apr 14 '12 at 13:29
  • @Shubhayu perhaps I should write a service, like this gent had to having a similar problem: http://stackoverflow.com/questions/2939896/how-to-handle-activity-life-cycle-involving-sockets-in-android – Hein du Plessis Apr 14 '12 at 13:32
  • Why don't you try something like this? In your onPause() stopTracking(). This will close your locationManager and remover locationListener. Then in onResume() create your locationManager and startTracking() again. – Shubhayu Apr 14 '12 at 15:46
  • @Shubhayu Thanks, thought about that - but I'm worried it will affect the performance of the tracking. Would it help if I spawn it in a handler thread? – Hein du Plessis Apr 16 '12 at 07:22
  • Actually it is generally recommended that you free your resources a the time of onPause(). If you are worried about performance hit, in case you do not have a separate layout as such for your landscape mode, you could avoid recreating your layout when you change your orientation. Would you recommend that for your case? – Shubhayu Apr 16 '12 at 07:39
  • I'm running into the same problem as you did. How did you manage to solve this thing? Check http://stackoverflow.com/questions/24180148/layout-not-refreshing-after-orientation-change – MaiOM Jun 12 '14 at 10:21

1 Answers1

1

I am guessing that locationListener is an anonymous inner class of an Activity, which means that it holds a reference to its parent class. So now if this locationListener is not recreated after the onCreate() call, it will reference the old Activity, and a call to findViewById() will return objects hold by that old Activity. Not only will this cause your program to perform incorrectly, but causing memory leaks as well (basically everything created by the original Activity will be retained).

If the above is not the cause, then I'll need more information regarding locationListener and how it is used in order to help.

Kai
  • 15,284
  • 6
  • 51
  • 82
  • Thanks Kai - was thinking the same but not sure how to get around it. Good insight. Checking it out... – Hein du Plessis Apr 14 '12 at 08:09
  • I don't think I can figure out the right way to do it. The source for the activity is here: www.cde.co.za/shared/DroneMateActivity.txt It's quite simple. You'll see I've declared both locationManager and locationListener in the class, but I instantiate them with anonymous inner classes. Not sure what's the right thing to do here. – Hein du Plessis Apr 14 '12 at 08:27
  • I can't figure out what to do, at a bit of a loss. – Hein du Plessis Apr 14 '12 at 12:10
  • Do you really need to setContentView in onConfigurationChanged? Try remove it and see if it helps. – Kai Apr 16 '12 at 16:25