当应用程序发送到后台时,TCP连接会停止侦听

时间:2014-08-21 18:18:03

标签: android

当我将应用程序移至后台,连接未被删除时,我的服务停止收听服务器,这就是服务器日志所说的内容。为什么会发生这种情况?使用startService启动服务。

public class LocalService extends Service {
    Socket socket = null;
    public String SERVER_IP = "192.168.1.10";
    public boolean connected = false;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            if (intent.hasCategory("connection")) {
                if (connected) {
                    try {
                        if (socket != null) {
                            socket.close();
                            connected = false;
                            // sendBroadcast(intent1);
                        }
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                else {
                    connect();
                }
            }
        }

        return START_STICKY;
    }

    public void connect() {
        Thread thread = new Thread() {
            @Override
            public void run() {
                // sendBroadcast(intent1);

                try {
                    socket = new Socket(SERVER_IP, 5000);
                    socket.setSoTimeout(5000);

                    connected = true;
                    // sendBroadcast(intent2);

                    OutputStream out = socket.getOutputStream();
                    PrintWriter output = new PrintWriter(out);
                    BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                    while (true) {
                        String event = input.readLine();
                        // sendBroadcast(intent3);

                        if (event.substring(0, 3).equals("msg")) {
                            String notificationTitle = event.substring(4, event.indexOf("::"));
                            CharSequence tickerText = event.substring(event.indexOf("::") + 2);
                            String notificationContent = event.substring(event.indexOf("::") + 2);

                            Bitmap largeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

                            NotificationCompat.Builder mBuilder =
                                    new NotificationCompat.Builder(LocalService.this)
                                            .setSmallIcon(R.drawable.ic_launcher)
                                            .setLargeIcon(largeIcon)
                                            .setTicker(tickerText)
                                            .setContentTitle(notificationTitle)
                                            .setContentText(notificationContent)
                                            .setOnlyAlertOnce(true);

                            Intent resultIntent = new Intent(LocalService.this, ResultActivity.class);
                            TaskStackBuilder stackBuilder = TaskStackBuilder.create(LocalService.this);
                            stackBuilder.addParentStack(ResultActivity.class);
                            stackBuilder.addNextIntent(resultIntent);
                            PendingIntent resultPendingIntent =
                                    stackBuilder.getPendingIntent(
                                            0,
                                            PendingIntent.FLAG_UPDATE_CURRENT
                                    );
                            mBuilder.setContentIntent(resultPendingIntent);
                            NotificationManager mNotificationManager =
                                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                            mNotificationManager.notify(mId, mBuilder.build());
                            mId = mId + 1;
                        }
                    }
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (java.net.ConnectException e) {
                    e.printStackTrace();
                    // sendBroadcast(intent4);
                } catch (SocketTimeoutException e) {
                    e.printStackTrace();
                } catch(java.net.SocketException e) {
                    e.printStackTrace();
                    connected = false;
                    // sendBroadcast(intent5);
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                    connected = false;
                    // sendBroadcast(intenty);
                }
            }
        };

        thread.start();
    }

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

    private final IBinder mBinder = new LocalBinder();
}

2 个答案:

答案 0 :(得分:1)

您需要的是粘性服务

您可以通过返回以下标志

来执行此操作
  @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("LocalService", "Received start id " + startId + ": " + intent);
        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

根据enter link description here

Constant to return from onStartCommand(Intent, int, int): if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance; if there are not any pending start commands to be delivered to the service, it will be called with a null intent object, so you must take care to check for this.

This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, such as a service performing background music playback.

我感觉它的以下循环在服务重新启动并关闭连接时被调用:

if (connected) {
                    try {
                        if (socket != null) {
                            socket.close();
                            connected = false;
                            // sendBroadcast(intent1);
                        }
                    }

答案 1 :(得分:1)

似乎您在对服务进行限制和取消绑定方面存在一些问题。 我猜你没有解除绑定到这个服务的活动,所以在你活动stoped / killed之后你的服务停止工作,因为START_STICKY它将由系统再次启动。 您应该取消绑定onPause()中的活动,并断开服务中onDestory方法中的套接字。