Android - 如何在服务重启时保留套接字连接
Android - How to preserve socket connection when a service is restarted
我有一个创建套接字服务器和客户端连接到它的服务。连接保持打开状态以传输数据。该服务是 START_STICKY
。因此,当用户通过从最近的任务中滑动来终止应用程序时,将再次调用 onCreate
和 onStartCommand
函数。我不想重新初始化套接字,而是保留它在用户滑动任务以终止它之前的状态,并继续不间断地传输数据。
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) {
}
}
}
我尝试了什么?
尝试在 SharedPreferences
中使用 gson
保存套接字。
无法取回套接字对象。
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()
- 在启动服务的activity中创建一个
static
保存套接字。服务恢复时始终为空。
I don't want to re-initialize the socket and instead preserve it's state as it was before the user swiped the task to kill it and keep transferring the data uninterrupted.
根据定义,这是不可能的。您的进程已终止。您的套接字会在您的进程消失时消失。
Try to save socket as using gson in SharedPreferences.
无法保留套接字。您保存了 Socket
的 toString()
,仅此而已。
您可以通过 class 扩展应用程序
来修复它
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">
我又做了一些修改,但无法保存连接。所以我想如果我可以通知我的客户我的服务器希望它在连接断开之前重新连接,我可以自动重新连接。如果有人觉得这有用。
刚刚在清单的服务标签中添加 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[=10=]");
out.flush();
out = null;
}catch(Exception e) {
System.out.println("Exception in closing connection.");
e.printStackTrace();
}
}
我有一个创建套接字服务器和客户端连接到它的服务。连接保持打开状态以传输数据。该服务是 START_STICKY
。因此,当用户通过从最近的任务中滑动来终止应用程序时,将再次调用 onCreate
和 onStartCommand
函数。我不想重新初始化套接字,而是保留它在用户滑动任务以终止它之前的状态,并继续不间断地传输数据。
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) {
}
}
}
我尝试了什么?
尝试在
SharedPreferences
中使用gson
保存套接字。 无法取回套接字对象。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()
- 在启动服务的activity中创建一个
static
保存套接字。服务恢复时始终为空。
I don't want to re-initialize the socket and instead preserve it's state as it was before the user swiped the task to kill it and keep transferring the data uninterrupted.
根据定义,这是不可能的。您的进程已终止。您的套接字会在您的进程消失时消失。
Try to save socket as using gson in SharedPreferences.
无法保留套接字。您保存了 Socket
的 toString()
,仅此而已。
您可以通过 class 扩展应用程序
来修复它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">
我又做了一些修改,但无法保存连接。所以我想如果我可以通知我的客户我的服务器希望它在连接断开之前重新连接,我可以自动重新连接。如果有人觉得这有用。
刚刚在清单的服务标签中添加 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[=10=]");
out.flush();
out = null;
}catch(Exception e) {
System.out.println("Exception in closing connection.");
e.printStackTrace();
}
}