【问题标题】:Is correct start Kotlin coroutines from Activity java file?从 Activity java 文件中正确启动 Kotlin 协程是否正确?
【发布时间】:2019-07-15 10:05:08
【问题描述】:

Android Studio 3.4

classpath 'com.android.tools.build:gradle:3.4.2'

在 Kotlin 文件中:TransportService.kt

import kotlinx.coroutines.*
import retrofit2.Response


  @JvmStatic
        fun doLoginFromJava(
            email: String,
            password: String,
            isCustomtHandle: Boolean = false
        ): CompletableFuture<Response<*>> = GlobalScope.future {
            login(email, password, isCustomtHandle)
        }


suspend fun login(email: String, password: String, isCustomtHandle: Boolean = false): Response<*> {
            val json = JsonObject()
            json.addProperty("email", email);
            json.addProperty("password", password);
            suspend fun execOperation(): Response<*> = myRestClient.login(json)
            return runOperation(isCustomtHandle, ::execOperation)
}

她的api接口:

import com.google.gson.JsonElement
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.POST

/*
  Notice we are calling the suspend method in order to wait until our asynchronous operation has finished.
  Awaits for completion of this value without blocking a thread and resumes when deferred computation is complete,
  returning the resulting value (e.g. after 3 seconds) or throwing the corresponding exception if the deferred was cancelled.
*/
interface TangoRestClient {

    @POST("/login")
    suspend fun login(@Body body: JsonElement) : Response<JsonElement>  


}

从 Kotlin 活动文件 (TradersActivity.kt) 中使用它:

import android.app.Activity;
class TradersActivity :Activity

    private fun loadData() {
        GlobalScope.launch(Dispatchers.Main) {
            val response: Response<*> = TransportService.login("email", "password")
             if (response.get().isSuccessful()) {
                     Toast.makeText(context, "Success response", Toast.LENGTH_SHORT).show();
                }
        }
    }

很好,工作正常。

好的。

但我也有需要使用相同逻辑的 java 文件。 我暂时无法将其转换为 Kotlin

我需要从 java 启动 Kotlin 协程并在 IO(异步)线程中启动方法 doLoginFromJava。 结果还必须在 UI 线程中显示 toast。

所以我在java文件LoginActivity.java中试试这个(我调用方法doLoginFromJava

 import android.app.Activity;
public class LoginActivity extends Activity {

  try {
        CompletableFuture<Response<?>> response = TransportService.doLogin("email", "pass", false);
        if (BuildConfig.DEBUG)
            Log.d(TAG, "login_response = " + response);
        if (response.get().isSuccessful()) {
            Toast.makeText(getApplicationContext(), "Success reponse", Toast.LENGTH_SHORT).show();
        }
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

问题是: 这是 Kotlin 代码的正确等价物吗?

【问题讨论】:

    标签: android kotlin kotlin-coroutines android-gradle-3.0


    【解决方案1】:

    不,它不等效,因为response.get() 会阻塞 UI 线程。

    您根本无法将协程的功能复制为单一方法,因为它们旨在处理其他代码可能运行的执行过程中的“中断”。您将需要实施普通的Handler 和基于回调的解决方案来处理未来某个时间可用的数据。

    但是,您可能需要考虑在 kotlin 中实现需要协程的部分,然后只从 LoginActivity 调用它,基本上是根据需要慢慢地移动实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-29
      • 1970-01-01
      • 2015-01-25
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      相关资源
      最近更新 更多