Office Hours — Today, October 5

Thursday, September 30

Oct 5
7:55 PM
Mark M.
has entered the room
Mark M.
turned on guest access
Darryl
has entered the room
Mark M.
howdy, Darryl!
Darryl
Good Evening!
Mike R.
has entered the room
Darryl
View paste
I am looking for some advice on how to design an application.  I have a connection to a bluetooth device which will be receiving data from the device at unknown times.  I will need to store the data it receives into a database for later retrieval but also for viewing during the data retrieval itself.

I will need an activity showing the data (in a listview of some sort).  Where I am getting hung up on is where to put the database connection.  Since I will need a landscape and portrait view, my activity could be destroyed at any time.  I suppose I could put the database connection in the service, which is running in the background, or in the application object itself.  Also, should I use a local or remote service?  Using AIDL seems to be a pain, but then again sending broadcasts to the activity also seems to be questionable at best.  

If you recommend a local service, how can I communicate from the service TO the activity reliably?
Mike R.
Hello
8:00 PM
Mark M.
howdy, Mike R!
Darryl: whole lotta questions there
Darryl
Sorry... I'm a little hung on on my application design.
Mark M.
:-)
Darryl
I thought I would come to the master for help!
Mark M.
yeah, well, you have a complicated scenario
Darryl
And BTW, the data collection from bluetooth is client driven. I understand the pitfalls of leaving something running in the background.
Mark M.
if the activity is on-screen, is the expectation that the service will also be running?
Darryl
Yes, I would think so.
Mark M.
then I'd go the route of keeping the database connection in the service
use the local binding pattern to allow the activity to ask the service for a Cursor representing whatever is needed
allows you to keep a single database connection and not have to worry about any sort of contention
whether you use AIDL or just the pure local binding pattern is up to you -- AIDL does not imply a remote service
though it tends to be used for that
Darryl
So then I would be showing an array list on the activity?
Mark M.
no
you'd be showing a Cursor
that you got from the service
when the service updates the database, you have your choice for who calls requery() on the Cursor and when
8:05 PM
Darryl
This is where I'm getting hung up. How can the service return, well, anything to the activity if they are separate?
Mark M.
via the local binding pattern
bindService()
gives access to an API exposed by the service
for async pushes, service -> activity, you can use a callback/listener object, or a broadcast, or createPendingResult()
or, in this case, the service could call requery() on the Cursor itself, if the service can arrange to do that on the main application thread
Darryl
Can the service and the activity be hitting the database at the same time? I.e., suppose some data comes in, and I tell my activity to update the list, and it starts to update but then more data comes in. So then I would have the service and the activity hitting the DB. Is that OK?
Mark M.
if you are using more than one connection, there could be issues
that is why I was recommending a single connection, held by the service
the activity asks the service, "yo, dawg, I wants a Cursor, yo"
the service does the query and hands back the Cursor
you could go the route of a ContentProvider for this, if you prefer
have the service and the activity both work off of the ContentProvider, which mediates the database
Darryl
Ah, more complexity...
Mark M.
yes, well, your scenario isn't precisely simple... :-)
8:10 PM
Darryl
When you mentioned about the service exposing an API, does that mean the activity can just call public methods defined in the service, or do I define specific methods in some way that get exposed via binding?
Mark M.
you create a Binder object, either just in Java code or via AIDL
the activity uses the Binder as the API
Darryl
And yeah, on the serface this seems simple until you break it down. OF course, getting the client to understand that is another matter.
Ah, OK.
Mark M.
this is covered in the service chapters of _The Busy Coder's Guide to Android Development_ and _The Busy Coder's Guide to Advanced Android Development_
Darryl
I will relook at those. In chatting here, it almost seems as though the ContentProvider may be the way to go.
Mark M.
it has its advantages
warning, though -- they're public by default
add android:exported="false" to limit access to your own process
(add that to the <provider> element in the manifest)
Darryl
Thanks for the warning!
Mark M.
let's swing over to Mike -- Mike, do you have a question?
Darryl
And also, thanks for your good books.
Mike R.
Back to diagnosing stack traces.
seems i'm getting a problem in this method:
View paste
	public void saveConfiguration() {
     	try {
    		FileOutputStream fileOut = openFileOutput( "config.ser", MODE_WORLD_WRITEABLE);
    		ObjectOutputStream out = new ObjectOutputStream(fileOut);
     		out.writeObject(config);
    		out.close();
    	}
    	catch (FileNotFoundException e) {
    		Log.d("Serialize Out", "File Not Found");
    		Log.e("Serialize Config", e.getLocalizedMessage());
    	}
    	catch (Exception e) {
    		Log.e("Serialize Out", e.getLocalizedMessage());
    	}
	}
getting a null exception in the last catch
says that println needs a message
Mark M.
huh?
8:15 PM
Mark M.
could you paste the stack trace, here or in a github gist or something?
Mike R.
sure thing
View paste (6 more lines)
ava.lang.RuntimeException: Unable to destroy activity {com.medpagetoday.medpage/com.medpagetoday.medpage.Channels}: java.lang.NullPointerException: println needs a message
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3874)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3924)
at android.app.ActivityThread.access$2900(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2169)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:144)
at android.app.ActivityThread.main(ActivityThread.java:4937)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
...
Mark M.
e.getLocalizedMessage() is returning null for some other exception
any particular reason you're using that, rather than just passing e?
Mike R.
not really
Mark M.
rather, passing e as the third parameter, and passing some other useful string as the 2nd?
Mike R.
could do that also
Mark M.
tough to tell what the actual crash is, at least from this trace
Mike R.
i just assumed that a system-generated exception would include a localized description
Mark M.
nice thought
Mike R.
as far as the actual crash, i think is has to do with one of my serialized objects
Mark M.
:: insert obligatory reference to "never assume" joke here ::
Mike R.
very nice
Mark M.
yeah, my guess is that you're blowing up in one of your serialization methods, but no good way from this trace to tell which
Mike R.
in looking at my code, one of the objects that I'm serializing could possilby have a reference to another object that's set to null
I'm guessing that's a no-no when it's time to serialize?
Mark M.
I haven't played with Java serialization in years and years
Mike R.
well, that's my guess anyway.
Mark M.
hence, I forget the rules
8:20 PM
Mike R.
i can pretty easily put a fix to make sure that reference is never null.
Mark M.
probably not a bad idea
Mike R.
but i'd rather not have to do this through trial and error
unless I have to :)
Mark M.
well, write a test case
Mike R.
ok. that sounds like a good idea. thanks.
that's it for me.
Mark M.
ok
Darryl: got another question?
Mike R.
has left the room
Darryl
No, not really.
Mark M.
ok
Darryl
If there is no one else, I was wondering one thing though.
Since you're pretty heavy into the Android community, why did they make the activities completely destroy themselves when rotating? IT seems to hang up a lot of people.
Myself included. :)
Mark M.
in part, to make absolutely certain you get the right resources (e.g., landscape layouts)
happens for all configuration changes, not just rotation (e.g., insert/remove from dock, change locale in Settings)
8:25 PM
Darryl
It just seems, well, unnecessarily destructive. I'm not saying other ways are better, just trying to understand why.
Thanks again for your help.
Darryl
has left the room
8:55 PM
Mark M.
turned off guest access

Thursday, September 30

 

Office Hours

People in this transcript

  • Darryl
  • Mark Murphy
  • Mike Renda