簡體   English   中英

使用 MVP 對 kotlin 進行 Retrofit 的 Api 調用問題

[英]Api call issue with Retrofit for kotlin using MVP

我正在使用 MVP 中的 Retrofit 與 kotlin 合作。 API 不返回響應或完成視圖加載。

演示者代碼

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>) {

}

接口服務

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> { ... })

但是根據名為login ApiService函數返回可選的Call對象和可選的 LoginModel響應對象。

這意味着調用enqueue函數的正確方法是:

CrosspolesApp.instance
             ?.apiService
             ?.login(map)?.enqueue(object: Callback<LoginModel?> { ... })

由於login(map)返回可選Call對象問號被放置在調用enqueue之前。

確保更新Callback對象onResponseonFailure函數實現(注意問號):

override fun onResponse(call: Call<LoginModel?>, ...) { ... }
override fun onFailure(call: Call<LoginModel?>, ...) { ... }

刪除空的擴展函數,因為它沒有任何作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM