Dec 27 | 8:55 AM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Dec 27 | 9:15 AM |
Venkat | has entered the room |
Venkat |
Hello
|
Mark M. |
hello, Venkat!
|
Mark M. |
how can I help you today?
|
Venkat |
I have two questions related to the same thing ...
|
Venkat |
I have a websocket service which 3 different activities use. Each activity has a member for ServiceConnection. What I expected was a single websocket connection to the server shared by all activities but what I see is 3 different connections.
|
Venkat |
1. Any ideas why this is happening.
|
Venkat |
2. I am thinking of either using something like Greenrobot EventBus or a singleton - which would be better.
|
Mark M. |
regarding #1, I cannot really comment on that, as I have no idea how this service is implemented
|
Venkat |
ok
|
Dec 27 | 9:20 AM |
Mark M. |
regarding #2, your question is akin to "I am thinking of using a banana or a hammer - which would be better?", insofar as the choice of a singleton or an event bus are not strictly related
|
Venkat |
ok
|
Mark M. |
and I do not know how either of those relate to the service and activities from #1
|
Mark M. |
so, let's go back to #1
|
Mark M. |
when and how does this service create a WebSocket?
|
Venkat |
Each activity has a member for ServiceConnection & in the override for onServiceConnected it attempts to create a websocket connection if not already done.
|
Mark M. |
then the activities are the ones creating the websocket, not the service
|
Mark M. |
and so if you have three activities, you will have three websockets
|
Venkat |
ok ...
|
Mark M. |
if you want a "websocket service", the *service* should be creating the websocket, perhaps in onCreate() of the service
|
Dec 27 | 9:25 AM |
Mark M. |
the activities delegate the websocket communications to the service
|
Venkat |
ok ... I will try that
|
Venkat |
To clarify ...
|
Venkat |
View paste
|
Venkat |
Does that create separate instances of the WebsocketService class for each activity?
|
Mark M. |
probably not, but I do not know all of the details behind those two lines
|
Venkat |
ok
|
Mark M. |
is WebsocketService a Service?
|
Dec 27 | 9:30 AM |
Venkat |
Yes, it extends Service.
|
Mark M. |
is WebsocketService.LocalBinder a subclass of IBinder, where WebsocketService returns an instance of WebsocketService.LocalBinder from onBind()?
|
Venkat |
Correct!
|
Mark M. |
OK
|
Mark M. |
in the first line of your code snippet (WebsocketService.LocalBinder binder = (WebsocketService.LocalBinder) service;), what is service? Is that the IBinder passed into onServiceConnected()?
|
Venkat |
Yes correct.
|
Mark M. |
and getService() on WebsocketService.LocalBinder returns... what?
|
Venkat |
WebsocketService.this
|
Mark M. |
OK
|
Mark M. |
then presumably all of these are in one process (as what you are doing will not work across process boundaries)
|
Venkat |
Yes
|
Dec 27 | 9:35 AM |
Mark M. |
whether mService is the same object or N objects depends on the timing of the binding and unbinding
|
Mark M. |
and whether you are also starting WebsocketService
|
Mark M. |
once you call unbindService(), if there are no other current bound connections from other bindService() calls, and if the service was not started, the service is destroyed
|
Mark M. |
so, suppose that your three activities are A, B, and C
|
Venkat |
Ok ...
|
Mark M. |
if A binds and unbinds before B and C get a chance to bind, and if A did not start WebsocketService, A will have worked with a different instance of WebsocketService than will the others
|
Venkat |
Ok ... that complicates things a bit ... I did not know that.
|
Mark M. |
this is one of the reasons why I am not a big fan of the binding pattern -- the bookkeeping gets complex
|
Venkat |
I think that is what I am doing wrong
|
Venkat |
... there is no call to startService in my code.
|
Dec 27 | 9:40 AM |
Mark M. |
depending on your activity flow, you *may* be able to make that work
|
Mark M. |
you would have to bind in onCreate() and unbind in onDestroy()
|
Mark M. |
(plus use a retained fragment or something so that you do not unbind and re-bind on a configuration change)
|
Mark M. |
basically, you need to ensure that B has a chance to bind before A has a chance to unbind
|
Mark M. |
(and similarly for C)
|
Venkat |
Ok ...
|
Venkat |
I will read up more on services + change the code as you say.
|
Venkat |
I just had one more comment on the book.
|
Dec 27 | 9:45 AM |
Venkat |
I needed to implement tabs in my application and my first attempt was based on the example in your book (I don't remember the details). Later, I learnt that the recommended way is to use android.support.design.widget.BottomNavigationView
|
Mark M. |
there are lots of tab implementations
|
Venkat |
Just thought a note in the book about that option would be helpful.
|
Mark M. |
BottomNavigationView is not "the recommended way" necessarily
|
Venkat |
Ok ... :-)
|
Mark M. |
I do not anticipate covering BottomNavigationView any time soon, sorry
|
Venkat |
Ok ... I thought BottomNavigationView was recommended ... I don't remember the source though. Something to do with placement at the bottom of the screen.
|
Mark M. |
some people like that, some people do not
|
Venkat |
Ok
|
Mark M. |
I am not going to be covering every possible UI permutation -- I simply do not have that kind of time
|
Dec 27 | 9:50 AM |
Venkat |
:-) ... I fully understand ... the reason I asked you is to simply know if that was an oversight or intentional.
|
Mark M. |
it's an intentional oversight :-)
|
Venkat |
Thats all.
|
Venkat |
The book as it is is very extensive.
|
Mark M. |
Android is vast
|
Mark M. |
the Android ecosystem is even more vast
|
Venkat |
Yup ... and your book does a great job as a first source of reference.
|
Mark M. |
thanks!
|
Venkat |
Thanks for your help & best wishes of the season.
|
Venkat |
Goodbye.
|
Mark M. |
have a pleasant day!
|
Venkat | has left the room |
Dec 27 | 9:55 AM |
Leora | has entered the room |
Mark M. |
hello, Leora!
|
Leora |
Hi Mark, 3 minutes left!
|
Mark M. |
I can help you with a quick question, if you have one
|
Leora |
yeah, I need to query the DB using room...but when the user or OS kills the app.
|
Mark M. |
you do not get control when Android terminates your process (by user request or automatically when you are in the background)
|
Leora |
I'm using a service to catch the event just before the activity is destroyed
|
Mark M. |
do you mean onTaskRemoved()?
|
Leora |
I'm using it in onTaskRemovedBroadcastReceiver
|
Leora |
yes sir!
|
Mark M. |
AFAIK, that is not reliable, but if you want to do some work there, you are welcome to try
|
Leora |
so, the query won't work with context that is being destroyed
|
Leora |
but my boss doesn't want me to call the function beforehand
|
Leora |
since the query is unnecessary beforehand
|
Mark M. |
well, you can try using the Application context (call getApplicationContext() on any other Context)
|
Leora |
what would you recommend then to, for example, pause downloading content
|
Dec 27 | 10:00 AM |
Leora |
ok, application context option. anything else? better solution to make sure method is called?
|
Mark M. |
I am not quite certain what that has to do with Room, and it would depend on how the downloading is being done and what interruption options it has
|
Mark M. |
well, onTaskRemoved() is only called on some devices in some situations
|
Mark M. |
some devices do not appear to call that when the user swipes the task off the overview screen, for example
|
Leora |
cause the previous queries were not on another thread
|
Mark M. |
based on complaints that I have been seeing in Stack Overflow, etc.
|
Leora |
ahhh, i didn't know that
|
Leora |
so far it's worked
|
Mark M. |
I also do not expect it to be called if the user does a Force Stop from your app's screen in Settings
|
Leora |
but i ALWAYS wanted to know how to handle last second methods that HAVE to happen before app is killed
|
Mark M. |
by then, it's too late
|
Mark M. |
whatever work you wanted to do should have been done much sooner, such as when the app moved into the background
|
Mark M. |
or when the data changed
|
Mark M. |
or something
|
Leora |
but content should keep downloading in bckgrnd
|
Mark M. |
by definition, it will not be, as your process is being terminated
|
Mark M. |
(exception: downloading being done in another process, such as DownloadManager)
|
Leora |
and be suspended before app is closed
|
Mark M. |
you need to handle *lots* of downloading interruptions
|
Mark M. |
onTaskRemoved() represents a subset of those, at best
|
Dec 27 | 10:05 AM |
Leora |
i'm afraid i don't understand what you are suggesting
|
Mark M. |
since the downloading will be stopped when your process is, you need to be able to handle that when your process starts back up again
|
Mark M. |
as that will handle cases where the downloads are interrupted due to lost network connections, airplane mode, etc.
|
Leora |
oh i see
|
Mark M. |
in addition to mid-flight process termination
|
Leora |
yes i see
|
Mark M. |
moreover, on Android 8.0+, you need to use a foreground service, since the download might take more than a minute
|
Leora |
confused, yet understand, sort of
|
Leora |
:)
|
Mark M. |
such a service should still run even if the user swipes the task off of the screen
|
Leora |
it should? i'm rather surprised you say that
|
Mark M. |
worked when I tried it recently for an issue with my CWAC-Presentation library
|
Mark M. |
that may have been a Samsung-specific behavior, but AFAIK it is the norm
|
Leora |
it should keep downloading until the user herself pauses it?
|
Mark M. |
if that's what the service is doing, yes
|
Mark M. |
at least, for most devices
|
Mark M. |
there will always be edge cases, where the manufacturer ties the overview screen to Force Stop or something
|
Mark M. |
in addition to the problems with network connections and whatnot
|
Mark M. |
so, if I were in your shoes (which probably do not fit me, but, anyway...) I would be using a foreground service, but still have "disaster recovery" logic to deal with an interrupted download when my process starts up again
|
Leora |
i don't want to keep you any later. i will reread what you wrote and ponder
|
Mark M. |
and not worry about trying to somehow magically get control on every possible process termination scenario, since that's impractical
|
Mark M. |
OK
|
Leora |
and btw, i have big feet
|
Dec 27 | 10:10 AM |
Mark M. |
well, then, there's hope for me yet! :-)
|
Mark M. |
(or at least for my feet)
|
Leora |
i just don't know how i can get the 'actual' status of the content, but ok
|
Leora |
thank you so so much
|
Mark M. |
you're welcome! FWIW, the next chat in this time slot is Thursday of next week
|
Leora |
are you coming to droidcon TLV tomorrow as a surprise guest speaker?
|
Leora |
:)
|
Mark M. |
not that I am aware of
|
Leora |
darn it
|
Mark M. |
the transcript for this chat will go up on https://commonsware.com/office-hours/ shortly
|
Mark M. |
have a pleasant rest of your day!
|
Leora |
namaste
|
Leora | has left the room |
Mark M. | turned off guest access |