2013-02-20 29 views
15

Lúc đầu, tôi đã triển khai tác vụ không đồng bộ trong hoạt động của mình, gửi dữ liệu đến máy chủ. Nhưng khi tôi thay đổi hoạt động, kết nối bị mất. Để tránh cách tiếp cận của tôi này là để thực hiện một dịch vụ mà tập trung về mạng lưới hoạt động và gửi dữ liệu đến máy chủ và mã cho dịch vụ này được đưa ra dưới đâyLàm cách nào để giữ máy khách Android được kết nối với máy chủ ngay cả khi thay đổi hoạt động và gửi dữ liệu đến máy chủ?

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 là hoạt động của tôi mà tôi liên kết với dịch vụ này. Sau đây là vài đoạn mã từ hoạt động của tôi.

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(); 
} 

Bây giờ là dịch vụ này chạy ở chế độ nền, Nếu tôi muốn gửi một số dữ liệu đến máy chủ tôi sử dụng như sau

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

Trả lời

5

Mã đúng. Sai lầm duy nhất là tôi đã cố gắng để khởi động dịch vụ hai lần một lần trong phương thức onServiceConnected() và phương thức kia trong phương thức onCreate().

Tôi đã thay đổi mã của mình để chỉ bắt đầu dịch vụ trong phương thức onCreate() trong hoạt động trình khởi chạy. Phần còn lại của các hoạt động liên kết trực tiếp với dịch vụ bằng cách sử dụng phương thức doBindService()

+0

bạn vừa tiết kiệm thời gian của tôi. – BSKANIA

+0

mã trên của bạn là hoàn hảo hoặc bạn đã bắt đầu dịch vụ hai lần ở trên mã? bạn đã thay đổi mã trên? Tôi có thể thấy bạn đã bắt đầu một lần bằng phương thức startservice và một lần sử dụng phương thức doBindservice. Hãy làm đúng. Tôi là một connfuse sau khi đọc này –

+0

@sam_k Tôi đã sử dụng phương pháp startService chỉ tại mainactivity mà bắt đầu dịch vụ. Phần còn lại của các hoạt động chỉ sử dụng phương thức doBindService() trong onCreate. Đoạn mã trên được chỉnh sửa với mã đúng. Tôi không hiểu nhầm lẫn của bạn – Giz

2

Khi một dịch vụ được liên kết với một Activity, nó bị giết khi Hoạt động dừng lại, giống như một dịch vụ nền chỉ dành cho Activity. Do đó, để tiếp tục chạy, hãy triển khai phương thức onStartCommand() trong lớp Service của bạn và trả lại this.START_STICKY. và quản lý bạn đang phục vụ trong phương pháp này.

+0

Tôi đã thực hiện điều đó trong mã dịch vụ của mình. Nhưng tôi không biết cách gửi dữ liệu đến nhiệm vụ không đồng bộ để gửi nó đến máy chủ. – Giz

+0

Trong hoạt động mTcpClient luôn là null. – Giz

+0

Không, hãy kiểm tra tài liệu android của 'Dịch vụ', nếu bạn liên kết nó với' Hoạt động' bằng cách sử dụng 'Binder' thì nó sẽ tự động bị đóng. hãy thử loại bỏ nó khỏi một 'Binder' và thay vào đó hãy thử nó trong onStartCommand(). Đó là những gì tôi đang nói với bạn. – AbdulHannan

Các vấn đề liên quan