Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 线程上的联接阻止了Kotlin对象初始化_Android_Multithreading_Sockets_Object_Kotlin - Fatal编程技术网

Android 线程上的联接阻止了Kotlin对象初始化

Android 线程上的联接阻止了Kotlin对象初始化,android,multithreading,sockets,object,kotlin,Android,Multithreading,Sockets,Object,Kotlin,我正在Kotlin中编写一个Android应用程序,它将成为我的团队开发的服务器的客户端。我想创建一个对象连接,用于存储与服务器的套接字连接有关的所有必要数据: object Connection { const val HOST = "host_name" // in project it is well defined const val PORT = 52137 const val TIMEOUT = 5000 val socket: Socket = S

我正在Kotlin中编写一个Android应用程序,它将成为我的团队开发的服务器的客户端。我想创建一个对象
连接
,用于存储与服务器的套接字连接有关的所有必要数据:

object Connection {
    const val HOST = "host_name" // in project it is well defined
    const val PORT = 52137
    const val TIMEOUT = 5000

    val socket: Socket = Socket()

    /* ... */

    val connectData = MutableLiveData<String>()
    val errorData = MutableLiveData<String>()

    init {
        val connect = Thread({
            val address = InetSocketAddress(HOST, PORT)
            socket.connect(address, TIMEOUT)
        })
        connect.uncaughtExceptionHandler = Thread.UncaughtExceptionHandler({ t, e ->
            e.printStackTrace()
        })
        connect.start()
        connect.join()
        /*
        some more data processing
        */
    }
    /*
    some functions
    */
}

我知道Kotlin中的对象是延迟初始化的,所以连接对象在调用
Connection.connectData.observe(this,observator(this::displayConnectData))
时开始初始化,但我不知道为什么它会卡在
connect.join()
上,尽管定义了连接超时。我可以很容易地解决这个问题,还是应该对此对象采取不同的方法?

即使有效,这种方法是否也有缺陷?在建立连接的过程中,你不允许像那样阻塞UI线程,让整个应用程序完全冻结,这很容易需要几秒钟。将你的网络内容放在后台线程上,不要“同步等待”
class LoginActivity: AppCompatActivity() {

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

        Connection.connectData.observe(this, Observer(this::displayConnectData))
        Connection.errorData.observe(this, Observer(this::displayError))

        val viewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)

        login_button.setOnClickListener({
            val loggedIn = viewModel.login(username.text.toString(), password.text.toString())
            if (loggedIn) {
                val intent = Intent(this, MainMenuActivity::class.java)
                startActivity(intent)
                finish()
            }
        })
    }


    private fun displayConnectData(message: String?) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

    private fun displayError(message: String?) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

}