Bom dia a todos
O bug que eu encontrei se refere ao projeto do curso Android com Kotlin: comunicação com Web API
Eu fiz um teste para ver se o SwipeRefreshLayout estava funcionado. E nesse teste eu fiz em 2 aparelhos, percebi que o refresh estava funcionando normalmente, mas nisso eu percebi um bug no projeto.
Eu inseri um objeto no aparelho 1, atualizei o aparelho 2 e apareceu o objeto. Deletei o objeto do aparelho 1 de forma offline, atualizei o aparelho 1 online e o objeto foi deletado, mas ao atualizar o aparelho 2 ele não apagava o objeto.
Eu acredito que o objeto não foi deletado no aparelho 2 pois ele conta como se objeto no aparelho 2 não tivesse desativado, por isso o servidor não apaga, e nem o aparelho 2 manda o objeto ao servidor porque neste aparelho o objeto conta como se tivesse já sincronizado, então o objeto fica no limbo do aparelho 2, sem ser excluído, e sem ser mandado para o servidor.
Eu até posso colocar meu código aqui, mas acredito que não vai fazer muita diferença, porque em todos os testes ele estava funcionando normalmente:
class ListaNotasActivity : AppCompatActivity() {
private val binding by lazy {
ActivityListaNotasBinding.inflate(layoutInflater)
}
private val adapter by lazy {
ListaNotasAdapter(this)
}
private val repository by lazy {
NotaRepository(
AppDatabase.instancia(this).notaDao(),
NotaWebClient()
)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
configuraFab()
configuraRecyclerView()
carregaEAtualizaNotas()
configuraSwipeRefresh()
}
private fun configuraSwipeRefresh() {
binding.activityListaNotasSwipe.apply {
setOnRefreshListener {
carregaEAtualizaNotas()
lifecycleScope.launch {
repository.sincroniza()
isRefreshing = false
}
}
}
}
private fun configuraFab() {
binding.activityListaNotasFab.setOnClickListener {
Intent(this, FormNotaActivity::class.java).apply {
startActivity(this)
}
}
}
private fun configuraRecyclerView() {
binding.activityListaNotasRecyclerview.adapter = adapter
adapter.quandoClicaNoItem = { nota ->
vaiPara(FormNotaActivity::class.java) {
putExtra(NOTA_ID, nota.id)
}
}
}
private fun carregaEAtualizaNotas() {
lifecycleScope.launch {
launch {
repository.sincroniza()
}
repeatOnLifecycle(Lifecycle.State.STARTED) {
buscaNotas()
}
}
}
private suspend fun buscaNotas() {
repository.buscaTodes()
.collect { notasEncontradas ->
binding.activityListaNotasMensagemSemNotas.visibility =
if (notasEncontradas.isEmpty()) {
binding.activityListaNotasRecyclerview.visibility = GONE
VISIBLE
} else {
binding.activityListaNotasRecyclerview.visibility = VISIBLE
adapter.atualiza(notasEncontradas)
GONE
}
}
}
}
class NotaRepository(
private val dao: NotaDao,
private val webClient: NotaWebClient
) {
fun buscaTodes(): Flow<List<Nota>>{
return dao.buscaTodos()
}
fun buscaPorId(id: String): Flow<Nota> {
return dao.buscaPorId(id)
}
suspend fun desativa(id: String) {
dao.desativa(id)
remove(id)
}
private suspend fun remove(id: String) {
if (webClient.remove(id)) {
dao.remove(id)
}
}
suspend fun salva(nota: Nota) {
if(webClient.salva(nota)){
val notaSincronizada = nota.copy(sincronizada = true)
dao.salva(notaSincronizada)
} else{
dao.salva(nota)
}
}
suspend fun sincroniza(){
val notasDesativadas = dao.buscaNotasDesativadas().first()
notasDesativadas.forEach {
remove(it.id)
}
val notasNaoSincronizadas = dao.buscaNaoSincronizadas().first()
notasNaoSincronizadas.forEach {
salva(it)
}
atualizaTodos()
}
private suspend fun atualizaTodos(){
webClient.buscaTodos()?.let { notas ->
val notasSincronizadas = notas.map {
it.copy(sincronizada = true)
}
dao.salvaTodos(notasSincronizadas)
}
}
}