Office Hours — Today, March 17

Yesterday, March 16

Mar 17
3:50 PM
Mark M.
has entered the room
Mark M.
turned on guest access
4:00 PM
Guido
has entered the room
Mark M.
hello, Guido!
how can I help you today?
Guido
Hi Mark
I've got a question ready
View paste
I've got an activity that juggles two fragments, first to be instantiated is fragmentA when the app starts, and then fragmentB at a user request, the transaction that adds the latter will be added to the BackStack so the user can go back to fragmentA using the back key.
So, after instantiating FragmentB I've got MainActivity with FragmentB visible in its container, FragmentA isn't visible but is still hanging around.
If now I turn my devices on landscape, both fragments will be detached destroyed and recreated, however only FragmentB will go through the view creation, FragmentA will not - as it's not visible I guess- is this expected?
I didn't realise of this problem until I changed my device orientation again, as my custom onSaveInstanceState was trying to save the state of its view, which didn't exist. So I have to consider two cases depending on whether or not the view exists, which depends on multiple configuration changes. Does this make sense or did I miss anything?
Mark M.
wow, you type fast :-)
Guido
hahah :-)
Mark M.
"however only FragmentB will go through the view creation, FragmentA will not - as it's not visible I guess- is this expected?" -- I haven't specifically looked at this scenario, but I do not find this behavior to be surprising
Android often lazy-creates stuff
in the hopes that perhaps the work will never be needed, saving CPU time, battery, etc.
but, yes, it would imply that a custom onSaveInstanceState() at the fragment level would need to confirm that you indeed have widgets
otherwise, recycle the same state that you got previously, I guess
4:05 PM
Guido
well the status goes lost because when the view doesn't get created I cannot save it so the next time the fragment come back from the backstack bundle is empty
which doesn't reallymatter as I use it to save the selected items and I would lose them anyway if I close the fragment
Mark M.
you should be able to cache the Bundle itself
you would get it in places like onActivityCreated()
and onCreate()
then, in onSaveInstanceState(), if you do not have your widgets, copy the state out of the cached Bundle instead
Jan
has entered the room
Jan
Hello...
Mark M.
hello, Jan!
Guido
I forgot the details as I looked into it two weeks ago
Mark M.
Guido: let me take a question from Jan, and I will be back with you in a bit
Guido
but I'll look again into it
Mark M.
Jan: your turn! do you have a question?
Guido
sure
Jan
View paste
Sure, In which circumstances should one use which "context" and why ??
Why not simply always use getApplicationContext() ??

1. getApplicationContext()
2. <MyActivity>.this
3. ContextWrapper.getBaseContext

