Jul 15 | 7:20 PM |
Mark M. | has entered the room |
Jul 15 | 7:25 PM |
Mark M. | turned on guest access |
EGHDK | has entered the room |
ming | has entered the room |
Mark M. |
hello, EGHDK and ming!
|
EGHDK |
I have an application that has a user login. Once you login, you get a registration token to signify your session is logged on. I'm doing this in activity A. I have a setting in the app that lets the user select when it will lock them back out. From 1 minute to 1 day. So if the setting is set to 1 minute, and the user leaves, and then comes back within 50 seconds, the user is not prompted for a password. But if the user leaves and comes back after 70 seconds they are prompted with a password. The problem is that an activity can be killed and I'd like to save the session in something a little more longer lasting. I realize that the process can be killed whenever by the OS, but I was thinking maybe just saving the session in the application class would do the trick.
|
ming |
hi
|
Mark M. |
EGHDK, you narrowly got in first according to my chat log, so you get first shot
|
Mark M. |
(ming: I'll be with you in a bit)
|
Mark M. |
"but I was thinking maybe just saving the session in the application class would do the trick" -- no, because that goes away when your process does
|
Mark M. |
if you want something persistent, save it in a persistent store: a file, SharedPreferences, or a database
|
EGHDK |
I'm not looking for persistance. I'm looking for the best option while the process is alive and well.
|
EGHDK |
So I thought I could save the session in a service, but... that kind of doesn't make sense to me.
|
Mark M. |
then what specifically do you mean by "an activity can be killed"?
|
Mark M. |
do you mean being destroyed via the BACK button?
|
EGHDK |
Well, an activity would be killed faster than a service?
|
EGHDK |
if memory was needed
|
Mark M. |
activities are not "killed" if memory was needed
|
Mark M. |
processes are killed if memory was needed
|
EGHDK |
No I don't mean destroyed via the back button.
|
EGHDK |
Hmm,,, so lets say I had activity A B and C. And I traversed through A and B to get to C. A and B wouldn't get killed by anything?
|
Jul 15 | 7:30 PM |
Mark M. |
not unless you call finish() on them
|
EGHDK |
Really?
|
EGHDK |
I thought once you call onStop on an activity its eligible to be killed...
|
Mark M. |
that's not surprising you think that, as I thought that too for a while
|
Mark M. | |
Mark M. |
while I take ming's first question, and I'll be back with you in a bit
|
Mark M. |
ming: do you have a question?
|
ming |
my question is about expandablelistview
|
ming |
i have a long list of expandable items(parents) and each parent has 7~8 children items
|
ming |
I find it very slow to load, so I am wondering what is the best pattern here
|
Mark M. |
did you use Traceview to determine exactly where your problem is?
|
ming |
data is pulled from server if cannot be found in database
|
ming |
no I haven't yet since I do not know how to use it
|
Mark M. |
there's a chapter on Traceview in the book
|
Mark M. |
I'd start there
|
Mark M. |
and see what Traceview tells you
|
ming |
ok ill look into that
|
EGHDK |
ming I recently tried traceview and it helped me find my bottleneck. It's a little intimidating, but helpful.
|
Mark M. |
yes, Traceview isn't the most user-friendly tool out there
|
Jul 15 | 7:35 PM |
Mark M. |
but it's really helpful for problems like this
|
Jul 15 | 7:35 PM |
Mark M. |
EGHDK: your turn -- do you have another question
|
Mark M. |
?
|
EGHDK |
Mark M, I usually just put logs everywhere also, and watch log cat, and that usually gives me an idea of whats the bottleneck.
|
ming |
oh ya that was a really good and easy way
|
Mark M. |
that can help, but it may not be specific enough
|
EGHDK |
Mark... not really another question. Just back to the first... so activities for the most part wont be killed off. It's usually either the whole process... or nothing.
|
Mark M. |
right
|
EGHDK |
So what if I enter a single activity app. then press back, which calls finish on the activity. Is the application class dead? Like... what if I stored the session object in there?
|
Mark M. |
"Is the application class dead?" -- not yet, as the process is not yet terminated
|
Mark M. |
process termination does not occur *directly* due to BACK or HOME
|
Mark M. |
moving a process to the background by BACK, HOME, or other means signals that the process *can* be killed at any point
|
Mark M. |
when it *will* be killed is indeterminate
|
Jul 15 | 7:40 PM |
Mark M. |
ming: do you have another question?
|
EGHDK |
So I created a MySerivce extends service which has a thread and a Thread.sleep() and it just does this in a while (true) loop. I know this is probably bad, but looking in my app manager, my service is still alive and been alive for just over 4 hours now. This is leading me to thinking that I should have a service that just exists, so that the app class doesn't die so that the session is still seen as active.
|
Mark M. |
that's really user-hostile
|
ming |
I am thinking the current pattern for loading the list is not optimal
|
Mark M. |
EGHDK: let me take ming's next one, and I'll be back with you in a bit
|
ming |
Is it possible to load parents first, then when i click on a parent, load its children
|
EGHDK |
No prob.
|
Mark M. |
ming: I don't think ExpandableListAdapter will work all that well that way
|
ming |
ok i see
|
Mark M. |
there may be a recipe for what you are describing
|
Mark M. |
I do not use ExpandableListView much, and so I have not attempted what you are describing
|
Mark M. |
ideally, it would support what you want
|
Mark M. |
I apologize for not having more ExpandableListView experience to tap upon
|
Mark M. |
EGHDK: from the user's perspective, the difference between your storing your information in a file and your using a Service is that you are tying up RAM that could be used better for something else
|
Mark M. |
do not have a service running unless it is actively delivering value to the user
|
Jul 15 | 7:45 PM |
Mark M. |
and keeping data in RAM to avoid writing it to a file is little value
|
Mark M. |
not to mention that users with task managers will swat your process out of memory anyway
|
EGHDK |
Okay. But lets just say I had a service... if it did absolutely nothing, that would most likely keep the application class around for a longer period of time... correct?
|
Mark M. |
processes with services in it are considered higher priority than processes with just activities in it
|
Mark M. |
because it is assumed that the services are actively delivering value to the user
|
Mark M. |
and therefore such processes are, on average, less likely to be terminated due to low memory conditions
|
Mark M. |
from the user's standpoint, that only makes sense if the service *is* actively delivering value
|
EGHDK |
Okay, thats basically what I was looking for. Just couldn't put it to words. Yeah. I don't plan on doing this, but was just curious for my own personal application.
|
EGHDK |
What would be the best way to keep a service alive forever? Just Thread.sleep()? or just don't do anything and never call stopSelf()?
|
Mark M. |
the latter
|
Mark M. |
bearing in mind that "forever" is not forever
|
EGHDK |
Yeah. Got it.
|
Susheel | has entered the room |
Mark M. |
hello, Susheel!
|
Susheel |
Hi Mark
|
Mark M. |
Susheel: the others have had a chance with questions, so... do you have a question?
|
Jul 15 | 7:50 PM |
EGHDK |
The reason I don't want to write the session to persistant storage is because I want to verify that the user has the password before I let them in.
|
Susheel |
Yes, how can I make the navigation bar(the one with the back button, home button and recent apps) dissapear?
|
Susheel |
in Android 4.2.2
|
Mark M. |
you can't make it permanently disappear
|
Mark M. |
and in 4.2.2 I don't think you can do anything with it other than dim it
|
Susheel |
ok
|
EGHDK | |
EGHDK |
I did that like last week in an app. heh. =)
|
Mark M. |
yeah, I was just about to post that link
|
Mark M. |
however, it's only gone until the user touches the screen
|
Mark M. |
the immersive full-screen mode, which works a bit better, was only added in 4.4
|
Susheel |
EGHDK: thanks.. @Mark: Yes I tried that too...was wondering if there is a way to detect the touch and make it disappear it again really quickly before the user can sense it?
|
Mark M. |
well, you detect the touch via your widgets
|
Susheel |
ok
|
Mark M. |
and you can call setSystemUiVisibility() again
|
Mark M. |
however, I suspect the user will perceive it
|
Susheel |
ok
|
Mark M. |
ming: do you have another question?
|
Jul 15 | 7:55 PM |
ming |
not yet
|
ming |
im profiling my app
|
Mark M. |
OK, if you come up with another one, let me know
|
Mark M. |
EGHDK: do you have another question?
|
EGHDK |
Okay two more questions on my list. If an app has activity A B and C. ANd I'm now at C because I went from A > B > C. I then press home, then I press the app icon from the launcher. I get brought back into A. But my process wasn't killed, I can see that a variable I set in the App class is still set. So now what happened to the previous A B and C?
|
EGHDK |
Do they still count towards my app memory consumption?
|
Mark M. |
thats
|
Mark M. |
that's a fine question
|
Mark M. |
and off the cuff, I forget :-(
|
EGHDK |
Is there anyway to list all the active activities?
|
Mark M. |
not really, but you could add some Log statements to onDestroy() and see if they get destroyed
|
Mark M. |
if the effect of what you're doing is akin to FLAG_ACTIVITY_CLEAR_TOP, B and C at least should be destroyed
|
EGHDK |
Also... this day goes down in history "July 15th 2014, Mark Murphy told me I had a "fine question"
|
Mark M. |
the way I use that phrase, a "fine question" is usually one that I really ought to know the answer for, and don't, and I'm chagrined at that
|
Mark M. |
:)
|
Mark M. |
but you should be able to see if those activities get destroyed
|
Mark M. |
if they are not, they should still be floating around your process
|
Mark M. |
and you could bring them back to the foreground with FLAG_ACTIVITY_REORDER_TO_FRONT, if you wanted
|
Mark M. |
Susheel: do you have another question?
|
EGHDK |
Yeah I'm going to log. Theres no easy way to see what activities are active right? I remember seeing an app on the play store that was supposed to help you understand tasks and activies and their flags by showing you an up to date view of where in the task stack you are.
|
Jul 15 | 8:00 PM |
Mark M. |
"Theres no easy way to see what activities are active right?" -- not that I'm aware of
|
Susheel |
Yes.
|
Mark M. |
Susheel: go ahead
|
Susheel |
My android device does not have an accelerometer. Is there anyway I can flip the screen layout if the device is turned upside down?
|
Mark M. |
it doesn't have an accelerometer? really?
|
Susheel |
It's not a phone. It's a custom built Single Board Computer
|
Mark M. |
ah, OK
|
Mark M. |
I don't know how you would know the device is turned upside down
|
Susheel |
ok
|
Mark M. |
flipping the screen layout also is not something you can do on your own, unless you are drawing it all yourself
|
Mark M. |
(though you *might* be able to use rotation properties to fake it)
|
Susheel |
can we not just rotate the layout by 180 degrees?
|
Susheel |
cool
|
Susheel |
I can wait for my turn if anybody else has a question
|
Mark M. |
EGHDK: you're up next -- do you have another question?
|
EGHDK |
Any input for this question Mark? http://stackoverflow.com/questions/24745246/and...
|
Mark M. |
with respect to 1), I don't know the rules there
|
Jul 15 | 8:05 PM |
Mark M. |
with respect to 2), what do you mean by "force the launcher activity"?
|
EGHDK |
App icon has the intent category of "launcher"
|
EGHDK |
but sometimes it doesn't give me the launcher.
|
EGHDK |
launcher activity*
|
Mark M. |
but that doesn't really explain what "force the launcher activity" means
|
EGHDK |
So I need a way to test that if I'm at activity C, what happens to my app if I am put back into A.
|
Mark M. |
ok
|
EGHDK |
So I want to force open my launcher activity (A) somehow, but the app icon doesn't do it (always).
|
Mark M. |
I can think of a couple of options
|
Mark M. |
option #1 would be to write a second tiny app that just launches A in your first app
|
Mark M. |
option #2 would be to use adb shell am start
|
EGHDK |
am start?
|
Mark M. | |
Mark M. |
am is the "activity manager"
|
Mark M. |
it's a command-line tool, in the shell of your device or emulator
|
EGHDK |
I think I might do option 1. but that means I need to export my activity A... correct?
|
Mark M. |
your launcher activity is already exported
|
EGHDK |
because of its intent filter... rught?
|
Mark M. |
any activity with an <intent-filter> is exported by default
|
EGHDK |
Got it. Okay. So I call that activity directly... or the application?
|
Mark M. |
find your app in the list of apps, and tap on it
|
Mark M. |
option #3 would be to run my Launchalot app from the book
|
Mark M. |
there is no application
|
EGHDK |
Okay thanks.
|
Mark M. |
you either call startActivity() or use am start to start an activity
|
Mark M. |
Susheel: your turn -- do you have another question?
|
Susheel |
Yes
|
Susheel |
View paste
|
EGHDK |
Yeah, I didn't know I could make an explicit startActivity call to an outside activity.
|
Jul 15 | 8:10 PM |
Mark M. |
Susheel: sorry, but I have no idea
|
Susheel |
But did I ask my question in a way you understood it?
|
Mark M. |
I have never tried mixing onTouchEvent() with other higher-order UI events like a long click
|
Susheel |
ok
|
Mark M. |
in fact, I rarely use onTouchEvent()
|
Susheel |
Thing is I am implementing an integer incrementer when a button is pressed and held
|
Mark M. |
off the cuff, I would suggest doing *everything* from onTouchEvent() and get rid of the long-click listener
|
Mark M. |
but that's just a gut instinct
|
Susheel |
ok
|
ming | |
Susheel |
how would you go about implementing an integer incrementer as long as a button is held?
|
Susheel |
if I may ask
|
Mark M. |
Susheel: start incrementing on MOTION_DOWN, stop incrementing on MOTION_UP
|
EGHDK |
Susheel on touch down take a timestamp, ontouchup take a time stamp?
|
Susheel |
cool thanks
|
Mark M. |
but, again, I haven't fussed with onTouchEvent() since I worked on drag-and-drop code for the old Maps V1 stuff a few years ago
|
Susheel |
EGHDK: Thanks
|
Susheel |
cool beans. Thanks for your help today :)
|
EGHDK |
Subtract them, and you'll get lets say 3 seconds, and you can count that as the value that its been held down for. I actually did something like that recently as well.
|
Mark M. |
ming: while the bar chart is sometimes informative, I'd focus more on the tree of calls in the bottom half of the Traceview window, to see what methods are consuming the most time or are being called way too many times
|
Susheel |
EGHDK: I am going to try that now
|
Jul 15 | 8:15 PM |
ming |
the method takes the most time is doing network request
|
Mark M. |
OK, that's not surprising
|
Mark M. |
is that being called on a background thread?
|
ming |
i guess theres no way I can improve on that
|
ming |
yes
|
Mark M. |
you might be able to get some improvement, but that usually depends as much on the server as on your code in the app
|
ming |
i suppose, I am using robospice, im not completely sure but I would assume
|
Mark M. |
I have never used Robospice, so I do not know all of its details
|
Mark M. |
you should be able to tell from Traceview if the network calls are on the background thread, though
|
ming |
oh yes, it is called in the background thread
|
Mark M. |
when you say that "the current pattern for loading the list is not optimal", what are your exact symptoms?
|
Mark M. |
is the UI frozen?
|
Mark M. |
are you waiting too long to be able to populate the ExpandableListView?
|
Mark M. |
something else?
|
ming |
the second
|
Mark M. |
OK, so you kick off the thread to build up the data for the ExpandableListAdapter, and that is taking too long?
|
ming |
yes
|
Jul 15 | 8:20 PM |
Mark M. |
what is the nature of the network calls? is it a single call to download the whole tree of data, or is it several separate calls?
|
ming |
it is getting all data in one call
|
Mark M. |
then there probably is not much you can do about that
|
ming |
then put those data into arraylist of models
|
Mark M. |
is there a way you can do the call at some other time, and cache the results, so you have them when the UI is needed?
|
ming |
yes that will be a great idea
|
Mark M. |
OK, if anyone has any remaining questions, ask away
|
ming |
but users' expectation is "i want to see this data now so i click the button"
|
EGHDK |
Two more things. 1. Reading my java book. It talkas about synchrnoized. It says that this means something along the lines of "one atomic process". And it keeps saying atomic... I've never heard of this in programming contaxt. I think atomic as in bomb. Is this atomic thing a java thing or what?
|
Mark M. |
ming: then they will need to expect to wait a bit -- show a ProgressBar or otherwise let them know you are working on it
|
ming |
atomic comes from "atom", which is believed cannot be separated further
|
Jul 15 | 8:25 PM |
Mark M. |
EGHDK: in this sense, "atomic" means "only modified by one thing at once", more or less
|
Mark M. | |
Jul 15 | 8:30 PM |
Mark M. |
OK, that's a wrap for today's chat
|
Mark M. |
the transcript will be posted to http://commonsware.com/office-hours/ shortly
|
Mark M. |
the next chat is next Tuesday at 7:30pm US Eastern Time
|
Mark M. |
have a pleasant day!
|
ming |
thank you so much!
|
EGHDK | has left the room |
ming | has left the room |
Susheel | has left the room |
Mark M. | turned off guest access |