gpt4 book ai didi

android - 使用ViewModel和LiveData改造执行API多次

转载 作者:行者123 更新时间:2023-12-03 10:41:23 24 4
gpt4 key购买 nike

因此,当我执行操作单击以请求API GET时,我遇到了一个问题,我多次使用MVVM和LiveData组合从API获取值时,多次击中了端点。
下面的代码
ApiService.kt

   class ApiService {
private var retrofit : Retrofit? = null
private val okHttpBuilder = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.connectTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
.build()


fun <S> createService(serviceClass: Class<S>?): S {
if(retrofit == null){
retrofit = Retrofit.Builder().addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.client(okHttpBuilder)
.build()
}
return retrofit!!.create(serviceClass!!)
}


val serviceGuestMerchants : GuestMerchantsService by lazy{
createService(GuestMerchantsService::class.java)
}
}
介面
GuestMerchantService.kt
    interface GuestMerchantsService {
@GET(ConstantGuestMerchants.BASE_URL_GUEST_MERCHANT)
suspend fun getListMerchant(@Query("page") page :Int?, @Query("order-direction") orderDirection :
String) : ResponseListMerchant

@GET(ConstantGuestMerchants.BASE_URL_GUEST_MERCHANT_DETAIL)
suspend fun getPreviewMerchant(@Path("id") id:Int) : ResponsePreviewMerchant

@GET(ConstantGuestMerchants.BASE_URL_GUEST_MERCHANT_PRODUCT_LIST)
suspend fun getListProductByMerchant(
@Path("id") id : Int,
@Query("page") page : Int?) : ResponseProductByMerchant

@GET(ConstantGuestMerchants.BASE_URL_GUEST_MERCHANT_STATUS)
suspend fun getStatusMerchant(@Header("Authorization") authorization : String) :
ResponseGetStatusMerchant

@Multipart
@POST(ConstantGuestMerchants.BASE_URL_GUEST_MERCHANT_REQUEST_MERCHANT)
fun registerMerchant(@Header("Authorization") authorization: String,
@Part fotoKtp : MultipartBody.Part, @Part fotoPemilik : MultipartBody.Part,
@Part fotoToko : MultipartBody.Part,
@Part namaToko : MultipartBody.Part,@Part noHp : MultipartBody.Part ,
@Part alamat : MultipartBody.Part, @Part noKtp : MultipartBody.Part) : Call<ResponseRegisterMerchant>

@DELETE(ConstantGuestMerchants.BASE_URL_GUEST_MERCHANT)
fun deleteRequestMerchant(@Header("Authorization") authorization : String) :
Call<ResponseDeleteReqMerchant>
}
View 模型
ProfileViewModel.kt
    class ProfileViewModel : ViewModel(){

private val _profile = MutableLiveData<Profile>()
val profile : LiveData<Profile>
get() = _profile

private val _status = MutableLiveData<ApiStatus>()
val status : LiveData<ApiStatus>
get() = _status

private suspend fun getProfileUser(token : String){
try {
_status.postValue(ApiStatus.LOADING)
val apiService = ApiService().serviceProfileUser
_profile.postValue(apiService.getProfile(token).data)
_status.postValue(ApiStatus.SUCCESS)
}catch (e : Exception){
Log.d("REQ_PROF_USR_FAIL", e.localizedMessage!!)
_status.postValue(ApiStatus.FAILED)
}
}

fun getDataProfileUser(token : String){
viewModelScope.launch {
getProfileUser(token)
}
}

}
执行 Action 以从ViewModel调用函数的片段
CustomerProfileFragment.kt
    class CustomerProfileFragment : Fragment() {

private lateinit var adapter: AdapterUtil<ProfileMenuItem>
private lateinit var binding: FragmentCustomerProfileBinding
private lateinit var cacheUtil: CacheUtil
private var auth : Login? = null
private val viewModel : ProfileViewModel by lazy {
ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(ProfileViewModel::class.java)
}

private val viewModelRegisterMerchant: RegisterMerchantViewModel by lazy {
ViewModelProvider(
this,
ViewModelProvider.NewInstanceFactory()
).get(RegisterMerchantViewModel::class.java)
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//binding init
binding = FragmentCustomerProfileBinding.inflate(inflater, container, false)
// Setup Cache
cacheUtil = CacheUtil()
cacheUtil.start(context as Activity, ConstantAuth.PREFERENCES)
// Setup Title
(activity as AppCompatActivity?)!!.setSupportActionBar(binding.toolbar)
binding.toolbar.title = getString(R.string.akun_saya)

//After Login
if (getAuth(cacheUtil).token!!.isNotEmpty()) {
auth = getAuth(cacheUtil)
Log.d("TOKEN NYA TOKEN", "${auth!!.token} TOKEN NYA TOKEN PROFILE")
binding.llLogin.visibility=View.GONE
setupProfileMenu()
binding.tvRegistrasi.setOnClickListener {
startActivity(Intent(context, RegisterUserActivity::class.java))
}
//login
binding.tvLogin.setOnClickListener {
startActivity(Intent(context, LoginActivity::class.java))
}


//Logout
binding.tvLogout.setOnClickListener {
this.cacheUtil.clear()
startActivity(Intent(requireContext(), MainActivity::class.java))
requireActivity().finish()
}
binding.imFotoProfil.setOnClickListener {
ImagePicker.create(this)
.single()
.start()
}

//edit photo profile
}else{
binding.tvNamaAkun.text = ""
binding.tvEmailAkun.text = ""
Glide.with(requireContext()).load(R.drawable.ic_baseline_account_circle_24).into(binding.imFotoProfil)
}

return binding.root
}

private fun setupProfileMenu(){
//Setup Profil Menu
binding.rvIconmenu.layoutManager = LinearLayoutManager(context)
adapter =
AdapterUtil(R.layout.item_list_menu_akun,
listOf(
ProfileMenuItem(
"Saldo Saya",
R.drawable.ic_monetization
),
ProfileMenuItem(
"Pusat Bantuan",
R.drawable.ic_help_outline
),
ProfileMenuItem(
"Chat dengan Leh-Oleh",
R.drawable.ic_chat
),
ProfileMenuItem(
"Beri Kami Nilai",
R.drawable.ic_star_border
),
ProfileMenuItem(
"Toko Saya",
R.drawable.ic_store
)
), { position, itemView, item ->
itemView.tv_menu!!.text = item.label
itemView.im_akun_icon!!.setImageResource(item.icon)
itemView.im_chevron_right.setImageResource(R.drawable.ic_chevron_right)
}, { position, item ->
when (position) {
0 -> startActivity(
Intent(
context,
CustomerSaldoSayaActivity::class.java
)
)
1 -> startActivity(
Intent(
context,
BantuanActivity::class.java
)
)
4 -> {
viewModelRegisterMerchant.getDataStatusMerchant(auth!!.token!!)
viewModelRegisterMerchant.statusMerchant.observe(
viewLifecycleOwner,
Observer {
if (it.isVisible!!.isNotEmpty()) {
if (it.isVisible == "1") {
//findNavController().navigate(R.id.action_navigation_register_toko_to_navigation_toko_saya)
startActivity(Intent(requireContext(), MerchantTokoSayaActivity::class.java))
}
} else {
Log.d("DATA_STATUS", "BELUM LOGIN")
}

})
}
}
// 2 -> startActivity(Intent(context, ProductListActivity::class.java))
// 3 -> startActivity(Intent(context, ProductListActivity::class.java))
})
binding.rvIconmenu.adapter = adapter
}



override fun onResume() {
viewModel.getDataProfileUser(auth!!.token!!)
super.onResume()
}
}
注意,当调用viewModelRegisterMerchant并进行观察时,该意图执行了多次,当我看到Logcat时,该端点也被执行了多次。
我以为观察者会不断更新数据,但我不知道怎么可能
另一个类使其更清晰
启动意图时多次调用的类
MerchantTokoSaya.kt
    class MerchantTokoSayaActivity : AppCompatActivity() {
private lateinit var binding : ActivityMerchantTokoSayaBinding
private lateinit var auth: Login
private val viewModel : ProfileTokoViewModel by lazy {
ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(ProfileTokoViewModel::class.java)
}
private lateinit var cacheUtil: CacheUtil
private lateinit var adapter: AdapterUtil<ProfileMenuItem>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMerchantTokoSayaBinding.inflate(layoutInflater)
setContentView(binding.root)
cacheUtil = CacheUtil()
cacheUtil.start(this, ConstantAuth.PREFERENCES)
if (getAuth(cacheUtil).token!!.isNotEmpty()) {
auth = getAuth(cacheUtil)
Log.d("TOKEN NYA TOKEN", "${auth.token} TOKEN NYA TOKEN")
getDataProfileToko()

binding.tvUbahAkun.setOnClickListener {
val intent = Intent(this, RegisterMerchantFragment::class.java)
intent.putExtra(ConstantProfileMerchant.DATA_EDIT_PROFILE_TOKO, ConstantProfileMerchant.ACTION_EDIT_PROFILE_TOKO)
startActivity(intent)
finish()
}
title = "Toko Saya"

//Setup Profil Menu
binding.rvIconmenu.layoutManager = LinearLayoutManager(this)
adapter =
AdapterUtil(R.layout.item_list_menu_akun,
listOf(
ProfileMenuItem(
"Kelola Barang",
R.drawable.ic_card_giftcard
),
ProfileMenuItem(
"Kelola Pesanan",
R.drawable.ic_assignment
),
ProfileMenuItem(
"Pesan Masuk",
R.drawable.ic_chat
),
ProfileMenuItem(
"Keuangan",
R.drawable.ic_monetization
)
), { position, itemView, item ->
itemView.tv_menu!!.text = item.label
itemView.im_akun_icon!!.setImageResource(item.icon)
itemView.im_chevron_right.setImageResource(R.drawable.ic_chevron_right)
}, { position, item ->
when (position) {
0 -> startActivity(
Intent(
this,
MerchantKelolaBarangActivity::class.java
)
)
1 -> startActivity(
Intent(
this,
KelolaPesananActivity::class.java
)
)
// 2 -> startActivity(Intent(context, ProductListActivity::class.java))
// 3 -> startActivity(Intent(context, ProductListActivity::class.java))
}
})
binding.rvIconmenu.adapter = adapter

//init profil picture
binding.imFotoProfil.setImageResource(R.drawable.ic_home_black_24dp)
}else {
startActivity(Intent(this, LoginActivity::class.java))
}
}

