모바일 애플리케이션

[안드로이드/JAVA] java.util.UnknownFormatConversionException

java.util.UnknownFormatConversionException 문제


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 와 같이 소수점 자리수가 없을 때. 이 있어서는 안됩니다.

 

JooTC

안녕하세요. 테크놀로지에 관심이 많은 블로거입니다.

Recent Posts

[iOS] Xcode ‘You do not have required contracts to perform an operation’ 해결

Xcode에서 iOS 애플리케이션을 빌드(Archive)하고 App Store Connect에 앱을 업로드하는 도중, 아래와 같은 에러가 발생하면서 더…

1주 ago

[안드로이드] INSTALL_FAILED_INSUFFICIENT_STORAGE 해결

INSTALL_FAILED_INSUFFICIENT_STORAGE 문제 안드로이드 스튜디오에서 에뮬레이터를 실행하고 개발중인 애플리케이션을 실행하려 하면 로그 창에 아래와 같이 표시되면서…

6개월 ago

Zalgo 텍스트와 이를 방지하는 방법

인터넷 커뮤니티 사이트에서 게시글이나 댓글에 간혹 장난을 목적으로 작성된 특이한 글자를 볼 수 있습니다. 위…

8개월 ago

리눅스 kill, killall 명령어 – 특정 프로세스 종료하기

리눅스 명령어 - kill, killall 리눅스 kill 명령어는 특정 프로세스를 종료해주는 명령어입니다. 백그라운드에서 실행되고 있는…

8개월 ago

JavaScript typeof null이 ‘object’인 이유

JavaScript는 역사가 긴 스크립트 프로그래밍 언어입니다. 세월이 흐르면서 많은 자바스크립트 표준이 만들어졌고, 현재는 많은 문법적…

8개월 ago

Mocha Error: Resolution method is overspecified. 해결 방법

NodeJS 테스트 프레임워크인 Mocha는 비동기 테스트를 지원합니다. 간혹 특정 테스트 스크립트를 작성하고 실행하면 아래와 같이…

8개월 ago