【问题标题】:Android socket connect in backgroundAndroid套接字在后台连接
【发布时间】:2017-09-14 14:41:07
【问题描述】:

当应用程序在后台时,我应该怎么做才能保持服务器运行和监听?

我目前抛出一个错误:我无法建立连接,因为目标计算机正在积极拒绝连接。

我在 android 上有服务器,在 pc/python 上有客户端。

任何人都可以解释我将不胜感激。 使用我的服务器编写代码。

public class MainActivity extends Activity {

private ServerSocket serverSocket;

Handler updateConversationHandler;

Thread serverThread = null;

private TextView text;

public static final int SERVERPORT = 8080;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    text = (TextView) findViewById(R.id.textView);

    updateConversationHandler = new Handler();

    this.serverThread = new Thread(new ServerThread());
    this.serverThread.start();

}

@Override
protected void onStop() {
    super.onStop();
    try {
        serverSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

class ServerThread implements Runnable {

    public void run() {
        Socket socket = null;
        try {
            serverSocket = new ServerSocket(SERVERPORT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (!Thread.currentThread().isInterrupted()) {

            try {

                socket = serverSocket.accept();

                CommunicationThread commThread = new CommunicationThread(socket);
                new Thread(commThread).start();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class CommunicationThread implements Runnable {

    private Socket clientSocket;

    private BufferedReader input;

    public CommunicationThread(Socket clientSocket) {

        this.clientSocket = clientSocket;

        try {

            this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() {

            try {

                String read = input.readLine();

                updateConversationHandler.post(new updateUIThread(read));

            } catch (IOException e) {
                e.printStackTrace();
            }

    }

}

class updateUIThread implements Runnable {
    private String msg;

    public updateUIThread(String str) {
        this.msg = str;
    }
    @Override
    public void run() {
        if (msg == null) {
            text.setText(msg);
        }
        else{
            text.setText(msg);
            createNotification();
        }
    }
}
void createNotification() {

    Intent intent = new Intent(this, MainActivity.class);
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);

    Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

    Notification noti = new NotificationCompat.Builder(this)
            .setContentTitle("NOTIFICATION")
            .setContentText("NOTIFICATION")
            .setTicker("NOTIFICATION")
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setLargeIcon(icon)
            .setAutoCancel(true)
            .setContentIntent(pIntent)
            .build();

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    notificationManager.notify(0, noti);
}}

【问题讨论】:

    标签: android sockets background serversocket


    【解决方案1】:

    要在 Android 中执行后台任务,您应该使用服务。
    服务器的服务如下所示:

    public class MyService extends Service {
    
        public static final String START_SERVER = "startserver";
        public static final String STOP_SERVER = "stopserver";
        public static final int SERVERPORT = 8080;
    
        Thread serverThread;
        ServerSocket serverSocket;
    
        public MyService() {
    
        }
    
        //called when the services starts
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            //action set by setAction() in activity
            String action = intent.getAction();
            if (action.equals(START_SERVER)) {
                //start your server thread from here
                this.serverThread = new Thread(new ServerThread());
                this.serverThread.start();
            }
            if (action.equals(STOP_SERVER)) {
                //stop server
                if (serverSocket != null) {
                    try {
                        serverSocket.close();
                    } catch (IOException ignored) {}
                }
            }
    
            //configures behaviour if service is killed by system, see documentation
            return START_REDELIVER_INTENT;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
    
        class ServerThread implements Runnable {
    
            public void run() {
                Socket socket;
                try {
                    serverSocket = new ServerSocket(SERVERPORT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                while (!Thread.currentThread().isInterrupted()) {
    
                    try {
    
                        socket = serverSocket.accept();
    
                        CommunicationThread commThread = new CommunicationThread(socket);
                        new Thread(commThread).start();
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        class CommunicationThread implements Runnable {
    
            private Socket clientSocket;
    
            private BufferedReader input;
    
            public CommunicationThread(Socket clientSocket) {
    
                this.clientSocket = clientSocket;
    
                try {
    
                    this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
    
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            public void run() {
    
                try {
    
                    String read = input.readLine();
    
                    //update ui
                    //best way I found is to save the text somewhere and notify the MainActivity
                    //e.g. with a Broadcast
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
        }
    }
    

    在你的Activity中,你可以通过调用来启动Service:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        //will start the server
        Intent startServer = new Intent(this, MyService.class);
        startServer.setAction(MyService.START_SERVER);
        startService(startServer);
    
        //and stop using
        Intent stopServer = new Intent(this, MyService.class);
        stopServer.setAction(MyService.STOP_SERVER);
        startService(stopServer);
    }
    

    您还必须在您的 AndroidManifest.xml 中声明 Internet 权限。将这些添加到标记上方的行:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    

    【讨论】:

      【解决方案2】:

      您是在局域网上还是通过互联网 (WAN) 进行测试?

      必须考虑到,目前许多移动电话提供商没有为连接的设备分配公共 IP 地址,他们分配私有 IP,因此设备不能充当服务器,因为它的端口无法从 WAN 访问

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-28
        • 2013-12-26
        • 1970-01-01
        相关资源
        最近更新 更多