From your answers on SO you don't seem to like getApplicationContext().  Correct ?  Why ?
Dianne Hackborn (Google) wrote on 29/1/09 : Don't use getBaseContext() .....  Why ???
4:10 PM
Mark M.
I never see anyone use getBaseContext()
I don't even recall what that returns off the top of my head
with regards when to use what sort of Context, generally speaking, use the one you have
if you are in an Activity or Fragment, use the Activity, for example
the Application object is a singleton Context, which can be useful and can be dangerous
in particular, it knows nothing about themes
and so setting up UI using Application invariably means default styling, not your custom colors, etc.
that link is to Dave Smith's epic post, "Context? What Context?"
I point everybody to it for a concise summary of when to use what Context
Jan
I found a sample on internet from someone who seems to be rather advanced in Android and he is using getBaseContext all the time in the sample..... I guess i should ask him why.
Mark M.
getBaseContext() is undocumented
which means unless you're rooting through the source code, you don't know what it does
Jan
That's the problem :-)
Mark M.
and it means that the rules of what it does can change without warning
Raghavendra M.
has entered the room
Mark M.
there are probably some specialized scenarios where getBaseContext() is useful
4:15 PM
Raghavendra M.
HI
Mark M.
however, I consider its use to be a code smell, just as I consider the indiscriminate use of getApplicationContext() to be a code smell
(hello, Raghavendra -- I will be with you shortly!)
Raghavendra M.
Sure
Jan
I'll start by having a look at the article you gave me....
Mark M.
Jan: too often, newcomers to Android are newcomers to Java, and therefore do not know about MainActivity.this syntax
so they call getApplicationContext() or getBaseContext(), perhaps based on IDE suggestions
Jan
Is that the way you want to refer to the context of the above lying activity
Mark M.
if you are in a nested class, like an anonymous inner class, MainActivity.this will get you the "outer" class instance
so if you are doing button.setOnClickListener(new View.OnClickListener() { ... });, and you need a Context inside onClick(), you would use YourActivityClassName.this
(where YourActivityClassName is, um, your activity class name :-)
let me take questions from the others, and I will be back with you shortly
Raghavendra: your turn! do you have a question?
Jan
I didn't know that getApplicationContext was not aware of themes ....
Raghavendra M.
yeah
View paste
Had a question for queue upload and download of content(base 64 encoded content).Any libraries or samples I can get.
How to show a incremental progress bar  while uploading and downloading base 64 content
Mark M.
um
well
Base64 encoding has nothing to do with showing an incremental progress bar
Raghavendra M.
ok
Mark M.
Base64 encoding has nothing to do with queued uploads and downloads of content
Raghavendra M.
it will based on the outputstream
Mark M.
in both cases, whether the content is encoded in Base64 or something else is your choice, between you and the server
4:20 PM
Raghavendra M.
yes
Mark M.
now, when you say "queue upload and download", is the queue just in memory, or are you looking for some sort of a persistent work queue?
Raghavendra M.
in memory
no storing
of the content
as long the app lives
Mark M.
if you only need to do one upload/download at a time, IntentService has a built-in work queue
Raghavendra M.
ok
Mark M.
if you want to do parallel uploads/downloads, create a service with a ThreadPoolExecutor backed by a LinkedBlockingQueue (or PriorityQueue)
Raghavendra M.
how to know which request is currently executing
nth request
i was reading about Tape square library
Mark M.
assign each job a number
Raghavendra M.
ok
Mark M.
if you wanted a persistent work queue, I would steer you to Tape
Raghavendra M.
ok
Mark M.
with regards to the incremental progress bar, you have two pieces to consider: knowing the progress, and communicating that to the user
Raghavendra M.
yes
from a callback
from intent service
Mark M.
you'll need to look for an HTTP client library that gives you convenient access to the progress
Raghavendra M.
or broadcast reciever
Mark M.
(assuming these uploads/downloads are over HTTP)
Raghavendra M.
yes they are on http
Mark M.
I haven't looked into tracking progress, and so I cannot make any recommendations there
Raghavendra M.
ok
Mark M.
then, I'd use an event bus to let your UI layer know about the progress changes
if relevant, you could have a fallback of updating a progress bar in a Notification
Raghavendra M.
ok
4:25 PM
Mark M.
I have a chapter in the book on event bus implementations that demonstrates the fallback concept
Raghavendra M.
ok
will refer to it
how to query the intent service and get the job number
associated with request
Mark M.
I wouldn't do that
Raghavendra M.
ok
Mark M.
I would have the UI layer pick up the job number as part of the progress events
Raghavendra M.
i would use event bus for it
Mark M.
right
Raghavendra M.
event bus again will have dependecies,...?
Mark M.
all are from libraries
Raghavendra M.
its a standalone lib..?
please tell me the chapter name
Mark M.
whether that is LocalBroadcastManager in the Android Support package or libraries that you get from greenrobot, Square, etc.
Raghavendra M.
i have the book downloaded
Mark M.
the concept of event buses is introduced in the "Dealing with Threads" chapter
and there is an "Event Bus Alternatives" chapter later in the book
Raghavendra M.
sure thank you
will refer to it
Mark M.
let me take questions from the others, and I will be back with you
Raghavendra M.
sure
Mark M.
Guido: your turn! do you have another question?
Guido
yes please
View paste
I have a list based on a SimpleCursorAdapter and I need to drag and drop items to re-arrange them.

