Office Hours — Today, November 2

Tuesday, October 26

Nov 2
3:20 PM
Mark M.
has entered the room
3:25 PM
Mark M.
turned on guest access
3:30 PM
Julius
has entered the room
Mark M.
howdy, Julius!
Julius
Good day
I hope you are well.
I have a couple of questions for you...
:)
Mark M.
fire away!
Julius
I'll fire away now (tw - I realloy enjoy reading the transcripts of these)
I have an Activity which takes photos and saves the files using an AsyncTask. Mt problem is that if I press the "button" (an ImageButton) twice in succession (ie. quickly) I get an ANR and the Camera is no longer accessible in any application unless I reboot the phone. Just wondering if you've seen this or might have some idea of things I could do to attempt to prevent this. The call back method is like this:
View paste
	Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {

		public void onPictureTaken(byte[] imageData, Camera c) {

			new SavePhotoAsyncTak().execute(imageData);
			mCamera.startPreview();
		}
		

	};
ooop Mt => My
Mark M.
where does the ImageButton come into play?
3:35 PM
Julius
The ImageButton is in the relativeLayout which has teh SurfaceView
Mark M.
right
Julius
it is pressed to start the Camera.takePhoto
Mark M.
but what does it do?
ah
Julius
View paste
		mTakePhotoImageButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// Take picture and pass callback to camera
				mCamera.takePicture(null, null, mPictureCallback);
			}
		});
