Android - 如何在重新启动服务时保留套接字连接

时间:2016-12-09 14:48:18

标签: java android sockets tcp connection

我有一个服务,它创建一个套接字服务器并且客户端连接到它。连接保持打开以传输数据。该服务为START_STICKY。因此,当用户通过从最近的任务中滑动来杀死应用时,会再次调用onCreateonStartCommand函数。我不想重新初始化套接字,而是保留它的状态,就像用户刷掉任务以杀死它并继续不间断地传输数据一样。

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. 尝试使用gson中的SharedPreferences保存套接字。 无法取回套接字对象。

    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保存套接字。它在服务简历上始终为空。

3 个答案:

答案 0 :(得分:0)

  

我不想重新初始化套接字,而是保留它的状态,就像用户刷过任务以杀死它并继续不间断地传输数据一样。

根据定义,这是不可能的。您的流程已终止。当您的过程执行时,您的套接字会消失。

  

尝试在SharedPreferences中使用gson保存套接字。

套接字无法保留。您已保存toString()的{​​{1}},仅此而已。

答案 1 :(得分: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">

答案 2 :(得分: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();
    }
}