Retrofit 服务未被调用/工作,并且 Android Retrofit、Kotlin、Viewmodel 都没有错误

问题描述 投票:0回答:1

我目前正在开发一个 Android 应用程序,我尝试使用 Retrofit 进行 API 调用并在 RecyclerView 中显示检索到的数据。下面,我包含了 Retrofit 设置、ViewModel 和相关组件的相关代码片段。

  1. 改造实例和服务: 我定义了用于进行 API 调用的 Retrofit 实例和服务,如下所示:
interface ApiServices {
    @GET("home/banners.php")
    suspend fun getBannersList(): Response<ResponseBanner>
}

  1. ResponseBanner 类: ResponseBanner 类被定义为 ArrayList 的扩展,用于保存 API 响应数据:
class ResponseBanner : ArrayList<ResponseBanner.ResponseBannerItem>() {
    data class ResponseBannerItem(
        @SerializedName("id")
        val id: Int?,
        @SerializedName("image")
        val image: String?,
        @SerializedName("link")
        val link: String?,
        @SerializedName("type")
        val type: String?
    )
}

  1. HomeRepository 类: 用于从 API 获取数据的存储库类定义如下:
class HomeRepository @Inject constructor(private val api: ApiServices) {
    suspend fun getBannerList() = api.getBannersList()
}

  1. MVI 状态和意图类别

以下是 HomeIntent 和 HomeState 密封类:

sealed class HomeIntent {
    data class LoadBanners(val banner: MutableList<ResponseBanner.ResponseBannerItem>) : HomeIntent()
}

sealed class HomeState {
    object Idle : HomeState()
    object LoadingProfile : HomeState()
    object LoadingBanner : HomeState()
    object Empty : HomeState()
    data class BannerListItem(val banner: MutableList<ResponseBanner.ResponseBannerItem>) : HomeState()
    data class Error(val error: String) : HomeState()
}

5.HomeViewModel类: 负责管理 UI 状态并与存储库交互的 ViewModel 定义如下:

@HiltViewModel
class HomeViewModel @Inject constructor(private val repository: HomeRepository) : ViewModel() {
    val intentChannel = Channel<HomeIntent>()
    private val _state = MutableStateFlow<HomeState>(HomeState.Idle)
    val state: StateFlow<HomeState> get() = _state

    init {
        handleIntents()
    }

    private fun handleIntents() = viewModelScope.launch {
        intentChannel.consumeAsFlow().collect { intent ->
            when (intent) {
                is HomeIntent.LoadBanners -> fetchingBanner()
            }
        }
    }


    private suspend fun fetchingBanner() {
        val response = repository.getBannerList()
        when (response.code()) {
            in 200..202 -> {
                _state.emit(HomeState.BannerListItem(response.body()!!))
            }

            in 400..499 -> {
                _state.emit(HomeState.Error(""))
            }

            in 500..599 -> {
                _state.emit(HomeState.Error(""))
            }
        }
    }

}

.6 HomeFragment类: 这是 HomeFragment 类的一个片段,我在其中观察 ViewModel 的状态以更新 UI:

@AndroidEntryPoint
class HomeFragment : Fragment() {
    //Binding
    private var _binding: FragmentHomeBinding? = null
    private val binding get() = _binding!!

    @Inject
    lateinit var bannerAdapter: AdapterBanner


    //other
    private val viewModel: HomeViewModel by viewModels()
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentHomeBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //initViews
        binding.apply {
            //lifecycle
            viewLifecycleOwner.lifecycleScope.launch {
                viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                    viewModel.state.collect { state ->
                        when (state) {
                            is HomeState.Idle -> {}
                            is HomeState.LoadingBanner -> {}
                            is HomeState.LoadingProfile -> {}
                            is HomeState.BannerListItem -> {}
                            is HomeState.Empty -> {}
                            is HomeState.Error -> {}
                        }
                    }
                }
            }
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        _binding = null
    }
}



我还在“AndroidManifest.xml”文件中添加了必要的互联网访问权限,并包含“android:usesCleartextTraffic=”true”。”

尽管设置了如上所示的代码,但我遇到了一个问题:当我在 ViewModel 中使用断点时,API 调用似乎没有进行。我已经检查了错误并检查了代码,但我无法弄清楚为什么没有进行调用。有人可以帮我找出可能导致此问题的原因吗? '我使用最新版本的 Retrofit 和 Okhttp' 预先感谢您的协助!

我使用断点进行测试,视图模型根本没有被调用,我用来调用横幅的函数。

kotlin retrofit2 okhttp
1个回答
0
投票

您从未发送过加载横幅的意图,

在ViewModel中你需要执行以下操作

init{
     handleIntents()
     onIntent(HomeIntent.LoadBanners)/*I don't know your business requirement,
 you may choose to call this from fragment on a button click or from a lifecycle callback.*/
}


fun onIntent(intent:HomeIntent) = viewModelScope.launch {
    intentChannel.send(intent)
}
© www.soinside.com 2019 - 2024. All rights reserved.