Office Hours — Today, March 6

Monday, March 3

Mar 6
9:50 AM
Mark M.
has entered the room
Mark M.
turned on guest access
10:05 AM
Dusan
has entered the room
Mark M.
hello, Dusan!
how can I help you today?
Dusan
Hi
I am dealing here with some legacy code and I am applying wakefulServices...
I have IntentService, which has (inside the code) new Thread. Now my question is...if I change IntentService to WakefulService, will wake lock also apply on that thread inside that service? (I suppose not)
Mark M.
your existing code sounds like it has a bug
an IntentService should not be spawning another thread
whether that is a regular IntentService or WakefulIntentService
once you return from onHandleIntent(), if there is no more work to be done, the IntentService will stopSelf()
which means you will leak that thread
and there may be nothing telling Android to keep your process around doing work
that being said, the WakeLock definitely will not be maintained for that separate thread if you use WakefulIntentService
Dusan
yea...I thought so. I am just applying this things on code some other guy wrote
so yea...it is like I thought
10:10 AM
Mark M.
if you have another question, go ahead -- there's nobody else in the chat room at the moment
Dusan
I can find one :)
So...I am implementing wakeful service
EGHDK
has entered the room
Mark M.
(hello, EGHDK -- be with you shortly!)
Andrei R.
has entered the room
Mark M.
(hello, Andrei -- I will be with you shortly!)
Dusan
and I created library with files (wakefulIntentService and alarmReceiver) and one AlarmHelper. From my app now I just want to call AlarmHelper.scheduleAlarm(intent that needs to be done)
Andrei R.
Hello
Dusan
is there a simple way of doing this?
Mark M.
doing what?
10:15 AM
Dusan
or go ahead...talk with others, I little complicated things :)
Mark M.
if AlarmHelper is a class in your library, and the library is available to your app project, you should be able to call static methods on it, if that is what you mean
let me take questions from the others, and I will be back with you in a bit
EGHDK: do you have a question?
EGHDK
Hey Mark. Two questions today. First, do you know if there is some chart that shows different priority for things in Android. Such as activities and services. I've been reading a ton about services the past week, and I keep learning more and more of what makes a service less likely to be "killed" off. I was just wondering if there was a go to chart or something.
Mark M.
EGHDK
Also, the service class has me extremely confused. But thats just a statement. Not a question. hah.
Thanks!
Mark M.
Andrei: your turn -- do you have a question?
EGHDK
I'll ask my second question when you make your way around again.
Andrei R.
View paste
Hi, I wanted to use your cwac-loaderex library. Why are the acl and non-acl constructors for SQLCipherCursorLoader different? 1) The acl version does not take any password, and 2) the non-acl version 
takes a SQLiteOpenHelper as a second parameter instead of SQLiteDatabase (acl version)
Mark M.
that's a fine question
let me peek at the code for a moment -- hold on
10:20 AM
Mark M.
probably what I have in the non-acl version is right
to be honest, I'll be discontinuing this project soon
once I move some SQLCipher code over to my CWAC-Security project
I never use loaders, outside of a couple of book examples
they're fine with a ContentProvider, but the Loader abstraction does not work well with anything else
Andrei R.
I see, thanks. I have other questions as well but I'll wait for others to ask another round of questions.
Mark M.
Dusan: do you have another question?
EGHDK: do you have another question?
EGHDK
I have an App right now that when you open it up, it checks the current date, and if the date matches up with a date in my local DB, it will show a textView with the "message" associated with that date. It works perfectly. What I want to do now, is convert this into something that runs every day at a certain time. I guess I will settle on 8am. How would I do this? I know I asked you about alarms once, and you said that you've heard of alarms being set way in the future could fail. So how would you accomplish that at 8am every day, my app would trigger, do the DB search, and set a notification?
Mark M.
AlarmManager for a daily alarm should be fine
AlarmManager for a monthly alarm is where I have heard complaints
10:25 AM
Mark M.
even better would be to not check at 8am
Dusan
I reformed my question: I want to put wakeful things + BroadcastReceiver into a separate library. So that in my app I would not need to implement BroadcastReceiver that starts WakefulService. From my app I would then just call for example: AlarmHelper.scheduleAlarm(intent for starting WakefulIntentService)". Is this possible?
Mark M.
but instead set the alarm based on the details in the message
but if you are anticipating messages with dates far in the future, then the daily alarm is probably safer
EGHDK
Can you elaborate from "instead set the alarm based on the details in the message"?
Mark M.
Dusan: I still do not know what "this" is in your question "is this possible"?
can you create a library? yes
can you put classes in a library? yes
can you put a BroadcastReceiver in a library? yes
can you put a service in a library? yes
frankly, I don't see what you're adding in your library that isn't already in mine, but I suspect that's because I am not understanding your situation very well
Dusan
Yea...sometimes I really complicate things. I'll work some more on that and if I'll have more specific question, then I'll come back.
Mark M.
EGHDK: suppose your database contains one message
that message's date is May 23, 2032
in theory, it is a waste to check every day for the next ~18 years
in theory, you'd set an alarm event to get control on May 23, 2032, at 8am
in practice, that doesn't work so well
EGHDK
Gotcha. I probably have 3 messages every month. That should work out alright by checking everyday... right?
10:30 AM
Mark M.
your battery drain should not be a major problem, if that's what you mean
EGHDK
Yeah. I guess thats what I'm getting at.
Mark M.
just make sure that you follow the coding rule outlined by an old Chili's commercial: "get in, get out, get on with life" :-)
EGHDK
I don't want users to be like "Hey your app is so small, but taking up this much of my battery according to Android!"
Also, as a side note, I'd like for the user to specify a time to set off the alarm. So the user could get the notification at 8, and then the next day just go in the app and say, I think 10am is better for me. You still think AlarmManager is fine for this?
Mark M.
sure, just cancel the 8am one and schedule a 10am one
EGHDK
I guess there is a way to deregister the 8am. okay cool
Mark M.
note that the AlarmManager events default to being "inexact" on Android 4.4
EGHDK
Thanks mark
Mark M.
Andrei: do you have another question?
Andrei R.
I'm a bit surprised about your earlier comment on Loaders. I thought Loaders were supposed to (more or less) replace ContentProviders, at least in some contexts, as they can work in background, whereas ContentProviders can't. Has this trend changed?
EGHDK
What's that mean "inexact". If that doesn't take too long to answer?
Mark M.
Loaders do not replace ContentProviders
CursorLoader is a client of a ContentProvider
CursorLoader replaces managedQuery()
Andrei R.
Ups, I mixed them up, sorry :-)
Mark M.
no problem
Dusan: do you have another question?
Dusan
Ok, one more question. I have broadcastReceiver in my library. Can I set Intent which will be executed in method onReceive from the App (which is using the library)?
Mark M.
by "library", do you mean a JAR, or an Android library project?
Dusan
JAR
10:35 AM
Mark M.
then your app that uses the JAR will still need to have the <receiver> element in it, pointing to your BroadcastReceiver in the JAR
Dusan
yes...I know that
Mark M.
Android library projects offer some amount of "manifest merging", though I haven't experimented with that just yet
Dusan
ok
Mark M.
then I guess I do not understand what "set Intent which will be executed in method onReceive from the App" means
onReceive() is not in your app
it is in your library
as your BroadcastReceiver is in your library
Dusan
yes
method of broadcastReceiver in library
Mark M.
if by "executed in method onReceive", you mean that you are referring to some other Intent that will be used with startService() or something, then that'll be a problem
the BroadcastReceiver does not exist beyond the onReceive() call
so there is no way to configure the instance at runtime
Dusan
aha
thats what I meant yes
Mark M.
in a pinch, you could do something icky with a custom Application subclass
Dusan
thanks
Mark M.
assuming that the Application subclass can create the Intent without any other prior data (since it may be newly created for a new process)
EGHDK: by "inexact", I mean that Android wants to schedule your event to coincide with others, so it has to wake up the device fewer times
this is covered in the chapter on AlarmManager in the book
rather than doing your event at 8am on the dot, it may shift it by some amount of time
since you are looking to give user control over that, you cannot support the inexact behavior
which will require more work on your part for Android 4.4+
again, covered in the AlarmManager chapter in the book
10:40 AM
Mark M.
EGHDK: do you have another question?
EGHDK
Okay, thanks. Thats helpful.
I am starting a service from a class of mine. I saw that a service will run on the main ui thread, so I have to create my own thread. Where would I actually do this? Inside the service? Or create a new thread in my activity and start the service in it?
Mark M.
from onStartCommand() of the service, most likely
it depends a bit upon what you're doing with the thread
and whether you are using Service, IntentService, or something else as your base class
EGHDK
I'm using a Service
not an IntentService
Mark M.
and what is the role of the thread?
EGHDK
Basically, I'm doing a check in with my server. The check "starts" when the user is in the app and hits refresh. But if the user leaves, or has a really slow connection, I want the check to continue.
So I need the thread, so that the Service doesn't run on the main ui thread.
Mark M.
that sounds like a job for IntentService, which gives you a background thread "for free"
EGHDK
Oh!
Mark M.
if you don't want to use IntentService, this sounds like you should be forking your thread from onStartCommand()
EGHDK
I didn't know that.
Dusan
has left the room
EGHDK
Okay, intentService and service still have me confused.
Mark M.
Service is a Java clas
er, class
IntentService is a subclass of Service
EGHDK
IntentService extends service
yeah
Mark M.
IntentService implements one particular pattern for operating a Service
EGHDK
But I'm not sure what IntentService was made. One particular pattern? What pattern is this?
Mark M.
specifically, for things that feel "transactional" (disk I/O, database I/O, Web service calls, etc.), IntentService is probably the right answer
EGHDK
gotcha.
10:45 AM
EGHDK
So if I go ahead and make an intentService... I dont have to create a new thread?
Mark M.
correct
just put your code in onHandleIntent()
IntentService will call that method on a background thread
EGHDK
Great. And then I start it just like any other service?
Mark M.
and, when you return from onHandleIntent(), the IntentService will stopSelf() and go away
you send a command to the IntentService via startService()
EGHDK
Intent i = new Intent(this, MyIntentService.class) startService(i);?
oops semicolon missing.
Mark M.
yes
EGHDK
Thanks. That's very helpful.
Mark M.
optionally, you can stuff some extras on the Intent, if you need to pass some data to the service
Andrei: do you have another question?
Andrei R.
View paste
Yes. In my DatabaseHelper I want to see if a column from my database table contains a value. Is this code ok?

