You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中如何连接Socket.io并接收实时股票数据?

Fixing Startup Crashes & Connecting to IEX WebSocket for Real-Time Stock Data

Hey there! Let's get your Android app connected to that IEX WebSocket and fix those startup crashes—no more head-scratching needed. 😊

First, a quick critical note: The IEX endpoint you're targeting is a standard WebSocket, not a Socket.io server. Socket.io uses its own custom protocol on top of WebSocket, so trying to use a Socket.io client here is likely causing your crash. We'll use a standard WebSocket client (OkHttp, a popular and reliable choice) instead.


Step 1: Fix the Startup Crash (Common Causes)

Your app crashing before launch usually boils down to a few easy fixes:

  • Missing internet permission: Android requires explicit permission to access the internet. Add this to your AndroidManifest.xml:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • Network operations on main thread: Android blocks network calls on the UI thread (it freezes the app!). We'll use background threads/coroutines to avoid this.
  • Missing dependencies: We'll add the OkHttp library next to handle WebSocket connections.

Step 2: Add Required Dependencies

Open your app's build.gradle (Module level) and add these dependencies in the dependencies block:

For Kotlin (with Coroutines)

// OkHttp for WebSocket support
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
// Coroutines for safe background threading
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'

For Java

// OkHttp for WebSocket support
implementation 'com.squareup.okhttp3:okhttp:4.12.0'

Sync your project to download the libraries.


Step 3: Implement WebSocket Connection & Data Handling

We'll create a reusable manager class to handle the WebSocket lifecycle, then use it in your Activity.

Kotlin Implementation

1. Create a WebSocketManager Class

This class wraps all connection logic, data listening, and cleanup:

import okhttp3.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class WebSocketManager {
    private val okHttpClient = OkHttpClient()
    private var webSocket: WebSocket? = null

    // Listener to handle WebSocket events
    private val webSocketListener = object : WebSocketListener() {
        override fun onOpen(webSocket: WebSocket, response: Response) {
            super.onOpen(webSocket, response)
            // Connection successful! Update UI on main thread
            CoroutineScope(Dispatchers.Main).launch {
                // Example: Show a "Connected" toast or update a TextView
            }
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            super.onMessage(webSocket, text)
            // This is where real-time stock data comes in!
            CoroutineScope(Dispatchers.Main).launch {
                parseStockData(text)
            }
        }

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            super.onFailure(webSocket, t, response)
            t.printStackTrace()
            // Handle errors (e.g., reconnect, show error message)
            CoroutineScope(Dispatchers.Main).launch {
                // Example: Show an error toast
            }
        }

        override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
            super.onClosing(webSocket, code, reason)
            webSocket.close(1000, "Closing connection")
        }
    }

    // Start WebSocket connection (runs in background thread)
    fun connectToIEX() {
        CoroutineScope(Dispatchers.IO).launch {
            val request = Request.Builder()
                .url("wss://ws-api.iextrading.com/1.0/stock/aapl/quote") // Use wss:// for WebSocket!
                .build()
            webSocket = okHttpClient.newWebSocket(request, webSocketListener)
            okHttpClient.dispatcher.executorService.shutdown()
        }
    }

    // Clean up connection when done
    fun disconnect() {
        webSocket?.close(1000, "User disconnected")
        webSocket = null
    }

    // Parse JSON response into a usable data object
    private fun parseStockData(jsonString: String) {
        // Use Gson or Moshi to convert JSON to a data class
        // Example with Gson:
        // val stockQuote = Gson().fromJson(jsonString, StockQuote::class.java)
        // Then update your UI with stockQuote.latestPrice, stockQuote.symbol, etc.
    }
}

// Data class to match IEX's stock quote response structure
data class StockQuote(
    val symbol: String,
    val latestPrice: Double,
    val latestTime: String,
    // Add any other fields you need from the IEX response
)

2. Use the Manager in Your Activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    private lateinit var webSocketManager: WebSocketManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        webSocketManager = WebSocketManager()
        // Start connection when the activity launches
        webSocketManager.connectToIEX()
    }

    override fun onDestroy() {
        super.onDestroy()
        // Clean up connection to avoid memory leaks
        webSocketManager.disconnect()
    }
}

Java Implementation

1. Create Connection Logic in Your Activity

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private WebSocket webSocket;
    private OkHttpClient client;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        client = new OkHttpClient();
        // Connect in background thread using AsyncTask
        new WebSocketConnectTask().execute();
    }

    private class WebSocketConnectTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            Request request = new Request.Builder()
                    .url("wss://ws-api.iextrading.com/1.0/stock/aapl/quote")
                    .build();

            webSocket = client.newWebSocket(request, new WebSocketListener() {
                @Override
                public void onOpen(WebSocket webSocket, Response response) {
                    super.onOpen(webSocket, response);
                    // Update UI on main thread
                    runOnUiThread(() -> {
                        // Example: Show "Connected" message
                    });
                }

                @Override
                public void onMessage(WebSocket webSocket, String text) {
                    super.onMessage(webSocket, text);
                    // Handle real-time data
                    runOnUiThread(() -> {
                        parseStockData(text);
                    });
                }

                @Override
                public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                    super.onFailure(webSocket, t, response);
                    t.printStackTrace();
                    runOnUiThread(() -> {
                        // Show error message
                    });
                }
            });
            client.dispatcher().executorService().shutdown();
            return null;
        }
    }

    private void parseStockData(String jsonString) {
        // Use Gson to parse JSON into a StockQuote object
        // StockQuote stockQuote = new Gson().fromJson(jsonString, StockQuote.class);
        // Update UI with stockQuote.getLatestPrice(), etc.
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (webSocket != null) {
            webSocket.close(1000, "Activity destroyed");
        }
    }
}

// StockQuote model class
class StockQuote {
    private String symbol;
    private double latestPrice;
    private String latestTime;

    // Getters and Setters
    public String getSymbol() { return symbol; }
    public void setSymbol(String symbol) { this.symbol = symbol; }
    public double getLatestPrice() { return latestPrice; }
    public void setLatestPrice(double latestPrice) { this.latestPrice = latestPrice; }
    public String getLatestTime() { return latestTime; }
    public void setLatestTime(String latestTime) { this.latestTime = latestTime; }
}

Step 4: Troubleshooting Tips

  • Still crashing? Double-check that you're not running network code on the main thread. The examples above use background threads/coroutines explicitly.
  • No data coming in? Ensure you're using wss:// instead of https:// (the latter is for HTTP, not WebSocket). Also, verify your device has a working internet connection.
  • JSON parsing errors? Use a tool like Postman to test the WebSocket endpoint and copy the exact response structure, then update your StockQuote class to match all fields.

内容的提问来源于stack exchange,提问作者killpwnrang3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:48:33