2016-11-15 29 views
4

我是新來的Android開發人員,我希望我的應用程序能夠檢測套接字事件,即使應用程序未通過後臺服務活動(所以我可以推送通知,例如,如果有一個新的消息, Whatsapp和其他人這樣做)。如何在Android中處理套接字事件作爲後臺服務?

我實現了後臺服務和啓動服務的應用程序類,但堅持在哪裏以及如何將套接字事件作爲Runnable任務放入我的後臺服務中。

我修改了下面的socket.io android chat項目示例,並添加了服務和應用程序類。

ChatApplication.java

package com.github.nkzawa.socketio.androidchat; 

import android.app.Application; 
import android.content.Intent; 
import android.content.res.Configuration; 

import io.socket.client.IO; 
import io.socket.client.Socket; 

import java.net.URISyntaxException; 

public class ChatApplication extends Application { 

    @Override 
    // called when the application is starting, before any other application objects have been created 
    public void onCreate() { 
     super.onCreate(); 

     // represents our background service 
     Intent background = new Intent(this, SocketBackgroundService.class); 
     startService(background); 
    } 

    private Socket mSocket; 
    { 
     try { 
      mSocket = IO.socket(Constants.CHAT_SERVER_URL); 
     } catch (URISyntaxException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public Socket getSocket() { 
     return mSocket; 
    } 
} 

SocketBackgroundService.java

package com.github.nkzawa.socketio.androidchat; 

import android.app.Service; 
import android.content.Intent; 
import android.os.IBinder; 
import android.util.Log; 

public class SocketBackgroundService extends Service { 
    private boolean isRunning; 
    private Thread backgroundThread; 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     this.isRunning = false; 
     this.backgroundThread = new Thread(myTask); 
    } 

    private Runnable myTask = new Runnable() { 
     @Override 
     public void run() { 
      // do something in here 
      Log.i("INFO", "SOCKET BACKGROUND SERVICE IS RUNNING"); 

      //TODO - how to handle socket events here? 
      //How do I do something like mSocket.on(Socket.EVENT_CONNECT,onConnect); here? 
     } 
    }; 

    @Override 
    public void onDestroy() { 
     this.isRunning = false; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if(!this.isRunning) { 
      this.isRunning = true; 
      this.backgroundThread.start(); 
     } 

     return START_STICKY; 
    } 
} 

回答

3

如果您需要的插座是活着你的應用程序停止後。將套接字移動到後臺服務,然後您可以在服務中添加套接字事件。

+0

語法是我實際試圖弄清楚的,如何移動S從應用程序到後臺服務中的Runnable函數。 :) – Woppi

+0

移動此私人套接字mSocket; { 嘗試mSocket = IO.socket(Constants.CHAT_SERVER_URL); catch(URISyntaxException e){ throw new RuntimeException(e); } } – Ashish

+0

轉換成SocketBackgroundService。 – Ashish

2

您在主線程上打開套接字。不要在主線程上打開套接字連接,它會爲您提供ANR(應用程序無響應)錯誤,這是由於UI線程上大量繁重工作而發生的。它阻止UI線程超過5秒。所以我建議你在服務線程中打開套接字連接。
下面是使用普通的插座例如:

  1. 對背景服務開始線程
  2. 用來打開在螺紋插座連接
  3. 用於套接字通信

    創建單獨的類上創建線程類創建一個服務類
    public class SocketBackgroundService extends Service { 
    
    private SocketThread mSocketThread; 
    
    @Override 
    public IBinder onBind(Intent intent) { 
        return null; 
    } 
    
    @Override 
    public void onCreate() { 
    
        mSocketThread = SocketThread.getInstance(); 
    } 
    
    
    @Override 
    public void onDestroy() { 
        //stop thread and socket connection here 
    } 
    
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
        if (mSocketThread.startThread) { 
        } else { 
         stopSelf(); 
        } 
    
        return START_STICKY; 
    } 
    } 
    
    public class SocketThread extends Thread { 
    
    private static SocketThread mSocketThread; 
    private SocketClient mSocketClient; 
    
    private SocketThread() { 
    } 
    
    // create single instance of socket thread class 
    public static SocketThread getInstance() { 
        if (mSocketThread == null)//you can use synchronized also 
        { 
         mSocketThread = new SocketThread(); 
        } 
        return mSocketThread; 
    } 
    
    
    public boolean startThread() { 
          =new SocketClient(); 
        if (socketClient.isConnected()) { 
         mSocketThread.start() 
         return true; 
        } 
        return false; 
    } 
    
    @Override 
    public void run() { 
        super.run(); 
        while (mSocketClient.isConnected()) { 
         // continue listen 
        } 
        // otherwise remove socketClient instance and stop thread 
    } 
    
    public class SocketClient { 
        //write all code here regarding opening, closing sockets 
        //create constructor 
        public SocketClient() { 
         // open socket connection here 
        } 
    
        public boolean isConnected() { 
         return true; 
        } 
    } 
    
+1

hello Sam,我是新來的android開發人員,想知道你在哪個部分檢測到我的代碼正在主線程上運行?通過上面的Ashish的建議,我獲得了後臺服務運行並能夠收聽套接字。當你提到這個問題時,我想改進它。這裏是我的工作代碼:https://gist.github.com/arvi/a31843d26dcd1fd69c32bbe2bb7130d7如果您可以抽出時間諮詢,非常感謝,我非常感謝。 :) – Woppi

+1

嗨Woppi,這段代碼對我來說很好。你真的做得很好,並且改進得非常好。你有任何關於這個代碼的問題嗎? –

+0

你好@Sam,我真的很感激你花時間檢閱我的代碼。它對我意義重大。所以現在我很清楚我已經很好地處理了這些線程。我今天也在鬆散社區分享了要點,以獲得一些反饋(我是arviio)https://androidchat.slack.com/messages/beginners/,並且建議我應該使用廣播接收器而不是綁定服務。有了這個,我可以在我的活動類中擺脫AppSocketEvents和ServiceConn ...並且只需使用服務即可。我還沒有看EventBus。如果我以正確的方式進行,我的問題是我的自信。 – Woppi

相關問題