Multiple Threads Reading From Same Socket
Solution 1:
A pretty straightforward and simple approach is the following:
- You create a new
Service
which runs in the background and communicates with the server through your socket - The
Service
receives data from the socket and forwards/broadcasts it to all of your Activities which are interested in receiving it (for example to update the UI) by using theLocalBroadcastManager
- All of your Activities implement a
BroadcastReceiver
and receive the data from yourService
inside theonReceive()
method
To accomplish that, you should read the introduction to Services and BroadcastReceivers to get an idea of how they work. Also to get a basic overview first, you should read about the available App Components.
EDIT, to answer the question in the comment:
You can always stop the Service
by calling stopService()
but you can also do it differently if you don't want/need all the functionality of a Service
. Instead of a Service
you could also create a simple Thread
or a HandlerThread
which communinicates with the server. From inside of your Thread, you can then forward/broadcast the data to your Activities by using the technique mentioned above (LocalBroadcastManager
).
Just to give you an example of the basic structure (code untested though):
classSocketThreadimplementsRunnable
{
staticfinalStringSOCKET_DATA_RECEIVED="com.your.package.SOCKET_DATA_RECEIVED";
staticfinalStringSOCKET_DATA_IDENTIFIER="com.your.package.SOCKET_DATA";
private Context context;
SocketThread(Context c) {
context = c.getApplicationContext();
}
@Overridepublicvoidrun() { // code running in your thread// fetch data from socket ...Intentintent=newIntent();
intent.putExtra(SOCKET_DATA_IDENTIFIER, data); // store data in your intent// send data to registered receivers
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
// your code ...
}
}
Then you have your Activities, for example MyActivity1
, MyActivity2
, ... MyActivityN
. They all register their embedded SocketDataReceiver
to receive the broadcast intent SOCKET_DATA_RECEIVED
, which is sent by your thread.
Inside your onReceive()
methods you can then extract the data from your intent
object by using the identifier SOCKET_DATA_IDENTIFIER
.
publicclassMyActivity1extendsActivity
{
privateSocketDataReceiver socketDataReceiver;
@OverrideprotectedvoidonResume() {
super.onResume();
socketDataReceiver = newSocketDataReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(
socketDataReceiver, newIntentFilter(SocketThread.SOCKET_DATA_RECEIVED));
}
@OverrideprotectedvoidonPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(socketDataReceiver);
}
privateclassSocketDataReceiverextendsBroadcastReceiver
{
@OverridepublicvoidonReceive(Context context, Intent intent) {
// intent contains your socket data,// get data from intent using SocketThread.SOCKET_DATA_IDENTIFIER
}
}
}
Solution 2:
Basically you answered your question yourself:
I can have a centralized thread which does the reading and then sends the data to all the other threads in other activities.
Meaning: of course, such a thing is possible. But you have to sit down, design and implement it. You would start by defining a reasonable interface that allows your other threads to communicate with that central service, something like:
enum RequestType { DO_THIS, DO_THAT };
interfaceServerConnectionService<T> {
List<T> performRequest(RequestType request);
}
Meaning: instead of having your different threads do "low level" talking on that socket, you create an abstraction that allows you to say: "when I need this kind of information, then I use my service; and it returns some specific answer to me). Of course, this is a very generic answer, but well, your question isn't exactly specific either.
The next step would then be to have some central (maybe singleton) implementation of that interface; which runs on its own thread, and can be used by other threads in a synchronized, well-defined way.
Final word of warning: if you don't own that server, and it has low quality and is causing trouble for you - that is not a good setup. Because no matter what you do in your code, if the server doesn't do a good job, users will perceive your app to be the problem. Users don't care if an operation fails because some remote server crashes. So the other aspect in your question is: right now, you are in a bad spot. You should spent some serious time to find ways out of there. Otherwise you will be wasting a lot of time to build workarounds for that server you are dealing with.
Post a Comment for "Multiple Threads Reading From Same Socket"