Android service pour les Sockets TCP
Fondée sur une proposition lors d'une précédente question, j'ai demandé ici, je suis en train de pousser ma connexion de socket pour une application que j'ai écrit dans un service. J'ai passé la meilleure partie de la journée hier, la recherche de services et de fait se moquaient un peu (une seule télécommande, un local).
Ma question est en deux parties:
1) après avoir joué à la fois un service de proximité et un service distant, je ne suis toujours pas sûr de savoir laquelle serait le mieux pour ma situation. Cela est dû en grande partie au fait que je suppose que je n'ai toujours pas très bien quels sont les avantages de l'exécution d'un autre processus " va me donner. Je suis en lançant un nouveau fil pour la connexion de socket n'importe quoi donc je n'aurai pas de fil de contention avec l'INTERFACE utilisateur. Donc, ce ne mettre en service dans un autre processus me permettre de faire? Vais-je potentiellement de meilleures performances de cette façon? Ma compréhension limitée est qu'en le mettant dans un processus différent, le service fonctionnera indépendamment de toute activité que j'ai en cours d'exécution sur mon application. J'ai quelques activités différentes, mais un seul d'entre eux nécessite la connexion de socket qui je vais reconstruire à chaque fois que l'activité est ouverte toute façon. Alors serait-service de proximité-être la solution pour moi?
2) je vais avoir mon socket "listener" (DataInputStream().readLine() à l'intérieur d'une boucle while) à l'intérieur de mon service pour toutes les nouvelles données qui est transmis vers le bas à partir du serveur. Après la lecture, j'ai fait hier, je ne pouvais pas comprendre comment transmettre les données qu'il lit à l'actuel "client" (à destination d'un client en service à distance ou en local pour le client lui-même) en "temps réel".
Serions très heureux de recevoir des suggestions pour la partie 1, et un peu d'aide avec la partie 2 (exemples de code? :))
TIA
Edit: ajout d'un code de mon service avec le service local
Classe De Service:
public class SocketService extends Service {
Socket s;
PrintStream os;
@Override
public IBinder onBind(Intent arg0) {
//TODO Auto-generated method stub
return myBinder;
}
private final IBinder myBinder = new LocalBinder();
public class LocalBinder extends Binder {
public SocketService getService() {
return SocketService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
s = new Socket();
}
public void IsBoundable(){
Toast.makeText(this,"I bind like butter", Toast.LENGTH_LONG).show();
}
public void onStart(Intent intent, int startId){
super.onStart(intent, startId);
Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show();
Runnable connect = new connectSocket();
new Thread(connect).start();
}
class connectSocket implements Runnable {
@Override
public void run() {
SocketAddress socketAddress = new InetSocketAddress("192.168.1.104", 4505);
try {
s.connect(socketAddress);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
try {
s.close();
} catch (IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
s = null;
}
}
Activité de service d'appels:
public class SocketServiceController extends Activity {
private SocketService mBoundService;
private Boolean mIsBound;
public SocketServiceController ssc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ssc = this;
setContentView(R.layout.main);
Button start = (Button)findViewById(R.id.serviceButton);
Button stop = (Button)findViewById(R.id.cancelButton);
start.setOnClickListener(startListener);
stop.setOnClickListener(stopListener);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((SocketService.LocalBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
private void doBindService() {
bindService(new Intent(SocketServiceController.this, SocketService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
mBoundService.IsBoundable();
}
private void doUnbindService() {
if (mIsBound) {
//Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
private OnClickListener startListener = new OnClickListener() {
public void onClick(View v){
startService(new Intent(SocketServiceController.this,SocketService.class));
doBindService();
}
};
private OnClickListener stopListener = new OnClickListener() {
public void onClick(View v){
stopService(new Intent(SocketServiceController.this,SocketService.class));
}
};
}
salut....j'ai résolu mon problème... j'ai dû utiliser getcontexteapplication() comme je l'ai été d'appeler à partir d'un onglet de l'activité... de toute façon je n'ai plus de doute... même moi, je suis en train de faire quelque chose de similaire à la vôtre... peut-on garder une douille ouverte et écouter les messages à chaque fois... ou doit-on fermer et ouvrir à tous les entrants ou des messages envoyés... ?
OriginalL'auteur Kyle | 2010-09-01
Vous devez vous connecter pour publier un commentaire.
En général, aucune. Vous créez un service à distance, si vous vous attendez à d'autres applications de communiquer avec le service. Si il ne sera utilisé que par votre propre application, utiliser un service de proximité.
Également, un service distant n'a rien à voir avec la création d'un processus distinct au sein de votre application.
Vous verrez pire performance de cette façon, en raison de la mémoire supplémentaire de la consommation.
Services ont un cycle de vie indépendant des activités, qu'il soit local ou distant.
Sons probable.
Utiliser le motif de liaison, et de l'activité de l'appel d'une API sur le service à enregistrer (et annuler l'inscription) un écouteur d'événement. Le service transmettre les données à l'activité par l'auditeur.
l'auditeur d'aller sur le client ou au sein du service lui-même" -- le client serait de créer l'auditeur et de le transmettre au service, à l'aide de certaines communes de l'interface Java ou quelque chose. Toutefois, cela ne fonctionne que si votre client est obligatoire pour le service (par exemple,
bindService()
etonBind()
), ce qui n'est pas la manière dont le service est actuellement structuré.Merci encore pour la réponse. Je pensais que je l'avais cloué après ma caresse autour d'hier...mais apparemment pas. J'ai mis à jour mon OP de nouveau par le code de la classe de service ainsi que le code de l'activité qui appelle le service. Je suis en train d'utiliser l'instance "mBoundService" pour appeler une méthode sur le service "IsBoundable" qui devrait juste toast quelque chose pour moi. Je me figure ce est la façon dont je"d besoin de passer à l'auditeur de ce service, cependant, je reçois une force de fermeture lorsque j'appelle cette méthode. Si je ne l'appelez pas, il semble être de liaison correctement du mieux que je peux en dire. Des idées?
Je suis toujours coincé ici. J'ai lu vos commentaires ici: stackoverflow.com/questions/2440548/... pour un problème similaire, et vous dites que le bindService() la méthode devrait commencer mon service avec l'BIND_AUTO_CREATE drapeau. Ce n'est pas de commencer mon service. Je me rends compte que c'est une sorte de hors sujet en ce qui concerne ma question d'origine, mais il me fait me demander si mon mBoundService est réellement lié. Je sais que le service ne démarre pas parce que c'est pas de la connexion à mon serveur socket alors que quand j'utilise startservice (), il le fait.
Voici un exemple d'un projet à l'aide d'un service de proximité et le local motif de liaison: github.com/commonsguy/cw-android/tree/master/Service/...
OriginalL'auteur CommonsWare