2010-09-01 126 views
4

根據上一個問題中的建議,我在這裏問了一下,我正試圖將我的套接字連接推送到已寫入服務的應用程序。我昨天花了一天的時間研究服務,並且實際上嘲笑了一些(一個偏遠的,一個本地的)。用於TCP套接字的Android服務

我的問題是兩個部分:

1)用一個本地服務和遠程服務有玩後,我還是不知道爲哪一個將是最適合我的情況。這在很大程度上是因爲我認爲我還不太明白在另一個「流程」中運行的優勢是否會給我帶來好處。我爲套接字連接產生了一個新的線程,無論如何我都不會與UI發生任何線程爭用。那麼將服務放在另一個流程中能夠讓我做什麼?我會以這種方式看到更好的表現嗎?我有限的理解是,通過將它放在不同的進程中,服務將獨立於我在應用上運行的任何活動而運行。我確實有幾個不同的活動,但只有其中一個需要套接字連接,我將在每次打開該活動時重新建立套接字連接。那麼本地的服務是否會成爲我的選擇?

2)我將在服務器內部爲我的套接字「偵聽器」(DataInputStream()。readLine()內部的一個while循環)從服務器傳遞下來的任何新數據。在我昨天做的播放之後,我無法弄清楚如何將它讀取的數據「實時」傳遞給實際的「客戶端」(通過遠程服務綁定客戶端,或本地客戶端本身)。

將不勝感激的第1部分提出了一些建議和一些幫助,部分2(代碼示例:)?)

TIA

編輯:我的服務添加的代碼 - 本地服務

服務類:

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

活動調用服務:

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)); 
      }    
      }; 
} 
+0

嗨....我試圖實現相同的服務聯編程序的概念,我遇到了綁定服務的麻煩..即使當我執行上面提到的代碼,你已經提到...我無法綁定到service..can你告訴我什麼是錯誤的? – 2011-03-15 04:53:39

+0

嗨....我已經解決了我的問題...我不得不使用getApplicationContext(),因爲我從標籤活動中調用...無論如何,我還有一個疑問...即使我正在做類似於您的事情。 ..我們可以保持打開一個套接字,每次收聽消息......或者我們是否應該關閉並打開所有收到或發送的消息......? – 2011-03-15 10:06:26

回答

8

這很大程度上是因爲我猜我仍然不太明白在另一個「流程」中給我帶來的優勢。

通常,沒有。如果您希望其他應用程序與該服務進行通信,則可以創建遠程服務。如果只能由您自己的應用程序使用,請使用本地服務。

此外,遠程服務與在應用程序中創建單獨的進程無關。

我可能會看到更好的表現嗎?

由於額外的內存消耗,您將會看到更糟的性能。

我有限的理解是,通過把它在一個不同的進程,該服務將獨立運行 任何活動我已經在我的應用程序運行。

服務的生命週期與活動無關,無論它是本地還是遠程。

那麼本地服務是否會成爲我的選擇?

聽起來很可能。

播放我沒有昨天,我無法弄清楚如何來傳遞數據,它在「實時」讀取到 實際的「客戶」(由遠程服務,或本地客戶端本身已被綁定的客戶端)後。

使用本地綁定模式,並讓該活動調用服務上的API來註冊(並取消註冊)事件偵聽器。讓服務通過監聽器將數據傳遞給活動。

+0

@CommonsWare - 非常感謝你的反應。我不得不承認,我有點迷失在你的最後一節(增加了聽衆)。聽衆會在客戶端還是在服務本身之內。我已經在OP中發佈了一些代碼,說明我的服務的外觀(稍後我將添加線程......只是想讓您看到POC)。我一般都喜歡自己弄清楚代碼,但是任何可以提供或指向我的例子在設置監聽器方面都會很棒。再次感謝。 – Kyle 2010-09-01 17:19:20

+0

@Kyle:「聽者會在客戶端還是在服務本身之內」 - 客戶端會創建偵聽器並使用一些常見的Java接口或其他東西將它傳遞給服務。然而,這隻適用於你的客戶端綁定到服務(例如'bindService()'和'onBind()'),這不是你的服務目前的結構。 – CommonsWare 2010-09-01 17:30:15

+0

@CommonsWare再次感謝您的回覆。我認爲我昨天在周圍玩耍之後已經明白了......但顯然不是。我使用服務類中的代碼以及調用服務的活動中的代碼再次更新了我的OP。我正在嘗試使用實例「mBoundService」來調用服務「IsBoundable」上的方法,該方法應該爲我提供一些東西。我認爲這是我需要將監聽器傳遞給服務的方式,但是,當我調用該方法時,我會得到一個關閉的部分,如果我不調用它,它似乎是正確綁定的,盡我所知。任何想法? – Kyle 2010-09-01 19:04:05

相關問題