1

安卓工作室 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 协程并doLoginFromJavaIO(异步)线程中启动方法。此外,结果必须在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 代码?

4

1 回答 1

2

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

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

但是,您可能需要考虑在 kotlin 中实现需要协程的部分,然后仅从LoginActivity.

于 2019-07-15T14:09:48.990 回答