2016-12-09 8 views
2

ソケットサーバーを作成してクライアントが接続するサービスがあります。接続はデータを転送するために開いたままです。サービスはSTART_STICKYです。したがって、ユーザーが最近のタスクからスワイプしてアプリを殺すと、onCreateonStartCommand関数が再び呼び出されます。私はソケットを再初期化したいのではなく、ユーザーがタスクをスワイプしてデータを強制終了し、データを途切れることなく転送し続ける前の状態を保持します。Android - サービスの再起動時にソケット接続を維持する方法

public class SendTasksService extends Service { 
    static Socket socket=null; 
    static boolean shouldRun=true; 
    static final int port = PORT_NO; 
    static ServerSocket listener = null; 

    @Override 
    public IBinder onBind(Intent intent) { 
     System.out.println("Service onBind."); 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     System.out.println("Service onCreate."); 
     shouldRun=true; 
     try { 
      if(socket==null){ 
       System.out.println("Starting Listening.."); 
       listener = new ServerSocket(port); 
       System.out.println("Notification Started."); 
      }else{ 
       System.out.println("Continuing With Old Socket.."); 
       /* 
        How to get the socket if the connection 
        was made before swipe killing the app from recent 
       */ 
      } 
     }catch(Exception ioe){ 
      System.out.println("Exception in listening."); 
      ioe.printStackTrace(); 
     } 
    } 

    public void onDestroy() { 
     System.out.println("Service onDestroy."); 
     closeConnection(); 
    } 

    public void closeConnection(){ 
     //Wind up work and close connection 
     /* 
      This should also remove any socket information saved anywhere 
     */ 
    } 

    public int onStartCommand(Intent intent, int flags, int startid) { 
     System.out.println("Service onStartCommand."); 
     try{ 
      new AsyncAction().execute(); 
     }catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return START_STICKY; 
    } 

    private class AsyncAction extends AsyncTask<String, Void, String> { 
     protected String doInBackground(String... args) { 
      while(shouldRun) { 
       try { 
        if(socket==null) { 
         socket = listener.accept(); 
         /* 
          Socket connection established here. 
          Save this socket state or preserve it somehow 
          So that connection does not break on killing the app 
         */ 
        }else{ 
         /* 
          Continue with the old socket data, and resume connection 
         */ 
        } 
        if(socket==null) 
         continue; 
       }catch(Exception e){ 
        System.out.println("Exception after Break"); 
        e.printStackTrace(); 
       } 
      } 
      return null; 
     } 

     protected void onPostExecute(String result) { 
     } 
    } 
} 

何を試してみましたか?

  1. SharedPreferencesgsonを使用してソケットを保存するようにしてください。 ソケットオブジェクトを戻すことができませんでした。

    SharedPreferences pref = getApplicationContext(). 
            getSharedPreferences("MyPref", MODE_PRIVATE); 
    SharedPreferences.Editor editor = pref.edit(); 
    editor.putBoolean("onGoingConnection",false); 
    Gson gson = new Gson(); 
    String json = gson.toJson(socket); 
    editor.putString("ExistingSocket",json); 
    editor.apply() 
    
  2. サービスを開始したアクティビティにstaticセービングソケットを作成します。サービス再開時には常にnullだった。

答えて

0

ような何かをし、その後マニフェストに私はいくつかのより多くの工夫をしましたし、保存するために動き回ることができませんでした接続。だから私は、私のサーバが接続が切断される前に再接続したいことをクライアントに知らせることができたら、私は自動的に再接続することができると考えました。誰かがこれを見つけると便利です。 マニフェストのサービスタグにandroid:stopWithTask="false"を追加し、サービス内のonTaskRemovedを削除しました。 onTaskRemovedでは、クライアントに信号を送り、サーバーに再接続しました。

public void onTaskRemoved(Intent rootIntent) { 
    System.out.println("Service onTaskRemoved."); 
    try { 
     PrintWriter out = new PrintWriter(socket.getOutputStream()); 
     out.print("RECONNECT\0"); 
     out.flush(); 
     out = null; 
    }catch(Exception e) { 
     System.out.println("Exception in closing connection."); 
     e.printStackTrace(); 
    } 
} 
0

私はソケットを再初期化し、代わりに、ユーザはそれを殺すし、途切れのないデータ転送を維持するためのタスクをスワイプする前にそれがあったとして、それは状態だ保存する必要はありません。

定義上、これは不可能です。あなたのプロセスは終了しました。あなたのプロセスがしているときにあなたのソケットがなくなります。

SharedPreferencesにgsonを使用してソケットを保存するようにしてください。

ソケットは永続化できません。 SockettoString()を保存しました。

+0

私の接続が破壊されるのを防ぐことはできませんか?別の解決策は、データグラムを使用することができますが、それは私のクライアントも変更する必要があります。 – dumplingParadox

+0

@dumplingParadox: "私の接続が破壊されないように保存できませんか?" - 正しい。あなたは、たとえサービスであっても、あなたのプロセスが永遠に続くと想定することはできません。プロセスが終了すると、システムが「START_STICKY」を使用していても、プロセスが再起動するまでに時間がかかることがあります。プロセスがなく、サーバーに接続していない任意の時間をサポートするようにアプリケーションを設計する必要があります。 – CommonsWare

+0

私はその周りに道を見いだしました、あなたは状態を救うことができないということについて正しいです。正解と表示されます。 :)) – dumplingParadox

0

あなたはクラスがアプリケーション

public class Engine extends Application { 
@Override 
public void onCreate() { 
    super.onCreate(); 
    /* do something here */ 

} 
} 

を拡張することによってそれを修正することができ、

<manifest...> 

<application 
    android:name=".[yourclassname]" // 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
+0

カスタム 'Application'クラスはプロセスの終了を止めません。 – CommonsWare

+0

しかし、問題はソケットの状態を保持することですか? – 1shubhamjoshi1

関連する問題