(In some ways this seems really simple)
Mark M.
I would disable the ImageButton until after mCamera.startPreview()
Prasanna P.
has entered the room
Julius
Of course with your book it does :)
ah!
ok I'll try that - simple an sweet thank you
Mark M.
howdy, Prasanna!
Prasanna P.
Hey Mark!
In general is it best practice to do all HTTP request on background threads?
Mark M.
yes
Prasanna P.
I need to update my UI based on a result that I get from making an HTTP request. To do this, in the onCreate() of the UI thread I create and execute an Asynch Task. My question is do I need to ‘cancel’ this background thread and/or set the reference to this background thread to null in the onDestory() of the UI thread?
Mark M.
you never know how long one will take
Prasanna P.
ok got it
Mark M.
Canceling a background thread is sometimes difficult
Unless the download is huge, I'd just let it run to completion, but that's just me
if the onDestroy() is due to a screen rotation, though, you will want to pass the AsyncTask to the new instance via onRetainNonConfigurationInstance()
see the RotationAsync pattern I have in _The Busy Coder's Guide to Android Development_
I think that's covered now at the end of the threading chapter
or possibly the end of the rotation chapter
Prasanna P.
yes ... was looking at that ...
In RotationAsync example, in the onRetainNonConfigurationInstance() method, task.detach(); is called. What if the task has completed when the rotation is happening … will this cause an error since the task (background thread) is not longer active.
Mark M.
not possible
onPostExecute() will not be called until after onCreate() of the new activity
3:40 PM
Mark M.
so long as you do not attempt to access the activity from doInBackground(), you're OK
Prasanna P.
trying to follow you ....
Mark M.
once onRetainNonConfigurationInstance() is called, no messages will be processed off the main application thread's message queue until after onCreate() is called on the new activity instance
so, you detach the AsyncTask in onRetain...() and you attach it onCreate() of the new instance
during that time, onPostExecute() will not be called, because that is triggered via a message on the message queue
hence, even though the background thread itself may end, onPostExecute() will not be called
until you have reattached via onCreate(), that is
Prasanna P.
oh ok
Mark M.
Julius: did you have another question?
Julius
yes...
Is there a smart way (in terms of layouts) to make tutorial screens? For example the first time you start an application, sometimes there are a few screens with "Next" buttons. The idea is that you press Next to go from one screen to another.
Mark M.
you mean a wizard?
3:45 PM
Julius
yeah
Mark M.
for a wizard, I'd either use FrameLayout or ViewFlipper, above the Next/Prev buttons
each button would adjust the contents of the ViewFlipper as appropriate
when you get to the end, Next becomes Finish and moves on to the next activity, finish()ing the current one
Julius
ah ok I'm not familiar with FrmaLayout or ViewFlipper - I'll check it out
thank you
Mark M.
Prasanna: do you have another question
?
Prasanna P.
yes
so let's day you are not downloading anything huge in the background thread ...
and you are not canceling it in the onDestroy of the UI thread ...
what happens to it after it is complete?
ie what happens to the background thread
Mark M.
it's part of a thread pool managed by Android
Prasanna P.
will it be garbage collected?
Mark M.
you do not have to worry about the AsyncTask threads
Android handles all of that for you
in fact, that's one of the main benefits of AsyncTask
3:50 PM
Prasanna P.
got it. Thanks
heading out Mark. As always thanks a lot for your help!
Mark M.
see ya!
Julius: any more questions?
Julius
:) well if you don't mind...
Regarding the orientation changes - if I have an activity which is not dependent on the orientation (or configuration) is there anything wrong with using ' android:configChanges="orientation|keyboardHidden" ' in the description of the Activity in the Manifest?
it seems to stop onDestroy / onCreate from occurring
Mark M.
well, that depends on who you ask
oh, it does
Google would really really really prefer you not use it except in specialized cases
for example, your camera activity is a good one for that pattern
Julius
oh ok.. <blush>
Mark M.
however, for garden-variety activities, they would rather you use onSaveInstanceState(), because that is applied in other case
er, cases
for example, if you get kicked out of RAM but are still part of an active task, onSaveInstanceState() allows the user to BACK-button their way back to you, and your activity will be recreated with your state
Julius
what are the benefits of using saving state, destroying everything and creating it all again?
Mark M.
looks to the user (more ore less) like you have never been gone
there are also a continuing series of configuration changes, like the new car dock and desk dock configurations
unless you are going to commit to ignoring all of those, you will still need onSaveInstanceState()/onRetainNonConfigurationInstance()
and, Google is nervous that you'll forget about necessary changes (e.g., locale changes needing your new string resources)
3:55 PM
Mark M.
onSaveInstanceState() is a Volvo, android:configChanges is a convertible
Julius
I'm not sure I understand... if I put the phone in the dock say - how would that affect my application?
heheh
Mark M.
your activity will be destroyed and recreated
it's a configuration change
Julius
right
Mark M.
orientation, language, car dock, desk dock -- all configuration changes
Julius
so basically I need to store any important info and pass it back
how do you mean with language?
eg...
Mark M.
user is working with your app, presses HOME, goes to Settings, changes their locale, long-presses HOME, returns to your app
Julius
oh I see
right
Mark M.
your activity will be destroyed and recreated so you pick up the new string resources
Julius
so I have set up my languages correctly
Mark M.
admittedly, that's an unlikely csae
er, case
Julius
which is al good in the app but the user won't see the changes
Mark M.
right
Julius
until restarting the activity
Mark M.
now, you could do android:configChanges and simply reload all of your string resources in onConfigurationChanged()
Google is worrying that you'll miss some
Julius
currently I have to admit I've been a little slack in this area
I guess I've taken the easy route
btw I have to thank you for at some point writing soewhere one should look at AsyncTask. It's the best thing since sliced bread
Mark M.
AsyncTask is very cool for things that should end in a reasonable period of time
wouldn't use one to maintain a chat connection, where we have no idea when the user will end the chat
Julius
yeah oh and the Wakeful service
that's brilliant
4:00 PM
Julius
I've used that with a couple of Alarms
Mark M.
both represent places where we're building higher-level components on top of underpinnings
Prasanna P.
has left the room
Julius
for updating something once a day or every 5 mins
Mark M.
AsyncTask started from some code Romain Guy wrote for his Shelves sample app, and got moved into the framework
Julius
wow I dont' know what I'd do without it
he seems like a nice chap
Mark M.
Romain is extremely talented
Julius
I was hoping he'd be at the google event in Sydney, but alas no (I was going to see if I could get him over to the android group in Auckland)
Mark M.
yeah, those sorts of events are mostly covered by the developer evangelists, like Tim Bray and Roman Nurik
Julius
o I had another question
Mark M.
go ahead -- you're the only one here right now
Julius
I often need to get a location quickly and the location is by nature always out of date. I seem to have trouble with this. I have a situation where I need to change the frequency of location updates.
I'd like to show you what I'm doing and see if there's any way I could either get the location more quickly.
Mark M.
um, ok
not sure what can really be done
4:05 PM
Mark M.
you might consider using gist.github.com or a similar code paste site, and putting the link here, if you want to share significant code
Julius
View paste
if(mAdminSettings.getBoolean("admin_pref_gps_enabled", true)) {

			mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, intervalInMillis, distanceInMetres, mLocationListener);

			locating.set(true);

			if (!mLocationManager.isProviderEnabled( LocationManager.GPS_PROVIDER)) {
				setGPSDisabled(true);
				locating.set(false);
			}

		} else {
			setGPSDisabled(true);
		}
	}
