【问题标题】:Android: How to use Gottox/socket.io-java-client library with right way?Android:如何正确使用 Gottox/socket.io-java-client 库?
【发布时间】:2015-01-24 13:19:00
【问题描述】:

我有一个服务。我创建了一个 Thread 用于在此服务的单独线程上使用 socket.io-java-client 库。

我用以下方式保持线程:

@Override
public void run() {
    while (canLiveThread) {
    //  keep thread
    }
}

这种方式完全错误是吗?要解决此解决方案,我需要找到以下问题的答案:

1. 是否需要我单独创建线程才能在 Service 中使用 socket.io-java-client 库?或者我可以不使用线程使用这个库,只需在 Service 中实现 socket.io-java-client 库?

2.如果需要创建线程来使用这个库,那么如何在后台服务中以正确的方式管理线程而不耗尽电池?

如果有人有任何解决方案,请回答这个问题...

提前致谢!

【问题讨论】:

  • 我正在使用nkzawa 库来模拟 Gottox,它甚至可以与 nodejs 1.x.x 一起使用。并且不需要创建一个单独的线程,只需要一个保持套接字存活的服务。
  • @Kush Sharma 我可以在 socket.io 0.9.18 中使用这个库吗?

标签: android multithreading sockets gottox socket.io-java-client


【解决方案1】:

其实我不知道我用socket-io-client的方法对不对,但我尽量说清楚。 据我所知socket-io-client 已经在使用后台线程来连接、发送、接收事件。

第一路

我认为这不是您想要的,但我尽可能地展示了这个变体。 所以,首先,我创建了一个 SocketClient ,如下所示:

public class SocketClient implements IOCallback {

    private SocketIO socket;
    private Context context; // for some cases (i.e. broadcasting via LocalBroadcastManager).

    public SocketClient(Context context) {
       this.context = context;
    }

    public synchronized void connect() {
        if (socket == null || !socket.isConnected()) {
            Properties properties = new Properties();
            // setting your properties...
            try {
                socket = new SocketIO("http://your.address", properties);
                socket.connect(this);
            } catch (MalformedURLException e) {
                Log.e("SocketClientException", e.getMessage());
            }
        }
    }

    @Override
    public void onDisconnect() {

    }

    @Override
    public void onConnect() {

    }

    @Override
    public void onMessage(String data, IOAcknowledge ack) {

    }

    @Override
    public void onMessage(JsonElement json, IOAcknowledge ack) {

    }

    @Override
    public void on(String event, IOAcknowledge ack, JsonElement... args) {
        LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("action_on"));
    }

    @Override
    public void onError(SocketIOException socketIOException) {

    }

}

然后我创建了一个 Singleton 来保存我们的SocketClient

public class API {

    private static API instance;
    private SocketClient client;

    private API() {
    }

    public static API getInstance() {
        if (instance == null) {
            instance = new API();
        }
        return instance;
    }

    public void init(Context context) {
        client = new SocketClient(context);
    }

    public SocketClient getSocketIO() {
        return client;
    }
}

然后在ServiceonCreate() 方法中,我只是调用我的单例:

@Override
public void onCreate() {
    super.onCreate();
    Log.i("SocketService", "onCreate");
    API.getInstance().init(getApplicationContext());
    API.getSocketIO().connect();
}

之后,只要Service,套接字就会一直处于活动状态,因此我们将能够在应用程序的任何地方通过我们的单例在后台接收和发送套接字命令。我们可以通过LocalBroadcastManagerononMessage方法在SocketClient中发送接收到的数据。

第二种方式

让我们尝试实现一个SocketService

public class SocketService extends Service implements IOCallback {
    private SocketIO socket;

    private synchronized void connect() {
        if (socket == null || !socket.isConnected()) {
            Properties properties = new Properties();
            // setting your properties...
            try {
                socket = new SocketIO("http://your.address", properties);
                socket.connect(this);
            } catch (MalformedURLException e) {
                Log.e("SocketClientException", e.getMessage());
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        connect();
    }

    @Override
    public void onDisconnect() {

    }

    @Override
    public void onConnect() {

    }

    @Override
    public void onMessage(String data, IOAcknowledge ack) {

    }

    @Override
    public void onMessage(JsonElement json, IOAcknowledge ack) {

    }

    @Override
    public void on(String event, IOAcknowledge ack, JsonElement... args) {
         LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("action_on"));
    }

    @Override
    public void onError(SocketIOException socketIOException) {

    }
}

就是这样。您可以从您的活动中启动服务并通过广播或消息处理程序进行通信。我从未尝试过第二种方式,但我认为它应该像一个魅力。

结论

这些方法中没有一个使用单独的后台线程,它对我有用,我有三个基于第一种方法的应用程序,它们都在后台工作,没有任何支持的东西。希望答案对SocketIO使用中所有有趣的人有所帮助:)

【讨论】:

  • 感谢您的出色回答,但我有一个问题,您的服务在主线程中运行是吗?我不明白你为什么不为 socket.io 创建单独的线程?
  • 也许我错了,但正如您在下面的链接中看到的那样,有一个单独的线程可以与服务器进行握手和连接。该线程在您调用SocketIO socket = new SocketIO(url, properties) 时启动,因此我认为我们无需再创建一个单独的线程来在其中启动ConnectThread。我认为这是多余的。链接:github.com/Gottox/socket.io-java-client/blob/master/src/io/…
  • Vov,是的,你是绝对正确的!但我看到了示例 gottox/socket.io,它们为使用套接字 io 库创建了单独的线程:github.com/Gottox/socket.io-java-client/blob/master/examples/…。你呢?
  • 说实话,我不知道他为什么要使用单独的线程来“启动另一个单独的线程” :) 我只是认为这是因为他有一个习惯使用单独的线程时使用标准的 Java 套接字。我认为使用线程启动线程是多余的。根据我的经验,当我使用 socket-io 时,它已经在单独的线程中工作,所以我从来没有出现过“冻结 UI”的效果。不管怎样,你可以在 Github 上问 Gottox,他为什么要使用另一个单独的线程。
猜你喜欢
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
  • 2014-07-27
  • 2013-04-26
  • 1970-01-01
相关资源
最近更新 更多