Api 使用 MVP 的 kotlin 改造调用问题
Api call issue with Retrofit for kotlin using MVP
我正在使用 MVP 中的 Retrofit 与 kotlin 合作。 API 未 return 响应或完成视图加载。
主持人代码
import android.content.Context
import android.util.Log
import com.crosspoles.CrosspolesApp
import com.crosspoles.R
import com.crosspoles.Views.LoginView
import com.ruhe.model.LoginModel
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*
class LoginPresenter : BasePresenter<LoginView?>() {
fun LoginUser(activity:Context, map:HashMap<String, RequestBody>, progress:Boolean) {
view!!.enableLoadingBar(activity, progress, activity.getResources().getString(R.string.loading))
CrosspolesApp.instance
?.apiService
?.login(map).enqueue(object:Callback<LoginModel> {
override fun onResponse(call:Call<LoginModel>, response:Response<LoginModel>) {
view!!.enableLoadingBar(activity, false, "")
view!!.onLoginComplete(response.body(), response.code())
Log.e("@@Start","dsadas")
}
override fun onFailure(call:Call<LoginModel>, t:Throwable) {
Log.e("@@Start2","dsadas")
view!!.enableLoadingBar(activity, false, "")
try {
t.printStackTrace()
}
catch (e:Exception) {
e.printStackTrace()
}
view!!.onError(null)
}
})
}
}
private fun <T> Call<T>?.enqueue(callback: Callback<LoginModel>) {
}
Api 服务
package com.crosspoles.service
import com.crosspoles.model.LoginModel
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PartMap
import java.util.*
interface ApiService {
@Multipart
@POST("login")
fun login(@PartMap map: HashMap<String, RequestBody>): Call<LoginModel?>?
}
CrosspolesApp是应用调用继承整个项目
package com.crosspoles
import android.content.Context
import android.os.StrictMode
import androidx.multidex.MultiDex
import androidx.multidex.MultiDexApplication
import com.crosspoles.service.ApiService
import com.crosspoles.service.CustomInterceptor
import com.facebook.stetho.Stetho
import com.google.gson.GsonBuilder
import com.crosspoles.extra.Constants
import io.github.inflationx.calligraphy3.CalligraphyConfig
import io.github.inflationx.calligraphy3.CalligraphyInterceptor
import io.github.inflationx.viewpump.ViewPump
import okhttp3.Cache
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.io.File
import java.util.*
import java.util.concurrent.TimeUnit
class CrosspolesApp : MultiDexApplication() {
var isAidl = false
var apiService: ApiService? = null
private set
override fun onCreate() {
super.onCreate()
instance = this
MultiDex.install(applicationContext)
createApiService()
val builder = StrictMode.VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build())
ViewPump.init(ViewPump.builder()
.addInterceptor(CalligraphyInterceptor(
CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/open_sans_regular.ttf")
.setFontAttrId(R.attr.fontPath)
.build()))
.build())
Stetho.initializeWithDefaults(this)
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
}
fun createApiService(): ApiService? {
val gson = GsonBuilder().create()
val httpCacheDirectory = File(cacheDir, "cache_file")
val cache = Cache(httpCacheDirectory, 20 * 1024 * 1024)
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.connectionPool(ConnectionPool(0, 5 * 60 * 1000, TimeUnit.SECONDS))
.addInterceptor(CustomInterceptor(instance, Locale.getDefault().language, appVersion))
.cache(cache)
.build()
val retrofit = Retrofit.Builder().client(okHttpClient)
.baseUrl(Constants.BASE_crosspoles_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
apiService = retrofit.create(ApiService::class.java)
return apiService
}
private val appVersion: String
private get() = try {
packageManager.getPackageInfo(packageName, 0).versionName
} catch (e: Exception) {
e.printStackTrace()
"1.1"
}
companion object {
var instance: CrosspolesApp? = null
private set
}
}
我想知道这些有什么错误。如果需要更多理解任何其他代码,请通知我。
根据问题下的评论中的讨论和另外发布的代码,我假设并且基本上可以肯定,问题是传递给 enqueue
函数的回调对象类型错误。
目前,入队函数接收类型为Callback<LoginModel>
的对象:
CrosspolesApp.instance
?.apiService
?.login(map).enqueue(object: Callback<LoginModel> { ... })
但是根据ApiService
函数命名login
returns可选Call
对象with可选LoginModel响应对象。
这意味着调用 enqueue
函数的正确方法是:
CrosspolesApp.instance
?.apiService
?.login(map)?.enqueue(object: Callback<LoginModel?> { ... })
由于login(map)
returns可选Call
对象问号在调用enqueue
之前被放置enqueue
.
确保更新 Callback
对象 onResponse
和 onFailure
函数实现(注意问号):
override fun onResponse(call: Call<LoginModel?>, ...) { ... }
override fun onFailure(call: Call<LoginModel?>, ...) { ... }
删除空扩展函数,因为它没有任何用处。
我正在使用 MVP 中的 Retrofit 与 kotlin 合作。 API 未 return 响应或完成视图加载。
主持人代码
import android.content.Context
import android.util.Log
import com.crosspoles.CrosspolesApp
import com.crosspoles.R
import com.crosspoles.Views.LoginView
import com.ruhe.model.LoginModel
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*
class LoginPresenter : BasePresenter<LoginView?>() {
fun LoginUser(activity:Context, map:HashMap<String, RequestBody>, progress:Boolean) {
view!!.enableLoadingBar(activity, progress, activity.getResources().getString(R.string.loading))
CrosspolesApp.instance
?.apiService
?.login(map).enqueue(object:Callback<LoginModel> {
override fun onResponse(call:Call<LoginModel>, response:Response<LoginModel>) {
view!!.enableLoadingBar(activity, false, "")
view!!.onLoginComplete(response.body(), response.code())
Log.e("@@Start","dsadas")
}
override fun onFailure(call:Call<LoginModel>, t:Throwable) {
Log.e("@@Start2","dsadas")
view!!.enableLoadingBar(activity, false, "")
try {
t.printStackTrace()
}
catch (e:Exception) {
e.printStackTrace()
}
view!!.onError(null)
}
})
}
}
private fun <T> Call<T>?.enqueue(callback: Callback<LoginModel>) {
}
Api 服务
package com.crosspoles.service
import com.crosspoles.model.LoginModel
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PartMap
import java.util.*
interface ApiService {
@Multipart
@POST("login")
fun login(@PartMap map: HashMap<String, RequestBody>): Call<LoginModel?>?
}
CrosspolesApp是应用调用继承整个项目
package com.crosspoles
import android.content.Context
import android.os.StrictMode
import androidx.multidex.MultiDex
import androidx.multidex.MultiDexApplication
import com.crosspoles.service.ApiService
import com.crosspoles.service.CustomInterceptor
import com.facebook.stetho.Stetho
import com.google.gson.GsonBuilder
import com.crosspoles.extra.Constants
import io.github.inflationx.calligraphy3.CalligraphyConfig
import io.github.inflationx.calligraphy3.CalligraphyInterceptor
import io.github.inflationx.viewpump.ViewPump
import okhttp3.Cache
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.io.File
import java.util.*
import java.util.concurrent.TimeUnit
class CrosspolesApp : MultiDexApplication() {
var isAidl = false
var apiService: ApiService? = null
private set
override fun onCreate() {
super.onCreate()
instance = this
MultiDex.install(applicationContext)
createApiService()
val builder = StrictMode.VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build())
ViewPump.init(ViewPump.builder()
.addInterceptor(CalligraphyInterceptor(
CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/open_sans_regular.ttf")
.setFontAttrId(R.attr.fontPath)
.build()))
.build())
Stetho.initializeWithDefaults(this)
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
}
fun createApiService(): ApiService? {
val gson = GsonBuilder().create()
val httpCacheDirectory = File(cacheDir, "cache_file")
val cache = Cache(httpCacheDirectory, 20 * 1024 * 1024)
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.connectionPool(ConnectionPool(0, 5 * 60 * 1000, TimeUnit.SECONDS))
.addInterceptor(CustomInterceptor(instance, Locale.getDefault().language, appVersion))
.cache(cache)
.build()
val retrofit = Retrofit.Builder().client(okHttpClient)
.baseUrl(Constants.BASE_crosspoles_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
apiService = retrofit.create(ApiService::class.java)
return apiService
}
private val appVersion: String
private get() = try {
packageManager.getPackageInfo(packageName, 0).versionName
} catch (e: Exception) {
e.printStackTrace()
"1.1"
}
companion object {
var instance: CrosspolesApp? = null
private set
}
}
我想知道这些有什么错误。如果需要更多理解任何其他代码,请通知我。
根据问题下的评论中的讨论和另外发布的代码,我假设并且基本上可以肯定,问题是传递给 enqueue
函数的回调对象类型错误。
目前,入队函数接收类型为Callback<LoginModel>
的对象:
CrosspolesApp.instance
?.apiService
?.login(map).enqueue(object: Callback<LoginModel> { ... })
但是根据ApiService
函数命名login
returns可选Call
对象with可选LoginModel响应对象。
这意味着调用 enqueue
函数的正确方法是:
CrosspolesApp.instance
?.apiService
?.login(map)?.enqueue(object: Callback<LoginModel?> { ... })
由于login(map)
returns可选Call
对象问号在调用enqueue
之前被放置enqueue
.
确保更新 Callback
对象 onResponse
和 onFailure
函数实现(注意问号):
override fun onResponse(call: Call<LoginModel?>, ...) { ... }
override fun onFailure(call: Call<LoginModel?>, ...) { ... }
删除空扩展函数,因为它没有任何用处。