<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Unescaping Special Characters in Android Applications | Infinum</title>
		<atom:link href="https://infinum.com/blog/unescaping-special-characters/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/unescaping-special-characters/</link>
		<description>Building digital products</description>
		<lastBuildDate>Tue, 07 Apr 2026 14:19:20 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7984https://infinum.com/uploads/2021/03/unescaping-special-characters-0.webp</url>
				</image>
				<title>Unescaping Special Characters in Android Applications</title>
				<link>https://infinum.com/blog/unescaping-special-characters/</link>
				<pubDate>Fri, 26 Mar 2021 10:45:00 +0000</pubDate>
				<dc:creator>Ivan Kocijan</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/unescaping-special-characters/</guid>
				<description>
					<![CDATA[<p>Try these two approaches if you need to escape strings.</p>
<p>The post <a href="https://infinum.com/blog/unescaping-special-characters/">Unescaping Special Characters in Android Applications</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-158"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	Android being a client-side platform, developers deal with many different APIs on a daily basis. Some of these APIs are great, some of them not really, but we can work with anything that a backend sends us.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	A while ago, we had an atypical request from our backend developers. They asked us to unescape every string in the app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	This meant that the strings from the backend would contain special characters which we needed to replace. For example, &amp; sign would be &amp;amp;, apostrophe would be &amp;apos; and so on. It was atypical because it’s not often that developers handle such a case in mobile apps. We make an API call and show the string which came from the backend as is.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-102">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-103'
	>
	Why unescape special characters?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	Although strange at first, the backend guys had a good reason for this. They were developing a platform which can be used by anyone, not only the Android application.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-108">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-109'
	>
	Other frontend clients could add items to the platform and they didn’t have control over how they would do it. In order to minimize cross-site scripting (XSS) vulnerability, they sanitized strings saved to the backend and they wanted to be sure they don’t send back anything exploitable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	Another reason why you would want to do this is to save the formatting of a string backend sends. If you want to show a multiline string, then you would format the string so it’s shown as expected.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-114">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-115'
	>
	Unescaping special characters for every string</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	If your backend escapes every string it returns, you need a method to unescape them all in one place. In Android, if you use Moshi, you can do it by defining an application-wide serializer for the String class.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class StringSerializer</span><span class="token">() </span><span class="token">: </span><span class="token" style="color: #6f42c1;">JsonAdapter</span><span class="token">&lt;</span><span class="token" style="color: #6f42c1;">String</span><span class="token">&gt;</span><span class="token">() {
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun fromJson</span><span class="token">(reader</span><span class="token">: </span><span class="token" style="color: #6f42c1;">JsonReader</span><span class="token">)</span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token">? </span><span class="token">{
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Unescape characters</span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">@Throws</span><span class="token">(IOException</span><span class="token">::</span><span class="token" style="color: #6f42c1;">class</span><span class="token">)
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun toJson</span><span class="token">(writer</span><span class="token">: </span><span class="token" style="color: #6f42c1;">JsonWriter</span><span class="token">, </span><span class="token" style="color: #d73a49;">value</span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token">?</span><span class="token">) {
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Escape characters or do nothing </span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-122">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-123'
	>
	Then add the serializer when defining Moshi.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-126"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">Moshi</span><span class="token">.Builder</span><span class="token">()</span><span class="token">.add</span><span class="token">(String</span><span class="token">::</span><span class="token" style="color: #6f42c1;">class</span><span class="token">.java, </span><span class="token">StringSerializer</span><span class="token">())
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-129"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-127">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-128'
	>
	If you initialize Moshi in one place and use the same instance across the app all your strings will be unescaped and your work is done.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-132"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-130">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-131'
	>
	Unescaping special characters for certain strings</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-133">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-134'
	>
	Sometimes, you might need to unescape special characters only for certain strings in the app. If this is your case, you can do this by defining an annotation which will be used only on those strings.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-137"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">@Retention</span><span class="token">(AnnotationRetention.RUNTIME)
</span></span><span class="line"><span class="token" style="color: #6f42c1;">@JsonQualifier</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">annotation</span><span class="token"> </span><span class="token">class Escaped
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-138">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-139'
	>
	Then, create a serializer and annotate the fromJson method and toJson parameter.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class EscapedStringSerializer</span><span class="token">() {
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">@FromJson</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">@Escaped</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">fun fromJson</span><span class="token">(reader</span><span class="token">: </span><span class="token" style="color: #6f42c1;">JsonReader</span><span class="token">)</span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token"> </span><span class="token">{
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Unescape special characters</span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">@ToJson</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">@Throws</span><span class="token">(IOException</span><span class="token">::</span><span class="token" style="color: #6f42c1;">class</span><span class="token">)
</span></span><span class="line"><span class="token">    </span><span class="token">fun toJson</span><span class="token">(</span><span class="token" style="color: #6f42c1;">@Escaped</span><span class="token"> </span><span class="token" style="color: #d73a49;">value</span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token">?</span><span class="token">) </span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token"> </span><span class="token">{
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Escape special characters or do nothing</span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-145"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-143">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-144'
	>
	After defining the annotation and serializer you can annotate any escaped string in your models.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class MyClass </span><span class="token">(</span><span class="token" style="color: #6f42c1;">@Escaped</span><span class="token"> </span><span class="token" style="color: #6f42c1;">@Json</span><span class="token">(name </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">description</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">) </span><span class="token">val </span><span class="token">description</span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token">) 
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-148">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-149'
	>
	Is unescaping for me?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-151">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-152'
	>
	Unless you load strings in a WebView, you probably don’t have a problem with XSS in your Android app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-156"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-154">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-155'
	>
	In most cases, mobile apps get a string from an API and show it in a TextView. However, if you really need to escape strings, it’s good to know you can use one of these two approaches.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/unescaping-special-characters/">Unescaping Special Characters in Android Applications</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>