长连接指客户端与服务器之间建立的持久化连接,区别于每次请求重新建立的短连接,在安卓应用中,长连接常用于实时通信(如聊天)、状态同步(如定位)、推送服务等场景。
核心特点:
协议 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
TCP | 自定义协议、文件传输 | 通用性强,支持全双工通信 | 需自行处理心跳、断线重连 |
WebSocket | 浏览器兼容、即时通讯 | 标准协议,支持跨域,低延迟 | 依赖浏览器支持,安卓需兼容低版本 |
MQTT | 物联网、消息推送 | 轻量级,支持主题订阅,省电 | 需部署 MQTT Broker,协议复杂度较高 |
TCP
的原生 Socket
// 创建客户端 Socket Socket socket = new Socket("server_ip", port); // 发送数据 OutputStream out = socket.getOutputStream(); out.write("Hello Server".getBytes()); // 接收数据 InputStream in = socket.getInputStream(); byte[] buffer = new byte[1024]; int len = in.read(buffer); String response = new String(buffer, 0, len);
OkHttp
库(推荐)OkHttpClient client = new OkHttpClient.Builder() .readTimeout(0, TimeUnit.MILLISECONDS) // 禁用读取超时 .build(); Request request = new Request.Builder() .url("wss://yourserver.com/socket") // WebSocket 地址 .build(); WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() { @Override public void onOpen(WebSocket webSocket, Response response) { // 连接成功 } @Override public void onMessage(WebSocket webSocket, String text) { // 接收消息 } });
// Android 端使用 Socket.IO 客户端 IO.Options opts = new IO.Options(); opts.secure = true; // 启用 SSL Socket socket = IO.socket("https://yourserver.com", opts); socket.connect(); socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { @Override public void call(Object... args) { // 连接成功 } });
// 使用 Handler 定时发送心跳 Handler handler = new Handler(Looper.getMainLooper()); Runnable heartbeat = () -> { if (socket.isConnected()) { socket.getOutputStream().write("HEARTBEAT".getBytes()); } handler.postDelayed(heartbeat, 30_000); // 30秒一次 }; handler.post(heartbeat);
NetworkCallback
),断线后自动重连。ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkRequest request = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(); cm.registerNetworkCallback(request, new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { // 网络恢复,尝试重连 reconnect(); } });
Doze
模式后断开)。JobScheduler
或 WorkManager
调度心跳任务。private void reconnect() { int retryCount = 0; while (retryCount < MAX_RETRY) { try { socket = new Socket("server_ip", port); break; // 重连成功 } catch (IOException e) { retryCount++; try { Thread.sleep((long) Math.pow(2, retryCount) 1000); } catch (InterruptedException ex) {} } } }
// OkHttp 启用 HTTPS OkHttpClient client = new OkHttpClient.Builder() .sslSocketFactory(SSLContext.getDefault().getSocketFactory(), trustManager) .build();
解答:
Foreground Service
并显示通知,避免被系统回收。AndroidManifest.xml
中声明 android:killBackgroundProcesses="false"
(需用户授权)。解答: