Mar 6 | 9:50 AM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Mar 6 | 10:05 AM |
Dusan | has entered the room |
Mark M. |
hello, Dusan!
|
Mark M. |
how can I help you today?
|
Dusan |
Hi
|
Dusan |
I am dealing here with some legacy code and I am applying wakefulServices...
|
Dusan |
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
|
Mark M. |
an IntentService should not be spawning another thread
|
Mark M. |
whether that is a regular IntentService or WakefulIntentService
|
Mark M. |
once you return from onHandleIntent(), if there is no more work to be done, the IntentService will stopSelf()
|
Mark M. |
which means you will leak that thread
|
Mark M. |
and there may be nothing telling Android to keep your process around doing work
|
Mark M. |
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
|
Dusan |
so yea...it is like I thought
|
Mar 6 | 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 :)
|
Dusan |
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?
|
Mar 6 | 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
|
Mark M. |
let me take questions from the others, and I will be back with you in a bit
|
Mark M. |
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.
|
EGHDK |
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
|
Mark M. |
that's a fine question
|
Mark M. |
let me peek at the code for a moment -- hold on
|
Mar 6 | 10:20 AM |
Mark M. |
probably what I have in the non-acl version is right
|
Mark M. |
to be honest, I'll be discontinuing this project soon
|
Mark M. |
once I move some SQLCipher code over to my CWAC-Security project
|
Mark M. |
I never use loaders, outside of a couple of book examples
|
Mark M. |
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?
|
Mark M. |
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
|
Mark M. |
AlarmManager for a monthly alarm is where I have heard complaints
|
Mar 6 | 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
|
Mark M. |
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"?
|
Mark M. |
can you create a library? yes
|
Mark M. |
can you put classes in a library? yes
|
Mark M. |
can you put a BroadcastReceiver in a library? yes
|
Mark M. |
can you put a service in a library? yes
|
Mark M. |
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
|
Mark M. |
that message's date is May 23, 2032
|
Mark M. |
in theory, it is a waste to check every day for the next ~18 years
|
Mark M. |
in theory, you'd set an alarm event to get control on May 23, 2032, at 8am
|
Mark M. |
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?
|
Mar 6 | 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!"
|
EGHDK |
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
|
Mark M. |
CursorLoader is a client of a ContentProvider
|
Mark M. |
CursorLoader replaces managedQuery()
|
Andrei R. |
Ups, I mixed them up, sorry :-)
|
Mark M. |
no problem
|
Mark M. |
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
|
Mar 6 | 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
|
Mark M. |
onReceive() is not in your app
|
Mark M. |
it is in your library
|
Mark M. |
as your BroadcastReceiver is in your library
|
Dusan |
yes
|
Dusan |
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
|
Mark M. |
the BroadcastReceiver does not exist beyond the onReceive() call
|
Mark M. |
so there is no way to configure the instance at runtime
|
Dusan |
aha
|
Dusan |
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)
|
Mark M. |
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
|
Mark M. |
this is covered in the chapter on AlarmManager in the book
|
Mark M. |
rather than doing your event at 8am on the dot, it may shift it by some amount of time
|
Mark M. |
since you are looking to give user control over that, you cannot support the inexact behavior
|
Mark M. |
which will require more work on your part for Android 4.4+
|
Mark M. |
again, covered in the AlarmManager chapter in the book
|
Mar 6 | 10:40 AM |
Mark M. |
EGHDK: do you have another question?
|
EGHDK |
Okay, thanks. Thats helpful.
|
EGHDK |
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
|
Mark M. |
it depends a bit upon what you're doing with the thread
|
Mark M. |
and whether you are using Service, IntentService, or something else as your base class
|
EGHDK |
I'm using a Service
|
EGHDK |
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.
|
EGHDK |
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
|
Mark M. |
er, class
|
Mark M. |
IntentService is a subclass of Service
|
EGHDK |
IntentService extends service
|
EGHDK |
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.
|
Mar 6 | 10:45 AM |
EGHDK |
So if I go ahead and make an intentService... I dont have to create a new thread?
|
Mark M. |
correct
|
Mark M. |
just put your code in onHandleIntent()
|
Mark M. |
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
|
Mark M. |
you send a command to the IntentService via startService()
|
EGHDK |
Intent i = new Intent(this, MyIntentService.class) startService(i);?
|
EGHDK |
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
|
Mark M. |
Andrei: do you have another question?
|
Andrei R. |
View paste
|
Mark M. |
no, the Cursor will not close automatically, other than when it gets garbage-collected
|
Mark M. |
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
|
Mark M. |
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?
|
Mar 6 | 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)
|
Andrei R. |
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
|
Mark M. |
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.
|
Andrei R. |
No more questions from me. Thanks a lot!
|
Mark M. |
you are very welcome!
|
Mar 6 | 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
|
Mark M. |
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
|
Mark M. |
I had never heard of that before now
|
Mar 6 | 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
|
Mark M. |
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
|
Mark M. |
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
|
Mark M. |
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. | |
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
|
Mar 6 | 11:05 AM |
EGHDK |
Aha.
|
Mark M. |
plus there's a JAR there in downloads on Google Code
|
Mark M. |
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
|
Mark M. |
next one is Monday at 7:30pm US Eastern Time
|
Mark M. |
the transcript will be posted to http://commonsware.com/office-hours/ shortly
|
Mark M. |
(barring upload problems from this hotel room...)
|
Mark M. |
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 |