There's a number of old projects and what seems to be the best solution is the DynamicListView from Google-DevBytes

However that was designed with and array of strings rather than a cursor, so it doesn't seem to fit, as I would need to run two update queries for each time an item swap with another one.
Have you got any suggestions?
Mark M.
well, I'd recommend switching to RecyclerView
there are multiple libraries that offer drag-and-drop IIRC
that use RecyclerView for the underlying implementation
and RecyclerView is *way* more suited to that than is ListView
that being said, you can't really drag-and-drop a Cursor, as Cursors are immutable
4:30 PM
Mark M.
at best, you would have to keep track of what position in the list corresponds to what position in the Cursor, as after drag-and-drop, they will not match
personally, this is an area where switching to a POJO collection will probably be simpler
Guido
yes makes sense
Mark M.
the whole "my model is a Cursor" approach is going to fade away over time
that was a huge win with tiny heap sizes
it's not as much of a win now, particularly with ART's background heap compaction
I think that's part of the reason why you're not seeing much from Google on using RecyclerView with cursors
you certainly can -- my RecyclerView chapter demonstrates it
but, the old rules about trying to avoid copying the Cursor data into POJOs aren't as crucial anymore
let me take questions from the others, and I will be back with you in a bit
Jan: your turn! do you have another question?
Guido
OK, sounds good thanks
Jan
Yes
But not really android related : How to search your office hours archives ?
Mark M.
ummm... Google?
Jan
Never saw them showing up ....
4:35 PM
Jan
Are they not protected, accessible only to members
Mark M.
no, they're public
PagerAdapter site:commonsware.com
Guido
Actually I'm done for tonight, many thanks for your help Mark!
Mark M.
the entries whose titles are "Campfire: Today, ..." are the office hours chats
Guido: you are very welcome!
Guido
has left the room
Jan
Ok, next time I'll try that first..... office hours archive must be a fantastic source of information :-)
Mark M.
it has its advantages
on the other hand, it's not Stack Overflow, either
Jan
OK, fine
That was it for me. Mark thanks a lot for your help.... until next time.
Mark M.
you're welcome!
Jan
has left the room
Mark M.
Raghavendra: your turn! do you have another question?
Raghavendra M.
yes
Had a question about communicating with the rest services.I am currently using volley for it.But After my client saw the code he told to use a service(I know its not a thread) that would initiate all the requests.he got inspired by a old google IO video(Google I/O 2010 - Android REST client application).He is insisting to use a service
i am not persisting any data
nor using services
no orientation change hassle
Mark M.
so, right now, your REST calls are triggered just by the UI?
Raghavendra M.
there is another layer which triggering
it
Ui is talking to the layer
Mark M.
but the only reason a REST call is made is because the UI asks for it
Raghavendra M.
mvp archi
Mark M.
as opposed to being caused by other events (AlarmManager, incoming broadcasts, etc.)
4:40 PM
Raghavendra M.
is it good to just use a service
if we starting a service from activity
service will be stopped
as the activity is destroyed
Mark M.
my general rule of thumb is: if the network I/O is non-essential and quick, just use a thread/AsyncTask
if you want to feel more assured that the I/O happens, and it's of medium duration (1-10 seconds), use an IntentService
Raghavendra M.
volley internally uses thread pool
Mark M.
or some other flavor of service
Raghavendra M.
that serves my purpose
how do i convince my client
to get away from service
Mark M.
if the duration of the I/O is long (10+ seconds), use my WakefulIntentService or otherwise maintain a WakeLock
ask the client what problem the service is solving
Raghavendra M.
ohh ok
when user presses home button
or stops the activity
Mark M.
the point behind a service is to raise the process priority by signalling to Android that you are doing work
Raghavendra M.
he is worried aboit that
Mark M.
if your app is in the foreground, you're already at high priority
Raghavendra M.
ok
thats correct
Mark M.
once the user moves you to the background, now issues can arise, but in your case, there will not be any new I/O once you move to the background, as I understand it
so the only ones at any risk are I/O triggered just before the user pressed HOME or something
and that's where the duration comes into play
the longer the I/O time-wise, the more you need to consider a service
Raghavendra M.
yes exaclty
there are some request which take time
Mark M.
in which case, I would consider using an IntentService or other form of service
those can use Volley (or any other HTTP client API) too
Raghavendra M.
there are lot of request
4:45 PM
Raghavendra M.
how do i a use a single service or do i need to write multiple services
Mark M.
you only need one service
Raghavendra M.
ok
Mark M.
call startService() for every I/O you're looking to do, with enough information for the service to know what to actually perform
Raghavendra M.
in onstartcommand how will trigger different requests
Mark M.
you don't want to be doing much work in onStartCommand(), as that is called on the main application thread
beyond that, use an if or switch statement
based on something in the Intent
Raghavendra M.
there are 10 requests
10 switches is ok i guess
Mark M.
well, it'd be one switch and 10 cases
but the concept is the same
Raghavendra M.
sorry for my type
u r right
startserice will be called from activity
..?
or the layer which talks to volley
Mark M.
it would be called from wherever you are doing the REST calls right now
Raghavendra M.
yes
Mark M.
so, presumably, it would be the layer that you are referring to
Raghavendra M.
wakefulintent service will be destroyed once the request completes with stopself
Mark M.
IntentService/WakefulIntentService calls stopSelf() internally
Raghavendra M.
yes
intent service does it
for us
Mark M.
once onHandleIntent() returns, if there are no more commands to process, it will call stopSelf()
as with your earlier questions, if you want to do more than one I/O at once, you can create your own service using a ThreadPoolExecutor
Raghavendra M.
every request-->startservice
Mark M.
however, then you would have to call stopSelf() yourself when the work is all done
4:50 PM
Mark M.
and yes, each operation would result in a startService() call, so the service starts up if it is not running
Raghavendra M.
there will be no harm in calling that i guess
volley also spaws a thread
intent service also spawns a worked thread
Mark M.
I don't use Volley, but there may be a synchronous option
Raghavendra M.
but i am halfway through the project
its a major change for me
Mark M.
that is between you and your client
Raghavendra M.
yeah
will propose this
thanks for your time
it was really helpful
Mark M.
you're welcome!
4:55 PM
Raghavendra M.
one last question u mentioned we can track progress using http client
how can we do that
Mark M.
again, that would depend upon the library
Raghavendra M.
server should also support right
Mark M.
I have not spent much time with Volley
Raghavendra M.
ok
Mark M.
and so I do not know what the options are
for an upload, the client will know how to measure progress itself
Raghavendra M.
if i use other clients
how can i measure them
Mark M.
for a download, if the server sends the Content-Length header, the client should be able to determine progress as well
as I noted earlier in the chat, I have not looked at tracking progress in any client library
sorry
Raghavendra M.
sorry
for asking again
so for upload also we can get the content-length
and measure
it
thank you
Mark M.
it is your file
Raghavendra M.
yes
Mark M.
you know how big it is
Raghavendra M.
getlenth propery would give me is suppose
its just the image file coverted to base64
which is retained in memory
size is too small
in kbs
5:00 PM
Raghavendra M.
while uploading it i need to show the incremental bar
as i have told u earlier
i open to using plain http-client as well
Mark M.
um, well, that's the end for today's office hours chat
the transcript will be uploaded to http://commonsware.com/office-hours/ shortly
Raghavendra M.
ok
Mark M.
the next chat is Friday at 9am US Eastern
have a pleasant day!
Raghavendra M.
has left the room
Mark M.
turned off guest access

Yesterday, March 16

 

Office Hours

People in this transcript

  • Guido
  • Jan
  • Mark Murphy
  • Raghavendra Malgi