Hi guys,

Thanks to everyone for the prompt responses.  I've studied up on
Services / IntentServices as well as how I would go about using a
Singleton to satisfy my goal and have decided to give both a try to
take the experiential learning route.  I've started with Services and
have managed to get my app working like it should with binding an
activity in view with the Service running my network thread.  I have a
bug though which I'm having trouble resolving.... in activity 'A' I'm
using the bindService method to start my service so as to communicate
back and forth between the Service and the activity.  I've created my
service connection like so:

private CallBackActivityAInterface _service = null;

private ServiceConnection serviceConnection = new ServiceConnection()
{
    public void onServiceConnected(ComponentName className, IBinder
binder) {
         _service = (CallBackActivityAInterface)binder;

        _service.registerActivityACallBack(activityACallBack);
    }

    public void onServiceDisconnected(ComponentName className) {
         _service = null;
    }
}

In my onServiceConnected method above I pass in a call back instance
to the service so it can communicate with activity A from the network
worker thread it is running which is waiting for incoming tcp data.
This is what the CallBackActivityAInterface implementation looks like
in activity A:

private CallBackActivityAInterface activityACallBack = new
CallBackActivityAInterface() {

                @Override
                public void receivedData() {
                        runOnUiThread(new Runnable() {

                                @Override
                                public void run() {
                                        Log.d(DEBUG, "hoorah we have a 
response");
                                }
                        });
                }
};

This works fine, when I invoke _activityACallBack.receivedData() in my
service from within the worker thread that's waiting for tcp data I
get my debug output above.  It's worth noting for clarification sake
that the callback instance I pass in to my
_service.registerActivityACallBack(..) method in my service is
assigned to a global variable of type CallBackActivityAInterface
within my service class.

In activity B I have the same sort of implementation as you see above
where I create it's own service connection instance and pass in a
callback to the service so it can communicate with activity B.  When I
navigate to activity B from activity A, I first unbind my service
connection from the running service in activity A and then use the
bindService method in activity B with it's own service connection.
The issue I'm having is the callback instance I'm sending through to
the service in activity B's onServiceConnected method is null when I
try use it from within the worker thread that is currently running in
the service.  This is the callback implementation I have in activity
B:

private CallBackActivityBInterface _service = null;

private ServiceConnection serviceConnection = new ServiceConnection()
{
    public void onServiceConnected(ComponentName className, IBinder
binder) {
         _service = (CallBackActivityBInterface)binder;

        _service.registerActivityBCallBack(activityBCallBack);
    }

    public void onServiceDisconnected(ComponentName className) {
         _service = null;
    }
}

private CallBackActivityBInterface activityBCallBack = new
CallBackActivityBInterface() {
    @Override
                public void receivedDataInActivityB() {
                        runOnUiThread(new Runnable() {

                                @Override
                                public void run() {
                                        Log.d(DEBUG, "hoorah we have a response 
in activity B");
                                }
                        });
                }
};

Stepping through the code reveals that activityBCallBack is not null
when I inspect it within _service.registerActivityBCallBack(..),
however the global variable I assign activityBCallBack to in my
_service.registerActivityBCallBack(..) method is null when I try use
it from within my worker thread that is already running.  Any idea why
this would be null?

I suspect it may be null because the worker thread is started before
activity B has a chance to populate the private global variable with
activityBCallBack so it can be used to communicate with activity B.
But I most certainly do populate the global callback instance the
worker thread is trying to access before it tries to use it.

I've used the following project as a guide:
https://github.com/commonsguy/cw-andtutorials/tree/master/18-LocalService/

Many thanks for the help!

Tonez


On Apr 19, 10:03 am, Android007 <[email protected]> wrote:
> Hi,
> I had the same problem as you do (sharing a TCP connection between
> activities) and I must with Dianne that if this is the case then you had
> better use a singleton.
> In my case I needed different apps to use one connection. This was not
> possible with a singleton because each app would call a new instance of the
> singleton (as weird as this sounds) even thoug hthe singleton I made was
> inside the Platform.
> Anyway, in my case, I had to use a service (it causes a major degradation
> in speed ), but I wouldn't recommend it
>
>
>
>
>
>
>
> On Tuesday, April 17, 2012 12:26:13 AM UTC+3, Kristopher Micinski wrote:
>
> > I would agree, the best thing for this would be a service that you can
> > bind do and do AIDL calls through, along with coordinating other
> > things.  Passing the raw socket can be accomplished through the
> > application object, though that sounds fairly dirty to me.  This is a
> > fairly common use case (in chat clients, etc.., although you
> > theoretically shouldn't be this bandwidth heavy..), and one which I
> > believe is typically implemented via services.
>
> > On Mon, Apr 16, 2012 at 12:31 PM, Tonez <[email protected]> wrote:
> > > Hi Everyone,
>
> > > I'm building an Android app which uses TCP sockets to communicate with
> > > a .net server application.  The android app as a whole relies quite
> > > heavily on TCP and as such nearly all the features in the app require
> > > writing to and listening from a socket stream.  I'm trying to
> > > determine what the best design approach is for having more than one
> > > activity utilize a live active socket.
>
> > > I've recently just finished building an iPhone version of this app,
> > > the way in which I got each feature (different view controllers) to
> > > use one live active socket connection was by passing the live socket
> > > instance to each view controller, each view controller would then
> > > retain ownership of that socket and as such the delegate methods which
> > > fire when a transmission is received work as expected.  Trying to
> > > simulate this design in Android is proving to be a pain because I
> > > can't pass a live socket instance to another activity as part of an
> > > intent parameter.
>
> > > If I wanted to have activity A listen for incoming TCP data, and then
> > > navigate to Activity B but then have activity B send TCP data to
> > > the .net server and of-course spawn a new thread to listen for
> > > incoming TCP data - what would be the best approach to achieve this?
>
> > > At the moment what I have is as follows:  activity A spawns a new
> > > thread listening for incoming TCP data, activity A can communicate
> > > with the .net server perfectly fine.  When I navigate to activity B
> > > and then want to communicate with the .net server - creating a new
> > > socket instance and then listening for incoming data results in
> > > activity A's readLine() method receiving the data.  Which makes sense,
> > > it's still running - but obviously the goal is to have activity B
> > > receive this data.
>
> > > An alternative approach I tried was to close down the TCP socket I
> > > have in activity A when opening up another TCP socket connection when
> > > I need to use TCP in activity B - although this somewhat works it
> > > really feels like the wrong way to go about it.
>
> > > And lastly, one other approach I've thought of is to have one activity
> > > handling all TCP comms with the .net server and contain all the
> > > functionality in this one activity by swapping out .xml layout files
> > > when necessary.  Obviously this will result in one massive .java file
> > > and again is a route which feels wrong.
>
> > > Any advice on how I can go about designing my app given that I want to
> > > use TCP functionality in every activity would be greatly appreciated.
>
> > > Many thanks,
>
> > > Tonez
>
> > > --
> > > You received this message because you are subscribed to the Google
> > > Groups "Android Developers" group.
> > > To post to this group, send email to [email protected]
> > > To unsubscribe from this group, send email to
> > > [email protected]
> > > For more options, visit this group at
> > >http://groups.google.com/group/android-developers?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to