Callback get response Sync kotlin
我正试图在同步模式下获取回调的响应,因为我的响应值是所有应用程序正常工作所必需的,没有此值(令牌),我将无法继续使用该应用程序。
这是我在改造界面内的同伴对象。我需要在创建客户端之前设置令牌。
我做错了什么?
编辑:
我在撰写本文时将其作为日志:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | companion object { private var mToken: String ="" fun create(activity: Activity): MyPhoneInterface { Log.d("tokenMyPhoneInterface", activity.localClassName) getToken(activity) Log.d("tokenMyPhoneInterface","client token $mToken") val client = OkHttpClient.Builder() .addInterceptor { chain -> val request = chain.request().newBuilder() .addHeader("Authorization", mToken).build() chain.proceed(request) }.build() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .client(client) .baseUrl(BuildConfig.API_HOST) .build() return retrofit.create(MyPhoneInterface::class.java) } private fun getToken(activity: Activity) { if(!activity.isFinishing && isJwtExpired(mToken)){ val latch = CountDownLatch(1) (LoginManager(activity)).getToken(true, object : ServiceCallback<String> { override fun success(token: String) { Log.d("tokenMyPhoneInterface","token $token") mToken = token latch.countDown() } override fun failure(serviceError: ServiceError) { Log.d("tokenMyPhoneInterface", serviceError.errorMessage) latch.countDown() } }) Log.d("tokenMyPhoneInterface","before await") latch.await() Log.d("tokenMyPhoneInterface","after await") } } } |
但是我系统被闩锁在了latch.await()中,日志是:
05-14 18:19:00.127 848-848 / com.italy.myphone D / tokenMyPhoneInterface:view.splash.activity.Splash
05-14 18:19:00.131 848-848 / com.italy.myphone D / tokenMyPhoneInterface:等待之前
编辑答案2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | sealed class TokenResult { class Success(val token: String) : TokenResult() class Error(val serviceError: ServiceError) : TokenResult()} suspend fun getToken(activity: Activity): TokenResult { return suspendCancellableCoroutine { continuation -> (LoginManager(activity)).getToken(true, object : ServiceCallback<String> { override fun success(token: String) { continuation.resume(TokenResult.Success(token)) } override fun failure(serviceError: ServiceError) { continuation.resume(TokenResult.Error(serviceError)) } }) }} |
这是我尝试调用suspend函数的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | companion object { fun create(activity: Activity): MyPhoneInterface{ Log.d("tokenMyPhoneInterface", activity.localClassName) var token = runBlocking { return@runBlocking getToken(activity) } Log.d("tokenMyPhoneInterface","obtained token") Log.d("tokenMyPhoneInterface","client token $tokenResult") val client = OkHttpClient.Builder() .addInterceptor { chain -> val request = chain.request().newBuilder() .addHeader("Authorization","").build() chain.proceed(request) }.build() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .client(client) .baseUrl(BuildConfig.API_HOST) .build() return retrofit.create(MyPhoneInterface::class.java) } } |
在接口内部,这是我用来在活动中调用接口/伴生对象的代码:
1 2 3 | private val mMyPhoneInterface by lazy { MyPhoneInterface.create(activity) } |
我知道在同步模式下获取回调响应的最好方法是使用
协程和函数
在您的情况下,您可以具有以下功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | suspend fun getToken(activity: Activity): TokenResult { return suspendCancellableCoroutine { continuation -> (LoginManager(activity)).getToken(true, object : ServiceCallback<String> { override fun success(token: String) { continuation.resume(TokenResult.Success(token)) } override fun failure(serviceError: ServiceError) { continuation.resume(TokenResult.Error(serviceError)) } }) } } sealed class TokenResult { class Success(val token: String) : TokenResult() class Error(val serviceError: ServiceError) : TokenResult() } |
在您的
1 2 3 4 5 6 7 8 9 10 | override fun onCreate(savedInstanceState: Bundle?) = runBlocking { super.onCreate(savedInstanceState) val tokenResult = getToken(this) if(tokenResult is Error){ finish() return@runBlocking } //create client here with tokenResult.token value } |
尝试一下,让我知道...
编辑:在该示例中,我使用
编辑:
要在项目中使用协同程序,请在gradle文件中添加以下行:
1 2 3 4 5 6 7 8 9 | dependencies { //other dependencies implementation"org.jetbrains.kotlinx:kotlinx-coroutines-android:0.22.5" } kotlin { experimental { coroutines"enable" } } |
最后,我使用JavaRx来同步回调。这是代码段。
1 2 3 4 5 6 7 8 9 10 11 12 13 | fun getToken(loginManager: LoginManager): String { return Single .create(SingleOnSubscribe<String> { emitter -> loginManager.getToken(object : TokenSimpleCallback { override fun onSuccess(token: String) { emitter.onSuccess(token) } override fun onFailure(loginServiceError: LoginServiceError) { emitter.onError(Throwable(loginServiceError.toString())) } }) }).blockingGet()} |
您不应该使用
对不起,如果我错了,我没有足够的存储库可以发表评论。