如何保持Android客户端连接到服务器甚至在活动更改和发送数据到服务器?

我最初在我的活动中实现了一个asynchronous任务,它将数据发送到服务器。 但是,当我改变活动连接丢失。 为了避免这种情况,我的方法是实现集中networking操作并将数据发送到服务器的服务,下面给出了此服务的代码

import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; import android.widget.Toast; public class SocketService extends Service { public static final String SERVERIP = ""; //your computer IP address should be written here public static final int SERVERPORT = 5000; PrintWriter out; Socket socket; InetAddress serverAddr; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub System.out.println("I am in Ibinder onBind method"); return myBinder; } private final IBinder myBinder = new LocalBinder(); TCPClient mTcpClient = new TCPClient(); public class LocalBinder extends Binder { public SocketService getService() { System.out.println("I am in Localbinder "); return SocketService.this; } } @Override public void onCreate() { super.onCreate(); System.out.println("I am in on create"); } public void IsBoundable(){ Toast.makeText(this,"I bind like butter", Toast.LENGTH_LONG).show(); } public void sendMessage(String message){ if (out != null && !out.checkError()) { System.out.println("in sendMessage"+message); out.println(message); out.flush(); } } @Override public int onStartCommand(Intent intent,int flags, int startId){ super.onStartCommand(intent, flags, startId); System.out.println("I am in on start"); // Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show(); Runnable connect = new connectSocket(); new Thread(connect).start(); return START_STICKY; } class connectSocket implements Runnable { @Override public void run() { try { //here you must put your computer's IP address. serverAddr = InetAddress.getByName(SERVERIP); Log.e("TCP Client", "C: Connecting..."); //create a socket to make the connection with the server socket = new Socket(serverAddr, SERVERPORT); try { //send the message to the server out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); Log.e("TCP Client", "C: Sent."); Log.e("TCP Client", "C: Done."); } catch (Exception e) { Log.e("TCP", "S: Error", e); } } catch (Exception e) { Log.e("TCP", "C: Error", e); } } } @Override public void onDestroy() { super.onDestroy(); try { socket.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } socket = null; } } 

Rotator.java是我绑定到这个服务的活动。 以下是我的活动中的几段代码。

 private ServiceConnection mConnection = new ServiceConnection() { //EDITED PART @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub mBoundService = ((SocketService.LocalBinder)service).getService(); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub mBoundService = null; } }; private void doBindService() { bindService(new Intent(Rotator.this, SocketService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; if(mBoundService!=null){ mBoundService.IsBoundable(); } } private void doUnbindService() { if (mIsBound) { // Detach our existing connection. unbindService(mConnection); mIsBound = false; } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); gestureDetector = new GestureDetector(this, new GestureListener()); setContentView(R.layout.activity_rotator); //Binding the activity to the service to perform client-server operations //start service on create startService(new Intent(Rotator.this,SocketService.class)); doBindService(); ........... ........... } @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); } 

现在,这个服务在后台运行,如果我想发送一些数据到服务器,我使用以下

  if(mBoundService!=null) { mBoundService.sendMessage("right"); } 

Solutions Collecting From Web of "如何保持Android客户端连接到服务器甚至在活动更改和发送数据到服务器?"

代码是正确的。 唯一的错误是我试图在onServiceConnected()方法中启动两次服务,而在onCreate()方法中另一次。

我改变了我的代码,只在启动器活动的onCreate()方法中启动服务。 其余的活动通过使用doBindService()方法直接绑定到服务

当一个服务被绑定到一个Activity ,当Activity停止时它就会被终止,就像一个仅用于Activity的后台服务。 因此,为了保持它的运行,在你的Service类中实现onStartCommand()方法并返回this.START_STICKY 。 并用这种方法pipe理你的服务。