strings.xml
파일을 수정하고 애플리케이션을 실행하던 도중, 다음과 같은 예외 문제가 발생하면서 앱이 강제로 종료되었습니다.
2019-08-06 12:44:51.056 11935-11935/com.company.appname E/AndroidRuntime: FATAL EXCEPTION: main Process: com.company.appname, PID: 11935 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.appname/com.company.appname.MyActivity}: java.util.UnknownFormatConversionException: Conversion = ')' at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) Caused by: java.util.UnknownFormatConversionException: Conversion = ')' at java.util.Formatter$FormatSpecifier.conversion(Formatter.java:2781) at java.util.Formatter$FormatSpecifier.<init>(Formatter.java:2811) at java.util.Formatter$FormatSpecifierParser.<init>(Formatter.java:2624) at java.util.Formatter.parse(Formatter.java:2557) at java.util.Formatter.format(Formatter.java:2504) at java.util.Formatter.format(Formatter.java:2458) at java.lang.String.format(String.java:2883) at android.content.res.Resources.getString(Resources.java:466) at android.content.Context.getString(Context.java:594) at com.company.appname.StringUtils.setSpanTextWithStrings(StringUtils.java:47) at com.company.appname.MyActivity.onCreate(MyActivity.java:34) at android.app.Activity.performCreate(Activity.java:7136) at android.app.Activity.performCreate(Activity.java:7127) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 2019-08-06 12:44:51.077 11935-11935/com.company.appname I/Process: Sending signal. PID: 11935 SIG: 9
상단 부분을 살펴보면 대략 다음과 같은 문제임을 알 수 있습니다.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.appname/com.company.appname.MyActivity}: java.util.UnknownFormatConversionException: Conversion = ')'
특정 액티비티에서 String.format
메소드에 의해 알 수 없는 포맷을 참조하려 하다가 문제가 발생한 것으로 보입니다. strings.xml
의 어디선가 발생한 포맷 에러인 것 같습니다.
이 문제는 다양한 원인 (잘못된 문자열 포맷)으로 인해 발생할 수 있기 때문에 여기에 있는 해결책으로 해결되지 않을 수 있습니다. 가장 좋은 방법은 문제가 발생한 시점에 strings.xml
에서 수정한 내용을 살펴보는 것입니다.
먼저 퍼센트 기호를 잘못 사용한 경우입니다. 다음 예시를 확인해보겠습니다.
<resources> <string name="today">오늘의 달성률은 100%입니다.</string> </resources>
특별한 문제가 없어보이지만, 문제는 퍼센트 기호(%
)에 있었습니다. String.format
메소드를 사용할 때는 strings.xml
에서 퍼센트 기호를 사용할 때 일반적으로 사용하듯이 %
를 사용해서는 안되며, 이스케이프 문자(\
)를 사용해도 마찬가지입니다.
이럴 때는 %
대신 %%
기호를 붙이면 해결됩니다. 퍼센트 기호를 하나 더 붙이면 에러가 발생하지 않을 것입니다.
<!-- 문제가 없는 코드 --> <resources> <string name="today">오늘의 달성률은 100%%입니다.</string> </resources>
다음으로 아래와 같이 %d
, %s
와 같은 정수와 문자열 포맷 이외에 존재하지 않는 포맷을 사용하려 하는 경우에도 문제가 발생합니다. (퍼센트 기호를 위와 같이 두 개를 사용하지 않는 것과 같은 현상입니다.)
<resources> <string name="today">오늘의 달성률은 100%percent</string> </resources>
또는 다음과 같이 실수형 포맷을 잘못 사용하는 경우도 있습니다.
<resources> <string name="result">소수 표현: %3.f</string> </resources>
실수형 포맷은 %.2f
혹은 %2.4f
(숫자는 임의)와 같은 형식으로 사용되어야 합니다. 여기서 콤마(.
)의 좌측 숫자는 폭(전체 수치의 영역 크기), 우측 숫자는 소수점의 자리수에 해당합니다. 위 예시에서의 %3.f
와 같이 소수점 자리수가 없을 때는 .
이 있어서는 안됩니다.
리눅스 명령어 - kill, killall 리눅스 kill 명령어는 특정 프로세스를 종료해주는 명령어입니다. 백그라운드에서 실행되고 있는…
JavaScript는 역사가 긴 스크립트 프로그래밍 언어입니다. 세월이 흐르면서 많은 자바스크립트 표준이 만들어졌고, 현재는 많은 문법적…
NodeJS 테스트 프레임워크인 Mocha는 비동기 테스트를 지원합니다. 간혹 특정 테스트 스크립트를 작성하고 실행하면 아래와 같이…
언제부턴가 윈도우 11을 처음 설치할 때 마이크로소프트(Microsoft) 계정 로그인을 강제로 요구하게 되었습니다. 물론 마이크로소프트 계정이…
애플 에어팟 프로 2 (AirPods Pro 2) 케이스에는 스피커가 내장되어 있습니다. 그런데 간혹 아무 것도…