return getDb(context).rawQuery("SELECT COUNT(*) FROM myTable WHERE Column1 = ?;", arg).moveToFirst();

My concern is that we return from the function without closing the cursor. Does the cursor closing happen automatically?
Mark M.
no, the Cursor will not close automatically, other than when it gets garbage-collected
you'll probably get warnings for this code at runtime in LogCat, complaining about not closing the Cursor
Andrei R.
I see. Then I first need to get the result, then close the cursor, then return the result
Mark M.
right
if anyone has any questions, go ahead
Andrei R.
Just a small observation on the chatroom page, FYI: The "Enter chatroom" button was not visible in the Opera browser. I had to log in from Chrome.
Mark M.
which version of Opera? and on which OS?
10:50 AM
Andrei R.
Win 7 64bit, Opera 12.16
Mark M.
OK, I'll see if I can fix that sometime -- thanks!
Andrei R.
(the "old" Opera)
and the "Logout" button for commonsware did not work in Chrome (maybe related to Chatroom hours?)
Mark M.
worked for me just now
EGHDK
A few weeks ago I had a terrible comprehension of static variables. I read some more of my book, and statics make total sense now. But they didn't say what to do to get rid of statics. How would I go about unloading a class/What is the best way to let go of statics though? Just set it = null?
Andrei R.
I initially switched a few times between Opera and Chrome and I was surprised to see I was still logged in in Chrome. I tried the Logout button a few times but I was still logged in after that,
Mark M.
EGHDK: if you are trying to allow an object to be garbage-collected, that is being referenced from a static data member, set the static data member to null
Andrei: ::shrug:: just tried it on Chrome and Chromium on Linux, no problems
Andrei R.
No pb from me, just wanted to mention those two minor points.
No more questions from me. Thanks a lot!
Mark M.
you are very welcome!
10:55 AM
EGHDK
Had this error I posted last night on SO. Have no idea why my SVG isn't showing on a few devices. Like 1 or two devices out of 100. http://stackoverflow.com/questions/22213767/svg...
Mark M.
that URL should work on zero devices
where is this SVG file?
EGHDK
raw
Mark M.
well, file:///android_res is undocumented
EGHDK
res/raw to be exact
Mark M.
I would not be surprised if not all devices support it
EGHDK
Heh. How the heck did I get that in there.
Mark M.
probably from other SO answers you used as a basis
I had never heard of that before now
11:00 AM
EGHDK
So how to you think I should show an svg in my app? Create a local web html doc? I'd probably have to use the raw directory anyway.
Mark M.
I'd try an asset first, as file:///android_asset *is* documented
or, read in the asset into a string and pass it in via loadData() with the right MIME type for SVG, though that will be more memory-intensive
however, it's also possible that your problem has nothing to do with android_res and is due to some other quirk in WebView on those devices
EGHDK
Hm... I think it's a pretty big file, so I want to use less memory, but also "load" it in a way that's documented.
Mark M.
there are also SVG libraries available that skip WebKit
EGHDK
I use custom fonts in the same app, and I use TypeFace.createFromAsset()
Mark M.
a 2.7MB SVG is one whopping big SVG
don't know that I've ever seen one that large
EGHDK
Mark, I looked and couldn't find anything that worked. Guess I didn't look hard enough? I'd appreciate it if you could point me in the direction of an SVG library that you know of.
Mark M.
EGHDK
Okay, so don't hate me, but I never know how to pull down the code form code.google.com. Its not like github =/
Mark M.
well, svg-android has moved to https://github.com/pents90/svg-android
11:05 AM
EGHDK
Aha.
Mark M.
plus there's a JAR there in downloads on Google Code
there's a downloads link for androidsvg as well
EGHDK
Victory. I really appreciate it. This will definitely allow me to ship a more usuable product. Thanks mark.
Mark M.
on the left-hand list of links off the project home page
EGHDK
Saved the day. Once again.
Mark M.
and that's a wrap for today's chat
next one is Monday at 7:30pm US Eastern Time
the transcript will be posted to http://commonsware.com/office-hours/ shortly
(barring upload problems from this hotel room...)
have a pleasant day!
Andrei R.
Thanks, you too!
EGHDK
has left the room
Andrei R.
has left the room
Mark M.
turned off guest access

Monday, March 3

 

Office Hours

People in this transcript

  • Andrei Rares
  • Dusan
  • EGHDK
  • Mark Murphy