private fun getDataProfileToko(){
viewModel.getDataProfileToko(auth.token!!)
viewModel.toko.observe(this, Observer {
binding.tvNamaAkun.text = it.marketName
Glide.with(this).load(it.authorUri).circleCrop().into(binding.imFotoProfil)
Glide.with(this).load(it.marketUri).into(binding.imageViewHeader)
})
}


}
util类保存共享的首选项
CacheUtil.kt
    class CacheUtil {
private var sharePref: SharedPreferences? = null

fun start(activity: Activity, PREFS: String) {
sharePref = activity.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
}

fun destroy() { this.sharePref = null }

fun <T> set(PREFS: String, value: T) {
this.sharePref?.let {
with(it.edit()) {
putString(PREFS, Gson().toJson(value))
Log.d("CACHE UTIL", PREFS)
apply()
}
}
}

fun clear() {
this.sharePref?.edit()?.clear()?.apply()
}

fun get(PREFS: String): String? {
if (sharePref != null) return sharePref!!.getString(PREFS, null)
return null
}
}
RegisterMerchantViewModel.kt
    class RegisterMerchantViewModel : ViewModel(){

private val _statusMerchant = MutableLiveData<DataGetStatusMerchant>()
val statusMerchant : LiveData<DataGetStatusMerchant>
get() = _statusMerchant

private val _status = MutableLiveData<ApiStatus>()
val status : LiveData<ApiStatus>
get() = _status


private val apiService = ApiService().serviceGuestMerchants

fun getDataStatusMerchant(token: String) {
viewModelScope.launch {
getStatusMerchant(token)
}
}

private suspend fun getStatusMerchant(token: String) {
try {
_status.postValue(ApiStatus.LOADING)
_statusMerchant.postValue(apiService.getStatusMerchant(token).data)
_status.postValue(ApiStatus.SUCCESS)
} catch (e: Exception) {
Log.d("ERROR_REQ_STATUS", e.localizedMessage!!)
_status.postValue(ApiStatus.FAILED)
}

}


}

最佳答案

我解决了这个问题,所以我将oncreateView内的所有代码移到onviewcreated上,并将viewModelRegisterMerchant.getDataStatusMerchant(auth !!。token !!)移到项目外部。

关于android - 使用ViewModel和LiveData改造执行API多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64790099/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com