1

我正在开发一个应用程序并在其上使用 Socket.io,我在扩展 Application 的类中初始化套接字,如下所示:

public class Inicio extends Application{
    private Socket mSocket;
    private SharedPreferences spref;

    @Override
    public void onCreate(){
        super.onCreate();
        try{
            spref = getSharedPreferences("accountData", Context.MODE_PRIVATE);
            IO.Options op = new IO.Options();
            op.forceNew = true;
            op.reconnection = true;
            op.query = "tok=" + spref.getString("sessiontoken", "") + "&usr=" + spref.getString("userid", "");
            mSocket = IO.socket(Constants.serverAddress, op);
        }catch(URISyntaxException e){
            throw new RuntimeException(e);
        }
    }

    public Socket getmSocket(){
        return mSocket;
    }
}

因此,我可以在应用程序代码的其他部分调用以下方式获取和使用相同的套接字实例:

Inicio appClass = (Inicio) getApplication();
mSocket = appClas.getmSocket();
mSocket.connect();

但是有一个小问题促使我发布这个问题,当我在 Application 类中调用 SharedPreferences 时,你能看到吗?我这样做是因为我需要发送会话令牌和用户帐户 ID 以正确启动与我的服务器的套接字连接,问题是:

假设一个用户第一次打开应用程序并且还没有帐户,他将登录或注册,然后会话令牌和用户 ID 将被保存到 SharedPreferences,但是当应用程序启动并运行 Application 类时,SharedPreferences仍然是空的,并且没有建立连接所需的令牌和用户 ID,因此用户现在必须重新打开应用程序才能成功使用套接字。

所以我问你:我有哪些解决问题的替代方案?除了 Application 类之外,还有其他结构可以用来避免这个问题吗?或者有什么方法可以绕过这个问题?

我现在要解决的问题是在登录时以编程方式重新启动应用程序,但我相信这看起来像是一个可悲的笑话,而不是理想的方法。

谢谢,对于我的这个冗长的问题,我深表歉意,但我将不胜感激。

4

1 回答 1

1

分离您的soket创建逻辑,如下所示:

private void createSoket() {
    spref = getSharedPreferences("accountData", Context.MODE_PRIVATE);
    String sessiontoken = spref.getString("sessiontoken", "");
    String userId = spref.getString("userid", "");

    if(!(TextUtils.isEmpty(sessiontoken) || TextUtils.isEmpty(userId))) {
        try {

            IO.Options op = new IO.Options();
            op.forceNew = true;
            op.reconnection = true;
            op.query = "tok=" + sessiontoken + "&usr=" + userId;
            mSocket = IO.socket(Constants.serverAddress, op);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
}

并在需要时检查null并在传递实例之前创建。

public Socket getmSocket(){
    if(mSoket == null)
        createSoket();

    return mSocket;
}

注意:没有有效settionTokenand userIdsoket为空

这是完整的应用程序类:

public class Inicio extends Application{
    private Socket mSocket;
    private SharedPreferences spref;

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

    private void createSoket() {
        spref = getSharedPreferences("accountData", Context.MODE_PRIVATE);
        String sessiontoken = spref.getString("sessiontoken", "");
        String userId = spref.getString("userid", "");

        if(!(TextUtils.isEmpty(sessiontoken) || TextUtils.isEmpty(userId))) {
            try {

                IO.Options op = new IO.Options();
                op.forceNew = true;
                op.reconnection = true;
                op.query = "tok=" + sessiontoken + "&usr=" + userId;
                mSocket = IO.socket(Constants.serverAddress, op);
            } catch (URISyntaxException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public Socket getmSocket(){
        if(mSoket == null)
            createSoket();

        return mSocket;
    }
}
于 2019-12-04T20:12:44.090 回答