hopefully not too much
then to stop:
View paste
		if((null!=mLocationListener)&&(null!=mLocationManager)) {
			mLocationManager.removeUpdates(mLocationListener);
		}
		locating.set(false);
Mark M.
well, I don't see anything particularly wrong with what you have
what specifically is your concern?
Julius
The location seems to be incorrect from time to time and it sorta needs to be up to date...
but I dont' want the GPS on all the time
Mark M.
um, not sure what you can do about that
Kevin M.
has entered the room
Mark M.
it takes a while just to start getting GPS fixes
Kevin M.
Hello
Julius
no problem at least it looks right thank you
Mark M.
unless your app will be on for a few hours, you may be better off just leaving GPS on
howdy, Kevin!
Kevin M.
Howdy
Julius
thank you
bfn
Mark M.
Kevin: do you have a question?
4:10 PM
Julius
has left the room
Kevin M.
What's the best way to handle a service if you want to send it messages and you don't want the service to die until it's done?
Mark M.
use an IntentService
perhaps also use startForeground(), like the Android Market does to indicate it is downloading
Kevin M.
Can I keep sending it info while it's running?
Mark M.
sure
IntentService queues up the Intents you send it via startService()
processes them one at a time on a background thread
automatically shuts down when the queue is empty
Kevin M.
Ah, I thought I had to bind to the service
Mark M.
nope
IntentService works great with the command pattenr
er, pattern
stuff your data in Intent extras and shoot it over via startService()
Kevin M.
Great
We talked last week about an Activity's lifecycle and different parameters
I'm still not that sure about how to set up an activity
I found out that pressing the recent menu item always goes to the first activity
4:15 PM
Kevin M.
There's the singleTop and SingleTask types
Mark M.
yeah, I haven't played with the recent menu much
Kevin M.
Right now, I have to keep track of the current activity in the application object
Then go to it when the main activity gets called
Mark M.
seems like that should not be needed, but I have no concrete advice on how to avoid it
Kevin M.
Is there are general rule about activity settings?
Mark M.
I am not sure what you mean
Kevin M.
I current have the main activity set as a SingleTask, other activities in between don't have anything and the top activity is a singletop
4:20 PM
Mark M.
Google doesn't recommend the use of singleTask very much
Kevin M.
My purpose is to make sure that when the user returns to the app, the same activity is shown
It seems in 2.2 that Android kills off regular activities really quickly
Mark M.
personally, I'd just let the recent activities do whatever it does
stuff like singleTask are for fairly specialized activities, like search activities
Kevin M.
Not a very good experience. Usually it takes you back to the main screen
Mark M.
really?
Gmail returns you to the activity you were on
Kevin M.
Maybe it's the singleTask setting
4:25 PM
Mark M.
mixed bag: Contacts doesn't remember
what I'd do is find an app that behaves the way you want, and try to mimic its settings
Gmail, of course, is not open source, so that's not a good example
Kevin M.
How about listview selection colors? I tried doing this and haven't got it to work
Mark M.
what about ListView selection colors?
Kevin M.
Didn't you do this in your book? I tried following an example and couldn't get it to work
Mark M.
there are examples of playing around with ListView selection, yes
in the Advanced Android book
4:30 PM
Kevin M.
I copied over the resources
and changed the images
Mark M.
um, the chat is about over
can we pick this up another time?
Kevin M.
Sure
Mark M.
ok
have a pleasant day!
Kevin M.
has left the room
Mark M.
turned off guest access

Tuesday, October 26

 

Office Hours

People in this transcript

  • Julius
  • Kevin Moroe
  • Mark Murphy
  • Prasanna Perera