Skip to content

Commit 46ee75d

Browse files
committed
activity: avoid replaying view intents on recreation
1 parent 732c440 commit 46ee75d

4 files changed

Lines changed: 61 additions & 9 deletions

File tree

app/src/main/java/com/kyhsgeekcode/disassembler/MainActivity.kt

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ class MainActivity : AppCompatActivity() {
6767
}
6868
// setupUncaughtException()
6969
initNative()
70-
handleViewActionIntent()
70+
if (shouldHandleIncomingIntent(intent, savedInstanceState)) {
71+
handleIncomingIntent(intent)
72+
}
7173

7274
setContent {
7375
MainScreen(viewModel = viewModel)
@@ -80,12 +82,20 @@ class MainActivity : AppCompatActivity() {
8082
ColorHelper.populatePalettes(context = this)
8183
}
8284

83-
private fun handleViewActionIntent() {
84-
val intent = intent ?: return
85-
val incomingUri = extractIncomingUri(intent) ?: return
86-
takePersistableReadPermissionIfPossible(incomingUri, intent.flags)
87-
intent.putExtra("uri", incomingUri)
88-
viewModel.onSelectIntent(intent)
85+
override fun onNewIntent(intent: Intent?) {
86+
super.onNewIntent(intent)
87+
setIntent(intent)
88+
if (hasIncomingIntent(intent)) {
89+
handleIncomingIntent(intent)
90+
}
91+
}
92+
93+
private fun handleIncomingIntent(intent: Intent?) {
94+
val incomingIntent = intent ?: return
95+
val incomingUri = extractIncomingUri(incomingIntent) ?: return
96+
takePersistableReadPermissionIfPossible(incomingUri, incomingIntent.flags)
97+
incomingIntent.putExtra("uri", incomingUri)
98+
viewModel.onSelectIntent(incomingIntent)
8999
}
90100

91101
private fun takePersistableReadPermissionIfPossible(uri: Uri, intentFlags: Int) {
@@ -101,7 +111,7 @@ class MainActivity : AppCompatActivity() {
101111
}
102112

103113
private fun setupUncaughtException() {
104-
Thread.setDefaultUncaughtExceptionHandler { p1: Thread?, p2: Throwable ->
114+
Thread.setDefaultUncaughtExceptionHandler { _: Thread?, p2: Throwable ->
105115
runOnUiThread {
106116
Toast.makeText(this@MainActivity, Log.getStackTraceString(p2), Toast.LENGTH_SHORT)
107117
.show()
@@ -181,3 +191,21 @@ private fun extractIncomingUri(intent: Intent): Uri? {
181191
intent.getParcelableExtra(Intent.EXTRA_STREAM)
182192
}
183193
}
194+
195+
internal fun hasIncomingIntent(intent: Intent?): Boolean {
196+
if (intent == null) {
197+
return false
198+
}
199+
return extractIncomingUri(intent) != null
200+
}
201+
202+
internal fun shouldHandleIncomingIntent(hasIncomingIntent: Boolean, hasSavedState: Boolean): Boolean {
203+
return !hasSavedState && hasIncomingIntent
204+
}
205+
206+
internal fun shouldHandleIncomingIntent(intent: Intent?, savedInstanceState: Bundle?): Boolean {
207+
return shouldHandleIncomingIntent(
208+
hasIncomingIntent = hasIncomingIntent(intent),
209+
hasSavedState = savedInstanceState != null
210+
)
211+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.kyhsgeekcode.disassembler
2+
3+
import org.junit.jupiter.api.Assertions.assertFalse
4+
import org.junit.jupiter.api.Assertions.assertTrue
5+
import org.junit.jupiter.api.Test
6+
7+
class MainActivityIntentHandlingTest {
8+
@Test
9+
fun `shouldHandleIncomingIntent handles external view intents on first create`() {
10+
assertTrue(shouldHandleIncomingIntent(hasIncomingIntent = true, hasSavedState = false))
11+
}
12+
13+
@Test
14+
fun `shouldHandleIncomingIntent skips external view intents after recreation`() {
15+
assertFalse(shouldHandleIncomingIntent(hasIncomingIntent = true, hasSavedState = true))
16+
}
17+
18+
@Test
19+
fun `shouldHandleIncomingIntent ignores launcher intents without imported content`() {
20+
assertFalse(shouldHandleIncomingIntent(hasIncomingIntent = false, hasSavedState = false))
21+
}
22+
}

docs/maintenance/backlog-triage.ko.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
| 최신 Android storage 정책 | `#95` | `planned-fast-follow` | 핵심 유지보수 항목이며 이미 SAF 전환을 시작했다 | 앱 전체 import/open 경로를 SAF 중심으로 계속 이관 |
4242
| 릴리스 산출물 부재 | `#719` | `planned-fast-follow` | 코드 문제보다 릴리스 파이프라인 문제다 | `#726`와 함께 릴리스 워크플로 정리 |
4343
| 대용량/메모리/RecyclerView 크래시 | `#219`, `#235`, `#442`, `#523` | `needs-repro` | 실제로는 한두 개의 메모리/상태 저장 설계 문제로 묶일 가능성이 크다 | 재현 샘플과 Android 버전 기준으로 우선 재현 |
44-
| 회전/상태 복원 크래시 | `#160` | `needs-repro` | 오래됐지만 여전히 구조적으로 중요한 버그다 | 현재 Compose/Activity 상태 저장 기준으로 재검토 |
44+
| 회전/상태 복원 크래시 | `#160` | `covered-by-open-pr` | `#728`에서 Activity 재생성 시 외부 import intent 재처리를 막는 1차 가드를 넣었다 | `#728` 병합 후 실제 회전 회귀를 확인하고 정리 |
4545
| `.so`/ELF/autosetup | `#514`, `#543`, `#576`, `#137` | `planned-fast-follow` | 기능 버그와 기능 요청이 섞여 있다 | `.so` 열기 재현 후 parsing/autosetup을 분리해서 다룬다 |
4646
| crash report 저신호 묶음 | `#716`, `#672`, `#512`, `#508`, `#507`, `#490`, `#438`, `#376`, `#280` | `needs-repro` | 제목만으로는 원인 판단이 어렵고 재현 자료가 부족하다 | 공통 템플릿으로 추가 정보 요청 후 재현 안 되면 정리 |
4747
| SWF 요청 중복 | `#721`, `#112` | `planned-fast-follow` | 같은 방향의 기능 요청이다 | 최신 요청 `#721` 중심으로 정리하고 하나는 중복 처리 검토 |

docs/maintenance/implementation-log.ko.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
| 이슈 `#670` 앱 런처 미노출 | `MainActivity``android:enabled="true"`를 명시 | 일부 기기/설정에서 런처 진입점이 빠지는 문제를 명시적으로 막았다 | `app/src/main/AndroidManifest.xml` | 완료 |
2424
| 이슈 `#396` Hex 화면 가독성 문제 | Hex view를 16바이트 행, offset 컬럼, ASCII 컬럼 구조로 재구성 | 바이너리 탐색 시 위치와 내용이 동시에 보이도록 바꿨다 | `app/src/main/java/com/kyhsgeekcode/disassembler/ui/components/HexView.kt` | 완료 |
2525
| 이슈 `#348` Disassembly 탭 가로 스크롤 민감도 | 수평 스크롤 책임을 외곽 컨테이너로 옮겼다 | 긴 디스어셈블리 라인에서 좌우 이동이 더 안정적으로 동작하도록 조정했다 | `app/src/main/java/com/kyhsgeekcode/disassembler/ui/tabs/BinaryDisasmTab.kt` | 완료 |
26+
| 이슈 `#160` 회전 시 재진입 크래시 후보 | `MainActivity`가 재생성될 때 기존 `ACTION_VIEW`/`EXTRA_STREAM` intent를 다시 처리하지 않도록 가드하고, 새 외부 인텐트는 `onNewIntent`에서만 처리하도록 분리 | 회전 같은 configuration change에서 같은 import 요청이 중복 실행되는 경로를 차단해 상태 복원 중 재import/중복 초기화 가능성을 줄였다 | `app/src/main/java/com/kyhsgeekcode/disassembler/MainActivity.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/MainActivityIntentHandlingTest.kt` | 완료 |
2627
| 프로젝트 경로/파일명 회귀 방지 | 프로젝트 상대경로 계산과 import 파일명 정규화를 pure helper로 분리 | 단위 테스트가 가능하도록 로직을 분리하고 경계 케이스를 줄였다 | `app/src/main/java/com/kyhsgeekcode/disassembler/project/ProjectManager.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/viewmodel/MainViewModel.kt` | 완료 |
2728
| 회귀 테스트 부재 | `ProjectManager`, 저장소 권한, Hex 레이아웃, import 파일명 테스트 추가 | 최소한의 유지보수 안전망을 확보했다 | `app/src/test/java/com/kyhsgeekcode/disassembler/ProjectManagerTest.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/PermissionUtilsTest.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/ui/components/HexViewLayoutTest.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/viewmodel/ImportedFileNameTest.kt` | 완료 |
2829

@@ -40,6 +41,7 @@
4041
| 파워유저 advanced source catalog 테스트 | 통과 | power-user 비활성 시 advanced source 없음, 활성 시 선택된 source group만 노출 |
4142
| persistable URI permission helper 테스트 | 통과 | content scheme + persistable/read 플래그 조합만 유지 대상으로 판정 |
4243
| project source helper 테스트 | 통과 | source file 및 `_libs` 경로 계산이 helper 계약으로 고정 |
44+
| `MainActivity` intent 재처리 가드 테스트 | 통과 | 첫 생성에서는 처리, 회전 재생성에서는 건너뛰는 규칙을 고정 |
4345
| workflow YAML 파싱 | 통과 | `.github/workflows/ci.yml`, `.github/workflows/release.yml` 모두 Ruby YAML 파서 기준 확인 |
4446

4547
## 다음 웨이브 후보

0 commit comments

Comments
 (0)