RecyclerView 아이템 무한 중복 생성
RecyclerView로 더미데이터를 다른 Activity로 넘겨주고 다시 돌아오는 과정에서 더미데이터가 계속 무한 중복, 중첩되는 문제가 발생하였습니다.
[ 밑에는 문제가 발생한 자료입니다. ]
왼쪽 자료는 처음 앱을 실행했을 때 10개의 더미데이터가 각각 나오는 모습이고
오른쪽 자료는 각 Recyclerview 아이템을 클릭하고 다시 Acitivty로 나왔을 때 더미데이터들이 중복되는 자료입니다.
[ 더보기를 클릭하면 초기 코드를 보실 수 있습니다. ]
Util.kt
val dummyItems = mutableListOf<PostModel>()
fun dummyData() {
dummyItems.add(
PostModel(
"대현동",
Uri.parse("android.resource://com.example.nbc_market/drawable/sample1"),
"산진 한달된 선풍기 팝니다",
"이사가서 필요가 없어졌어요 급하게 내놓습니다",
"서울 서대문구 창천동",
1000,
13,
25
)
)
dummyItems.add(
PostModel(
"안마담",
Uri.parse("android.resource://com.example.nbc_market/drawable/sample2"),
"김치냉장고",
"이사로인해 내놔요",
"인천 계양구 귤현동",
20000,
8,
28
)
)
dummyItems.add(
PostModel(
"코코유",
Uri.parse("android.resource://com.example.nbc_market/drawable/sample3"),
"샤넬 카드지갑",
"고퀄지갑이구요\n사용감이 있어서 싸게 내어둡니다",
"수성구 범어동",
10000,
23,
5
)
)
... [중략]
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
private val postAdapter = PostAdapter(dummyItems)
private val onBackPressedCallback: OnBackPressedCallback =
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
showBackPressedDialog()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
dummyData()
binding.rvMain.adapter = postAdapter
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
binding.ivAlarm.setOnClickListener {
notificationChannel()
}
// postAdapter의 아이템 클릭 이벤트
postAdapter.setItemClickListener(object: PostAdapter.OnItemClickListener{
override fun onClick(v: View, position: Int) {
val intent = Intent(baseContext, DetailActivity::class.java)
intent.putExtra("UserData", dummyItems[position])
startActivity(intent)
finish()
}
})
}
...[중략]
}
DetailActivity.kt
class DetailActivity : AppCompatActivity() {
private val binding: ActivityDetailBinding by lazy {
ActivityDetailBinding.inflate(layoutInflater)
}
private val postModel by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent?.getParcelableExtra("UserData", PostModel::class.java)
} else {
intent?.getParcelableExtra("UserData")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
showDetailActivity()
binding.tvMannersInfo.setOnClickListener {
showMannersInfoDialog()
}
binding.btnBack.setOnClickListener {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
}
... [중략 ]
}
이 문제가 발생하였을 때 가설을 세운 것이 MainActivity에서 DetailActivity로 갔다가 다시 MainActivity로 오면서 더미데이터가 들어있는 dummyData()가 onCreate 메서드 안에 있어서 계속 생성되는 것 같다는 생각이 들었습니다.
그렇다면 왜 계속 생성이 될까?
아이템이 중복 생성이 되던 이유
아이템이 무한 중복 생성이 되던 이유는 바로 dummyData와 finish()에서 문제가 발생하였습니다.
현재 dummyData를 mutableList 형태로 add해서 넣고 있기 때문에 MainActivity에서 DetailActivity로 넘어가면서 MainActivity를 종료시킨 후 DetailActivity에서 MainActivity로 넘어가면서 다시 MainActivity의 Task가 생성이 되어 Recyclerview의 아이템들이 중복 생성이 되던 것이었습니다.
처음 MainActivity에서 DetailActivity로 넘어가면서 finish()를 해준 이유가 MainActivity를 계속 살려두는 것보다 종료시키는 것이 더 효율적이지 않을까 했지만 이 문제로 여러 가지를 찾다 보니 BackStack을 종료시켰다가 재 생성 시키는 것보다 계속 남겨두는 것이 더 효율적이라는 것을 알게 되었습니다.
이런 비슷한 이유로 Recyclerview 또한 View를 계속 재활용하는 것인데.. 알고 나니 참 바보 같은 짓을 했네요..!
해결방법
1. MainActivity에서 Intent를 넘겨주는 부분에서 finish()를 삭제해 줍니다.
2. DetailActivity에서 불필요하게 이동하는 Intent부분을 삭제하고 finish()만 남겨줍니다.
'Android Studio > - Honey Tip' 카테고리의 다른 글
[안드로이드] Foreground Service에서 Notification이 뜨지 않는 문제 (Feat. FastCampus) (0) | 2024.07.30 |
---|---|
[안드로이드] Extended Controls의 location 흰색화면 (0) | 2024.06.17 |
[안드로이드/카카오 오븐] 프로토 타이핑 툴 - 앱 기획 (0) | 2023.12.17 |
주코딩의 개발 노트!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!