Я использую модификацию для входа в свой API, но если, например, я введу неправильный пароль и попытаюсь войти снова, служба больше не будет вызвана. "застревает" в репозитории, никогда не достигает службы.
Это мое первое приложение android, и я борюсь с этой ситуацией. Заранее благодарим за любую помощь, которую вы можете предоставить по этому поводу.
Это код для моего приложения.
DI
class Fiscalizacao : Application(), KodeinAware {
override val kodein = Kodein.lazy {
import(androidModule(this@Fiscalizacao))
bind() from singleton {
Autenticacao(
instance()
)
}
bind<IAutenticacaoDataSource>() with singleton {
AutenticacaoDataSourceImpl(
instance()
)
}
bind<IAuthenticationRepository>() with singleton {
AuthenticationRepositoryImpl(
instance()
)
}
bind() from provider { AutenticacaoViewModelFactory(instance(), instance()) }
}
override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this)
}
}
Service
interface Autenticacao {
@POST("auth")
fun authAsync(@Body user: RequestBody): Deferred<AutenticacaoResponseResource>
companion object {
operator fun invoke(connectivityInterceptor: IConnectivityInterceptor): Autenticacao {
val okHttpClient = OkHttpClient.Builder()
.build()
return Retrofit
.Builder()
.client(okHttpClient)
.baseUrl("http://10.110.100.216/identity/")
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(Autenticacao::class.java)
}
}
}
DataSource
class AutenticacaoDataSourceImpl(
private val autenticacao: Autenticacao
) :
IAutenticacaoDataSource {
private val _authResponse = MutableLiveData<AutenticacaoResponseResource>()
override val authResponse: LiveData<AutenticacaoResponseResource>
get() = _authResponse
override suspend fun auth(user: CredentialsResource?): LiveData<AutenticacaoResponseResource> {
try {
val userJsonObject = JsonObject()
userJsonObject.addProperty(Parameters.USERNAME.value, user?.utilizador)
userJsonObject.addProperty(Parameters.PASSWORD.value, user?.password)
val result = autenticacao
.authAsync(
userJsonObject.toString()
.toRequestBody(contentType = "application/json; charset=utf8".toMediaTypeOrNull())
)
.await()
_authResponse.postValue(result)
} catch (e: Exception) {
Log.e(e.cause.toString(), e.message, e)
}
return authResponse
}
}
Repository
class AuthenticationRepositoryImpl(
private val autenticacaoDataSource: IAutenticacaoDataSource
) : IAuthenticationRepository {
override suspend fun auth(user: CredentialsResource?): LiveData<AutenticacaoResponseResource> {
return withContext(Dispatchers.IO) {
return@withContext autenticacaoDataSource.auth(user)
}
}
}
ViewModel
class AutenticacaoViewModel(
private val authenticationRepository: IAuthenticationRepository,
) : ViewModel() {
lateinit var user:CredentialsResource
val login by lazyDeferred {
authenticationRepository.auth(user)
}
}
View Model Factory
class AutenticacaoViewModelFactory(private val authenticationRepository: IAuthenticationRepository, ) :
ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return AutenticacaoViewModel(authenticationRepository) as T
}
}
Coroutines
fun <T> lazyDeferred(block: suspend CoroutineScope.() -> T): Lazy<Deferred<T>>{
return lazy {
GlobalScope.async(start = CoroutineStart.LAZY) {
block.invoke(this)
}
}
}
class AutenticacaoFragment : ScopedFragment(), KodeinAware {
override val kodein by closestKodein()
private val authViewModelFactory: AutenticacaoViewModelFactory by instance()
private lateinit var viewModel: AutenticacaoViewModel
val gson = Gson()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: AutenticacaoFragmentBinding =
DataBindingUtil.inflate(inflater, R.layout.autenticacao_fragment, container, false)
binding.model =
AppGlobalObject
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this, authViewModelFactory)
.get(AutenticacaoViewModel::class.java)
mAutenticacao.setOnClickListener(listenerService)
}
private val listenerService =
View.OnClickListener {
when (it.id) {
R.id.mAutenticacao -> {
login(this.requireContext())
}
}
}
private fun login(context: Context) = launch {
viewModel.user = gson.fromJson(
gson.toJson(AppGlobalObject.autenticacao.user),
CredentialsResource::class.java
)
val result = viewModel.login.await()
result.observe(viewLifecycleOwner, Observer { response ->
if (response == null) return@Observer
val login = Utilities().validateStatusCodeOK(response.error)
when {
login -> {
Utilities().setLoginStatus(login, context)
}
else -> {
mPassword.error = "Erro no Login"
}
}
})
}