Feb 12 | 3:55 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Yaniv S. | has entered the room |
Mark M. |
hello, Yaniv!
|
Mark M. |
how can I help you today?
|
Yaniv S. |
Hi Mark
|
Yaniv S. |
two days ago you advised me on a problem , with the service to communicate with the client
|
Mark M. |
yes
|
Yaniv S. |
I couldn't apply the example from the book to my code :(
|
Yaniv S. |
can you look at my code ?..
|
Yaniv S. |
my service receives messages
|
Yaniv S. |
and when a message is received I want a client app to receive it
|
Yaniv S. |
(just a reminder)
|
Mark M. |
considering that your code is spread across multiple apps, and since I am probably not authorized to see that code in the first place, then I cannot really look at your code
|
Feb 12 | 4:00 PM |
Mark M. |
step #1 would be to get standard service binding going, with AIDL used by all apps, to expose your service and allow the clients to bind to it
|
Mark M. |
step #2 would be to augment the AIDL with some sort of callback/listener interface, where the clients pass an instance of that listener to the service, which uses it to let them know about incoming messages
|
Mark M. |
step #3 is usually beer, though other beverages can be substituted as appropriate :-)
|
Yaniv S. |
I'll just paste relevant snippets
|
Yaniv S. |
is that ok?
|
Mark M. |
it's up to you
|
Yaniv S. |
ok ..
|
Mark M. |
either paste them here, or use your favorite pastebin/gist sort of service and post the links here
|
Mark M. |
the advantage of the latter is that, if the service lets you, you can pull the snippets down later
|
Yaniv S. |
I don't know how..ill just paste here :)
|
Yaniv S. |
so , in the service, this is my thread that receives messages
|
Yaniv S. |
View paste
(11 more lines)
|
Yaniv S. |
it's an infinite loop, and serialComm.Receive
|
Yaniv S. |
is on a different class where I'm receiving the messages
|
Feb 12 | 4:05 PM |
Yaniv S. |
the return is the message which I pass to a handler
|
Yaniv S. |
now my AIDL file is this :
|
Yaniv S. | |
Yaniv S. |
the onBind:
|
Mark M. |
that presumably is the callback/listener interface, where the client is the implementer of the IExtMessage.Stub
|
Yaniv S. |
View paste
|
Yaniv S. |
and the messageBinder
|
Yaniv S. |
View paste
|
Mark M. |
that does not make much sense to me
|
Mark M. |
that would be a polling interface
|
Yaniv S. |
ok..so what am I doing weong here?
|
Mark M. |
bad bad bad bad bad
|
Yaniv S. |
wrong
|
tinoper | has entered the room |
Mark M. |
use a push system
|
tinoper |
hi
|
Mark M. |
(BTW, hello, tinoper -- I will be with you shortly)
|
Yaniv S. |
whats a push system?
|
Mark M. |
listeners, callbacks, etc.
|
Mark M. |
with a Button, we do not have a busy loop asking "were you just clicked?"
|
Mark M. |
instead, we register a listener, and we are told when the button is clicked
|
Mark M. |
similarly, your clients should not be polling the service asking "did I get a message?"
|
Mark M. |
instead, your clients should be supplying a listener to the service, and the service will tell the client when it receives a message
|
Mark M. |
this is what I pointed out to you in the book, with the Binding/Callback sample app
|
Yaniv S. |
so how do I supply that listener?
|
Mark M. |
via two AIDL interfaces
|
Mark M. |
as is shown in the Binding/Callback sample app from the book that I pointed out to you last time
|
Feb 12 | 4:10 PM |
Yaniv S. |
Iv'e seen it , but did not understand how to apply it to my case
|
Mark M. |
one is the service's AIDL, exposing some sort of registerClientListener(IExtMessageListener l) method
|
Mark M. |
the other is the client's AIDL, defining IExtMessageListener
|
Yaniv S. |
how should I write the aidl files then?
|
Mark M. |
in my sample, the listener is per-operation ("here is the listener to use for this download")
|
Yaniv S. |
when you say listener you mean IDownloadCallBack?
|
Mark M. |
yes, that was the one from the Binding/Callback sample app
|
Mark M. |
"listener" and "callback" tend to be used interchangeably as terms
|
Mark M. |
peek again at the "Servicing the Service" section in the book that I mentioned last time, while I take a question from tinoper, and I will be back with you shortly
|
Yaniv S. |
ok, so which methods I need to code in my listener?
|
Mark M. |
tinoper: your turn! do you have a question?
|
tinoper |
hi Mark
|
Feb 12 | 4:15 PM |
tinoper |
MediaPlayer class can play RTSP streaming?
|
Mark M. |
it is supposed to be able to handle RTSP, last time I checked
|
Mark M. |
as I do not have an RTSP server, I have not tried it
|
tinoper |
ok
|
Mark M. | |
tinoper |
Where can I check that?
|
Mark M. |
that page lists the supported network protocols for Android's media framework
|
Mark M. |
"RTSP (RTP, SDP)" is listed
|
tinoper |
I only found local files examples but not with rtsp streaming and when I try to do it fails.
|
Mark M. |
well, I know other audio players use RTSP, as I have seen where you can enter in RTSP URLs into them (though I haven't done this in ages)
|
Mark M. |
bear in mind that RTSP only supports a handful of codecs
|
Mark M. |
AFAIK, stuff like Shoutcast go beyond the RTSP spec
|
tinoper |
Instead of this I try with vitamio library and it works.
|
Mark M. |
and, at least back in the early days of Android, Android's support for RTSP was limited to the spec
|
Mark M. |
so, IIRC, RTSP does not support MP3, but Shoutcast added it
|
Mark M. |
but, at least early versions of Android did not support MP3 over RTSP, as that was out of spec
|
Mark M. |
I haven't looked at RTSP support in Android in years, and so I do not know if compatibility with popular extensions to the spec has improved
|
Feb 12 | 4:20 PM |
Mark M. |
third-party libraries give you greater flexibility, if licensing and the bigger APK size are not impediments
|
tinoper |
Do you suggest anyone?
|
Mark M. |
I have never used a third-party media library, so I have no recommendations
|
tinoper |
ups
|
tinoper |
what about Exoplayer?
|
Mark M. |
I have heard the name, but I don't know much about it
|
tinoper |
Well,I will try something more with them.
|
tinoper |
Right now,only Vitamio is working for me.
|
Mark M. |
sorry I could not help you much on this -- media (outside of the camera) is not one of my deeper areas in Android
|
Mark M. |
let me swing back to Yaniv for a bit, and I will come back to you shortly
|
Mark M. |
Yaniv: your turn!
|
tinoper |
No problem.Indeed,it's an answer too!
|
tinoper |
have a nice day
|
Mark M. |
Yaniv: "so which methods I need to code in my listener?" -- that is up to you, but presumably it would be something like onMessageReceived()
|
Mark M. |
tinoper: you too!
|
Yaniv S. |
and it returns void or a message?
|
Yaniv S. |
sorry i'm really having trouble with this aidl stuff
|
Mark M. |
it takes a message as a parameter, from the service
|
Mark M. |
what it returns is up to you
|
Mark M. |
usually, you return void, simply because you do not want to tie things up with blocking calls
|
Mark M. |
but if there's some simple rapid response you want to return, that is OK too
|
Yaniv S. |
but I need to return a message to the client no
|
Yaniv S. |
?
|
Mark M. |
correct
|
Feb 12 | 4:25 PM |
Yaniv S. |
so if it's void.. how does the client receives it?
|
Mark M. |
as a parameter to the method on the listener
|
Mark M. |
let's review how this is done in the Binding/Callback sample
|
Mark M. | |
Yaniv S. |
so something like this?
|
Mark M. |
this is the AIDL exposed by the service
|
Mark M. |
the download() method takes the URL to download, plus an IDownloadCallback object
|
Mark M. |
IDownloadCallback is another AIDL interface: https://github.com/commonsguy/cw-omnibus/blob/m...
|
Mark M. |
IDownloadCallback has onSuccess() and onFailure() methods, for the service to send results back
|
Mark M. |
in the case of your app, IDownload would be replaced by something like IExtMessageSource
|
Mark M. |
it would have a method, something like registerMessageClient()
|
Mark M. |
registerMessageClient() would take an AIDL-defined listener as a parameter
|
Mark M. |
just like how download() takes an AIDL-defined listener as a parameter
|
Yaniv S. |
ok.. with you so far
|
Mark M. |
so, we say that registerMessageClient() takes an IExtMessageListener parameter
|
Mark M. |
IExtMessageListener is another AIDL-defined interface
|
Mark M. |
it defines an onMessageReceived() method
|
Feb 12 | 4:30 PM |
Mark M. |
the service, in its implementation of registerMessageClient(), takes the IExtMessageListener and hangs onto it somewhere
|
Mark M. |
when a message comes in that is appropriate for that client, it calls onMessageReceived() on the IExtMessageListener object
|
Mark M. |
the client has the implementation of onMessageReceived(), and it receives the message as a parameter
|
Mark M. |
what the message itself is, I don't know -- String, Bundle, another AIDL-defined interface, whatever
|
Yaniv S. |
umm
|
Yaniv S. |
ok
|
Yaniv S. |
wait
|
Yaniv S. |
let me tell you where im confused
|
Yaniv S. |
in your example
|
Yaniv S. |
in the onbind method
|
Yaniv S. | |
Yaniv S. |
you return a new downloadBinder
|
Yaniv S. |
where it is a class that from there you start the thread
|
Mark M. |
correct
|
Yaniv S. |
but in my case
|
Yaniv S. |
the thread starts automatically when the service stars
|
Yaniv S. |
starts
|
Mark M. |
so?
|
Mark M. |
the listener is a Java object
|
Yaniv S. |
what do I return in y onBind?
|
Yaniv S. |
my
|
Mark M. |
you return the IExtMessageSource.Stub, based on the names I used above
|
Mark M. |
and note that you are looking at the wrong sample
|
Mark M. |
oh, no, you're right
|
Mark M. |
DownloadBinder is a subclass of IDownload.Stub
|
Mark M. |
my apologies
|
Mark M. |
so, you would return your subclass of IExtMessageSource.Stub
|
Feb 12 | 4:35 PM |
Yaniv S. |
what is this subclass use for?!
|
Mark M. |
where you have your implementation of registerMessageClient()
|
Yaniv S. |
why do i need it?
|
Mark M. |
you are implementing an API
|
Mark M. |
you need to get the listener from the client
|
Yaniv S. |
how do I use the listener?
|
Yaniv S. |
in your case you passed it to the thread
|
Mark M. |
you call methods on it when the messages come in
|
Yaniv S. |
no sure I follow
|
Yaniv S. |
View paste
|
Mark M. |
then I am afraid that I will be of little use to you
|
Mark M. |
let me take a question from tinoper, and I will be back with you in a bit
|
Mark M. |
tinoper: your turn! do you have another question?
|
Feb 12 | 4:40 PM |
tinoper | has left the room |
Mark M. |
OK, Yaniv, back to you
|
Yaniv S. |
so, in my case, the download method is a registerMessage method
|
Yaniv S. |
it passes the listener
|
Mark M. |
registerMessageListener()
|
Mark M. |
the client isn't registering a message, it is registering a listener to receive messages
|
Yaniv S. |
ok
|
Yaniv S. |
so it takes the listener as parameter
|
Mark M. |
right
|
Yaniv S. |
and..how do I use it?
|
Yaniv S. |
you start a thread
|
Yaniv S. |
what do I do ?
|
Mark M. |
store it somewhere
|
Mark M. |
your service is listening for messages on something
|
Mark M. |
when it gets a message, and it determines that it needs to pass the message to the client, it calls the method on the listener
|
Mark M. |
so, if the listener has an onMessageReceived() method, your service calls onMessageReceived()
|
Mark M. |
since I don't know your object model, I cannot tell you exactly what should hold onto the listeners, other than it is tied into your service somehow
|
Feb 12 | 4:45 PM |
Yaniv S. |
and and when onMessageReceived is called
|
Yaniv S. |
it's passed to the client?
|
Mark M. |
onMessageReceived() would take the message as a parameter
|
Yaniv S. |
oooohhhh
|
Mark M. |
the client would have the listener's .Stub subclass, with the implementation of onMessageReceived()
|
Yaniv S. |
now i get it
|
Mark M. |
and now the client has the message
|
Yaniv S. |
ok, I think I got it
|
Yaniv S. |
thank you very much Mark
|
Mark M. |
sorry that was so tough to get through
|
Yaniv S. |
that's ok ,I'm a beginner not only in android but in programming in general
|
Mark M. |
this is a tough project for a beginner
|
Yaniv S. |
so this is all really confusing
|
Yaniv S. |
I know, thank god you are here to help
|
Yaniv S. |
one more question:
|
Yaniv S. |
can I start as many threads as I want, in a service?
|
Mark M. |
well, don't go crazy :-)
|
Mark M. |
but there's no specific limit
|
Feb 12 | 4:50 PM |
Yaniv S. |
3-4?
|
Mark M. |
that's reasonable
|
Mark M. |
particularly if they are blocking waiting on I/O a lot
|
Yaniv S. |
blocking waiting is what I've used with the message receiveing?
|
Mark M. |
I do not know, as I do not know how your service is getting the messages
|
Mark M. |
if your serialComm object really means serial I/O, then presumably it is blocking in there somewhere
|
Yaniv S. |
what do you mean by blocking?
|
Mark M. |
that's a little complicated for a chat
|
Mark M. | |
Yaniv S. |
thanks, I'll read it there
|
Yaniv S. |
so thanks again Mark ,
|
Yaniv S. |
bye bye
|
Yaniv S. | has left the room |
Feb 12 | 5:00 PM |
Mark M. | turned off guest access |