<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Knowing Android - Medium]]></title>
        <description><![CDATA[Android development in Spanish and English | Desarrollo de Android en Español e Ingles - Medium]]></description>
        <link>https://medium.com/knowing-android?source=rss----b5e76c10d720---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Knowing Android - Medium</title>
            <link>https://medium.com/knowing-android?source=rss----b5e76c10d720---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 03:40:45 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/knowing-android" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Master Class on Security (part 1)]]></title>
            <link>https://medium.com/knowing-android/security-for-android-developers-part-1-ce5b63bcf82a?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/ce5b63bcf82a</guid>
            <category><![CDATA[android-development]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[encryption]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Fri, 03 Oct 2025 15:37:27 GMT</pubDate>
            <atom:updated>2025-10-13T01:12:41.445Z</atom:updated>
            <content:encoded><![CDATA[<h4>For Android Developers — from Encryption to Passkeys and Keystore</h4><p>If you are here, probably you know my other series of blog posts called <a href="https://medium.com/google-developer-experts/modern-security-in-android-part-1-6282bcb71e6c">Modern Security for Android Developers</a> — While that series has an incredible story and is still very usable to use, there are some changes in the API and Security layers in the last couple years inside the ecosystem that make it a little bit outdated, so here it is, the remastered version</p><p>Here is the list of the parts in this series:</p><ul><li><a href="https://ddinorahtovar.medium.com/security-for-android-developers-part-1-ce5b63bcf82a"><strong>Part 1 — Encryption</strong></a></li><li>Part 2 — Credential Manager API</li><li>Part 3—Passkeys</li><li>Part 4 — Android Keystore Deep Dive and Secure Key Management</li><li>Part 5 — Integrity and Network security</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NIFsgA6Ub3T48qqMjZzfLw.png" /><figcaption>This image was generated by Gemini Nano Banana (and is a lock, not a thermostat)</figcaption></figure><h3>Part 1 — Encryption</h3><p>Encryption is one of the most crucial parts of any software, and inside Android this is not an exception</p><p>Android has a wide array of algorithms for protecting data using cryptography. In software there are multiple algorithms (or a esult of algorithms) that are constantly used for security and confidentiality. Usually, this depends of the Cryptographic Architecture that this languages and OS have available<br>For Android this falls on the land of Java Cryptography Architecture (JCA) that is designed to offer an extensible mechanism for cryptographic services, including Hash, mathematical schemes and cryptographic keys, and others</p><p>Some of these task are terms that are allocated inside the cryptographyc architecture— <strong>Cipher</strong>, <strong>MessageDigest</strong>, <strong>MAC</strong>, and <strong>Signature</strong> — and refer to fundamental concepts and tools inside the JCA, each serving a different security goals</p><h4><strong>Cipher</strong></h4><p>An algorithm used for encryption and decryption. Its main purpose is to ensure confidentiality by transforming plain text into an unreadable form also known as ciphertext, and uses a mathematical algorithm and a secret key to scramble the data.</p><p>Ciphers fall into two main categories based on key usage: <br><strong>Symmetric Ciphers:</strong> Use a single secret key for both encryption and decryption, they are usually faster</p><p><strong>Asymmetric Ciphers</strong> (or Public-Key Ciphers): Use a pair of keys (a public key for encryption and a private key for decryption) they are used for secure key exchange and digital signatures</p><p>One of the most important parts is that it uses a pair of keys — a public key for encryption and a private key for decryption and they have different types of algorithms</p><p><strong>The algorithms can be</strong>: Advanced Encryption Standard (AES) or Rivest–Shamir–Adleman (RSA)</p><ul><li><strong>AES</strong> a cipher by blocks (symmetric) <br>In Android development, AES is the workhorse for bulk data encryption (e.g., local files, databases) due to its speed</li><li><strong>RSA</strong> a cipher with a public Key (non symmetric)<br>RSA is primarily used for smaller tasks like securely wrapping an AES key (key exchange) or for digital signatures, but is much slower for encrypting large amounts of data</li></ul><p><strong>The mode is: </strong>how the algorithm process the data in cipher chunks for example AES need this, the cipher mode is critical for security. A common and recommended mode is GCM (Galois/Counter Mode), which not only dictates <em>how</em> the data is chunked but also provides authenticated encryption. This means it ensures both confidentiality (encryption) and data integrity (it hasn’t been tampered with).</p><p><strong>The Padding is:</strong> the part of the encryption required for cipher that work in blocks, when you are working with blocks then the size of said block needs a exact size (ex. 128 bits para AES), the padding act as padding that add additional bytes at the end of the original message if the message doesn’t fulfill the size. For instance, if you are encrypting a 130-bit message with AES-128 (which uses 128-bit blocks), the padding scheme (like PKCS#7) will add 126 bits of padding to create a complete second 128-bit block, ensuring the entire message can be correctly processed by the block cipher</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tjpOhVOwob3jDMvHOseG6g.png" /></figure><p>You can see all the algorithms supported by Android and Android Versions <a href="https://developer.android.com/guide/topics/security/cryptography#supported-algorithms">here</a></p><h4>Message Digest</h4><p>A cryptographic <strong>hash function,</strong> that takes an input of the message without mattering the size and produces a fixed-size, unique-looking output called a hash value or digest.<br>Usually they are used for verification to make sure that data hasn’t been changed and it is computationally and mathematically impossible to reverse the process to find the original message or to find two different messages that produce the same digest (collision resistance). It does <strong>not</strong> use a key.<br>For Android: <strong>SHA-256 </strong>is the most common</p><h4>Message Authentication Code (MAC)</h4><p>A fixed-size tag generated from a message using a cryptographic algorithm and a secret key. Commonly used for data integrity and to match origin authentication <br>It is appended to the message both, the client and the receiver share the same symmetric key and the receiver uses it to calculate the MAC on the message and compares it<br>For Android: <strong>HMACSHA256</strong> (Hash-based MAC) is the most common</p><h4>Digital Signature (Signature)</h4><p>A mathematical scheme for verifying the authenticity and integrity of a message. It is created using a private key and is verified using the corresponding public key, this is usually what we think when we discuss public and private keys in software security</p><p>This algorithms can be used for many encryption processes, however, if your app requires a higher degree of key security, you should use the Android Keystore system, this allows you to store cryptographic keys in a container, making them significantly harder to extract from the device, once keys are in the Keystore, the key material remains non-exportable</p><p>We are gonna talk about Keystore in the following parts, as a proper substitution for the now <strong>deprecated <em>security-crypto</em></strong> Jetpack library that used to provide a wrapper like <strong>EncryptedSharedPreferences</strong> and <strong>EncryptedFile</strong> to simplify encryption for local data storage. This library is deprecated (as of v1.1.0-alpha07 in April 2025 and stable release 1.1.0 in July 2025) in favor of existing platform APIs and direct use of Android Keystore. For developers looking to replace EncryptedSharedPreferences, the modern platform solution is using <strong>DataStore</strong> combined with keys managed by <strong>Android Keystore</strong> to encrypt the underlying file — we are gonna discuss how to implemented it in the last part of this serie, that meets all the security requierements that are usually need it</p><p>This is all for this part of the posts, If you need help:</p><p>I’m always happy to help, you can find me here:</p><p>BlueSky: <a href="https://bsky.app/profile/ddinorahtovar.bsky.social">https://bsky.app/profile/ddinorahtovar.bsky.social</a><br>X: <a href="https://x.com/DDinorahtovar">https://x.com/DDinorahtovar</a><br>Medium: <a href="https://medium.com/@dinorahto">https://medium.com/@dinorahto</a><br>StackOverflow: <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">https://stackoverflow.com/users/4613259/dinorah-tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ce5b63bcf82a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/security-for-android-developers-part-1-ce5b63bcf82a">Master Class on Security (part 1)</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Product visions: From an engineering perspective]]></title>
            <link>https://medium.com/knowing-android/product-visions-from-an-engineering-perspective-bb6a2463e393?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/bb6a2463e393</guid>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[product-management]]></category>
            <category><![CDATA[product]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[mobile]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Mon, 19 Apr 2021 17:39:29 GMT</pubDate>
            <atom:updated>2021-04-19T17:38:55.186Z</atom:updated>
            <content:encoded><![CDATA[<p>An opinionated letter to product engineering</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iuUQ_i09znTW7qL24-HQRg.png" /><figcaption><a href="https://www.instagram.com/p/CEf3LkOAF45/">We’re not really strangers</a></figcaption></figure><p>This blog post is quite different from everything I have ever published, this is an open letter <strong>for all the developers and all the people in Product</strong>, that are building consumer-facing features, including non-only UI experiences, but also the ones that are creating APIs, security, and Architectural layers. This is gonna be a couple of opinionated comments and visions of how we should address some ideas, feedback, and mostly dilemmas around our profession.</p><p>I have been a mobile engineer for many years, around my time as a professional I had the pleasure to grow in many different positions, from platform, architecture, and product — all these different areas, are involved with the users, some have a closer interaction than the others and today I’m gonna tell you a story about some lessons that were learned in a hard way over multiple years.</p><h4>The feature is not only a problem to solve</h4><p>I used to think of features as a problem we need to address, we made rationals about architecture, task, and actions to tackle, we go over ideas from using X over Y and how long it would us to build that new functionality, everything ends up revolving around Jira tickets and sprints.</p><p>In my first years I learned that asking <strong>“why” was as important as asking “how”, </strong>‘cause engineering is about<strong> </strong>being<strong> </strong>resourceful to our counterparts in different areas, we need to create a retroactive chain of creativity with multiple stages that makes us aware of solutions, proposals, and process; that’s why I believe that a good product engineer should be strongly tied to the proposals from UX/UI, research, and growth.</p><p>As engineers sometimes we ended up thinking that we don’t need to be involved in this chain at all, hiding us behind the excuse that if we are not experts other than our areas, we should stay behind — A couple of months ago one developer told me that he was not involved in this kind of process and prefers to non-being a point of intervention, he believes that having this kind of affairs were tiresome and must of the times boring — Probably many engineers think of Product or Growth areas in the same way, but the factual reason of thinking this way is that we don’t have a culture revolving around the product (which is one of hardest to cultivate); whatsoever <strong>zero-intervention will create mediocre developers, but also mediocre products. </strong>One may wonder, why? the answer is quite simple, imagine this a chessboard knowing where all the pieces are placed give you the capacity of planning your next step, so having the understanding of decisions give you improvements on future areas of your codebase and operations, maintainability, and opportunities for growth, you became a player and not an observer.</p><h4>Asking the correct questions</h4><p>Creating a good relationship of Product with Tech is a maze, but everybody can solve it even when is not for everyone; a good starting point is <strong>asking the correct questions</strong> <strong>to the right people, </strong>also is start seeing us [engineers] as more than executors.<br>I’ve been thinking very deeply and profoundly about where do we stand as engineers if what we are gonna build in with tons of lines of code is gonna be in the hands of tons of users, are we a huge broadcast? where do we stand today inside the process? <strong>Are we executors or are we part of the procedure?</strong> I think I don’t have an answer, I believe we need to be in the middle of the whole process.<br>In the light of being resourceful, we need to deliver criticism and be honest about processes that may not be correct, secure, or straightforward for our users, we need to be really heart-spoken and opinionated when we get to deliver feedback with our users in mind — A year ago, I was building a new chart for our users, I didn’t understand what I was doing, the logic was tricky in the good light and horrible in the bad one, it was a failure in production — I forgot the user that day, that feature was not good enough, it was noisy and the UX/UI just make it worse.<br>I should have asked the correct question to get my concerns addressed, but I was playing the “only a developer” role that day, I remember hearing “this was a normal mistake” and thinking, “No, it’s not, we spend weeks building a feature that was poorly checked that could be way simpler”, there are always ways to simplify the noise around features and is our job to make it simpler. <br>There’s a design law for simplicity and limitations called Tesler’s law:</p><blockquote>Every application has an inherent amount of complexity that cannot be removed or hidden. Instead, it must be dealt with, either in product development or in user interaction.</blockquote><p>Every feature we build should land in the limits of Tesler’s law, we need to safeguard our users and our teams from experiences that are nonventilated to the law, we may not be a group of experts, but we can ask tons of questions to help our teams and our products to grow. Asking the correct question will eventually lead us to start a dialogue, a dialogue will start a feedback session and this is where we can stop being only executors to be part of this constructive chain.</p><h4>Ideas, Thoughts, and Comments</h4><p>Asking this amount of questions will definitely lead us to something I call — a space of creativity — which is where we can grow a culture of dialogue and product. <br>As an engineer, we need to work on our communications skills to deliver dialogues that are beneficial for creativity and invention, without adding the common “tech fog” in the process that will lead us to go too technical, especially because this creates a dome that pushes the conversation to the boundaries of &quot;tech square&quot; and creates a mental box for solving a problem; so we end up with a halfway solution proposed by tech that only addresses half the problem, <strong>having good communication skills and trying to improve them is key</strong> to go to the next step; In the last couple of months, I have been trying to walk out of the woods and the fog and one of the things that have helped me the most is understanding what an idea, a thought, and a comment are.</p><p>An idea and thought are two words that are often confused when it comes to their meanings and connotations. The idea refers to a plan or a process that occurs in the mind in relation to the completion of work or duty, on the other hand, a thought is a mental process that keeps on going in the mind unabated. A comment is an adjacent and overview part to a principal concept, the first one can not live without the second one but the second one can live without the first one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/1*ZWmraIocOw-51-wWk7teNA.png" /></figure><p>Having this concept clear will helps us to talk about any topic, from delivering feedback to developing a strategy, and making decisions, it also opens the door to complex and difficult problems.</p><p>Some teams especially in Growth and Product will choose practices and theoretical processes that can hurt more than the benefit that brings to the users, as Developers we are the last straw to stop a dangerous process, when it may work for the other teams it may compromise the integrity of the product we are building, for example, privacy.</p><h4>Complex topic and moral dilemmas</h4><p>After being able to handle communications and thoughts, we can talk about dilemmas that may not be the easiest topics to address without having some kind of confrontation with the team that is using some tool or method. Privacy has always been a moral dilemma, especially inside technology companies — It shouldn’t be — as engineers we end up planning how we address this dilemma, is our responsibility to keep our users safe and keep it away from prying eyes we take hard considerations about stored data in phones and databases, we think of methods of encryption from ciphers to certificates, going from Keystore to Keychain, but we may forget that this also includes Product, from analytics to multiple tools to do user research.<br>Almost a year ago I published this tweet asking about the implications of Session Replay software (a tool that recreates the clicks and views of a User)[<a href="https://freedom-to-tinker.com/2017/11/15/no-boundaries-exfiltration-of-personal-data-by-session-replay-scripts/">No boundaries: Exfiltration of personal data by session-replay scripts</a>] and crossing the boundaries of privacy and personal data.</p><h3>Dinorah Tovar on Twitter: &quot;Asking the right questions here:What do you think about session replay software, on websites/mobile apps/progressive apps? Share your thoughts and opinions below. / Twitter&quot;</h3><p>Asking the right questions here:What do you think about session replay software, on websites/mobile apps/progressive apps? Share your thoughts and opinions below.</p><p>The “Neutral” option is not a position we can take, the implications and normativity of these <strong>tools should be taken into consideration by developers</strong> — that are putting the SDK on the user phones — and by the Product persons — that are consuming this data — <strong>building team integrity will create integrity for the products. </strong><br>At the end of the day, we are responsible for the decisions we take and make, we have a voice that needs to be heard around all the areas we can reach, make ourselves opinionated, and ask questions, especially this one, not only makes us better professionals but also better human beings.</p><h4>Black boxes are like half-empty glasses</h4><p>I use to think that Tech and Product were areas full of black boxes, I don’t let myself think as an executor in a black box fulfilling the wishes of other boxes, thinking this way gives us only half of the solution and probably the poorest one, it puts us inside a block that only knows <strong>half the answers to half of the questions</strong>. A good product solves a problem in the finest possible way, and this involves security, architecture, UX/UI, and performance. Thinking in a holistic way will bring us stronger ideas and solutions, but especially a culture that can be a harvest for years to come.</p><p>So, if you are at the end of this post, the only advice I can securely give you is that being a passive Software Engineer will lead you to become an executor, you won’t be creating products, you will only produce code; and friend, that’s two completely different things, so remember that, <strong>you are here to build products, not only code.</strong></p><h4>Disclaimer</h4><p>I am not in the product area, these are opinions of how I conduct myself every day. I hate the word <em>user</em>, I think it cuts down the person that is consuming your app to a number, we tend to minimize this and we end up caring less about some parts. And finally, I’m always open for comments on my Twitter account or here.</p><p>If you need help, I’m always happy to help, you can find me here:<br>Medium as <a href="https://medium.com/u/676a20de80ad?source=post_page-----e74944f57a85--------------------------------">Dinorah Tovar</a><br>Twitter as <a href="https://twitter.com/DDinorahtovar">@ddinorahtovar</a><br>StackOverflow as <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">Dinorah Tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bb6a2463e393" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/product-visions-from-an-engineering-perspective-bb6a2463e393">Product visions: From an engineering perspective</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Wild Storage | Part 3— DataStore and SharedPreferences]]></title>
            <link>https://medium.com/knowing-android/wild-storage-part-3-datastore-and-sharedpreferences-b32e8686f22b?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/b32e8686f22b</guid>
            <category><![CDATA[jetpack-datastore]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[data]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Mon, 15 Mar 2021 23:15:14 GMT</pubDate>
            <atom:updated>2021-03-15T23:15:30.562Z</atom:updated>
            <content:encoded><![CDATA[<p>For Android Developers</p><p>Easy data layer for every Application, here is the list of the blogs in this series:</p><ul><li><a href="https://medium.com/knowing-android/wild-storage-part-1-performance-for-queries-661f11be9066">Part 1 — Performance for queries</a></li><li><a href="https://medium.com/knowing-android/wild-storage-part-2-threading-and-concurrency-40f38992ca2d">Part 2 — Threading and Concurrency</a></li><li><a href="https://medium.com/knowing-android/wild-storage-part-3-datastore-and-sharedpreferences-b32e8686f22b"><strong>Part 3 — DataStore and SharedPreferences</strong></a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pLF8sX1aUCdp29kd.jpeg" /><figcaption><a href="https://unsplash.com/photos/-IZ2sgQKIhM">This image is from Unsplash</a></figcaption></figure><p>This is the second part of the series <strong>“Wild Storage for Android developers”</strong> today we are gonna discuss <strong>Data Store and Shared preferences, </strong>specifically why they are an alternative to the normal Database</p><p>So in the past part, we talk about how Room can help us to handle threading and concurrency, this is something that was missing inside SharedPreferences which is one of the most primitive ways to save data inside Android! Let’s talk about Shared preferences and Data Store</p><h4>Shared Preferences and Data Store</h4><p>I have been getting this question around for a while, DataStore is the same as Shared Preferences? Well, the short answer is no!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V4rqe6DtnMshX7QUiFE_zA.png" /></figure><p>The main reason is that SharedPreferences has the next qualities that make it one of the most simple approaches, also pretty much follows the pattern of a file that stores a <em>Key-Value</em> in an XML file, that you can found in a debug app if you search for it, whatsoever is private for other apps and even trying we can not reach for it, a couple of years ago you can create a SharedPreference file with some public modes like MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE that have been deprecated and if you wanna use something like this, your app will crash with a SecurityException.</p><ul><li>Synchronous updates — All the process run in the main thread</li><li>Primitive Values — The only values available are Boolean, Int, String, or even a Set&lt;T&gt; where T is a primitive value</li><li>They can also be encrypted — SharedPreferences are the main instrument inside the incredible library androidx.security:security-cryptothat can encrypt data using a KeyStore approach, but it also follows the same restrictions and approaches that normal SharedPreferences, so, you can only encrypt primitive values, that is more than enough for multiple tasks that requires encryption.<br>If you wanna know how to encrypt data, you can review my past serial <a href="https://medium.com/knowing-android/modern-security-in-android-part-1-6282bcb71e6c">“Modern Security for Android Developers” on Google Developer Expert Blog</a></li></ul><p>For DataStore is focus on handling the overwork some teams were putting on SharedPreferences, especially with a focus on the threading integration.</p><ul><li>Asynchronous updates — All the process of editing and fetching data from the schema of DataStore are addressed over a flow that represents the stream of values that are being asynchronously computed</li><li>Objects — You can have an object inside DataStore with the use of ProtoBuffers that will make this approach type safe, without this, you will be able to store only Key-Value primitives without type safety</li><li>Encryption — There’s non available encryption for the moment for DataStore, but you can Encrypt a full data base using Room or Realm</li></ul><p>One of the most important parts of DataStore in a simple way:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6S73tPmfNyYo8uK2IYYahw.png" /></figure><p>Using the first way, you will create a simpler DataStore&lt;Preferences&gt; object and with the secon, you will create a migration from the SharedPreferences you were using in the past.</p><p>DataStore use Flow to extract data from your Preferences object, that provides efficient, cached access to the latest persisted state, then flow will take one of this two actions: Emit a value or throw an exception</p><p>You can safe data and get the values using this approach</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*gcs8r8cjKPN9JNEXPkbNkA.png" /></figure><p>For Protobuffers, we need to create an new object that extends Serializer with all override all the objects need it to a sucessful serialization.</p><p>This is all for this serial! Feel free to ask any question here or at my Twitter account that you can found below!</p><p>If you need help, I’m always happy to help, you can find me here:<br>Medium as <a href="https://medium.com/u/676a20de80ad?source=post_page-----e74944f57a85--------------------------------">Dinorah Tovar</a><br>Twitter as <a href="https://twitter.com/DDinorahtovar">@ddinorahtovar</a><br>StackOverflow as <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">Dinorah Tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b32e8686f22b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/wild-storage-part-3-datastore-and-sharedpreferences-b32e8686f22b">Wild Storage | Part 3— DataStore and SharedPreferences</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Wild Storage | Part 2 — Threading and Concurrency]]></title>
            <link>https://medium.com/knowing-android/wild-storage-part-2-threading-and-concurrency-40f38992ca2d?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/40f38992ca2d</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[threading]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[room]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Sun, 14 Mar 2021 21:02:35 GMT</pubDate>
            <atom:updated>2021-03-15T23:16:06.694Z</atom:updated>
            <content:encoded><![CDATA[<h3>Wild Storage | Part 2 — Threading and Concurrency</h3><p>For Android developers</p><p>Easy data layer for every Application, here is the list of the blogs in this series:</p><ul><li><a href="https://medium.com/knowing-android/wild-storage-part-1-performance-for-queries-661f11be9066">Part 1 — Performance for queries</a></li><li><a href="https://medium.com/knowing-android/wild-storage-part-2-threading-and-concurrency-40f38992ca2d"><strong>Part 2 — Threading and Concurrency</strong></a></li><li><a href="https://medium.com/knowing-android/wild-storage-part-3-datastore-and-sharedpreferences-b32e8686f22b">Part 3 — DataStore and SharedPreferences</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pLF8sX1aUCdp29kd.jpeg" /><figcaption><a href="https://unsplash.com/photos/-IZ2sgQKIhM">This image is from Unsplash</a></figcaption></figure><p>This is the second part of the series <strong>“Wild Storage for Android developers”</strong> today we are gonna discuss <strong>Threading and Concurrency </strong>specifically for how coroutines work for Room</p><p>Putting some details about the last part, usually, we end up with something like this in Mobile applications, we may have a suspendable function that goes to an API, and once this answers the expected result we may want to put some data inside a database.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bljjvyQt9dc4_P1rIkKd5Q.png" /></figure><p>We don’t want funky performance, our users will notice if we have some trouble loading our views, usually, about 60 frames per second our users can perceive the change of frames as smooth if our tasks are taking more than 16 milliseconds (not only fetch from the database but also network calls, maybe loading a view or even startup time) this can cause us trouble on a big scale especially cause all our users will notice, so we may use some threading to handle this part in a successful way like I say in the first part of this serial you can use <em>Coroutines</em> to create a suspend function inside Room, but we need to talk about multiprocessing and threading first!</p><h4>Threads</h4><p>Multiprocessing is the use of CPUs inside a computer, is the ability inside the hardware to support more than one processor and allocate tasks between them, all smartphones have processors.</p><p>Depending on the hardware, the operating system, and the software design we are building we have may have some considerations to determine the symmetry of the multiprocessing system, some may be equal, others may be reserved. For example, we may decide that we only going to have one particular CPU respond to all actions, which will make this multiprocessing app easier to make, but it will make the app less efficient than others in which all CPUs are utilized with multiple processors allocated, the reason is quite simple, cause if we have the ability to set up all the process we will be able to create more that one thread of execution within a process, giving space to something called multi-threading.</p><p>Whatsoever between process, we may have multiple threads, then Thread #1 start his execution, we may have to create another Thread #2 to execute a secondary task, you can’t execute more than one thread at the exact same time, there’s a reason for this!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*DJErkgVsGzIhGUadC-L-fQ.png" /></figure><p>Everything that may happen in multiprocess architecture need at least this three parts: <em>Scheduler, Processor, and Dispatcher</em>, the first one is in charge of priorities like his name says is the method that will be assigned to resources that complete the work, and makes sure that all the threads get to run and get to finish, the Processor is the process of allocation of the task, and the Dispatcher make sure that set up all the threads in the specific allocation context we need to be executed, for Android in specific, we may have some operations that need to run in the user interface context and another outside of this one, the first one, is a thread that is full user-facing is called UI thread, runs inside the On Resume and Foreground of our apps and can dispatch other threads that may run in the background. All our apps need a basic thread to start and this will change, only if we explicitly switch threads inside the code, for example, the use of the keyword s<em>uspend</em> will switch the thread, this also applies for callbacks in <em>RxJava</em> or any <em>Thread</em>, <em>Run</em>, or <em>Handler</em> function, this applies for databases, network calls and mostly everything that we want to do to have a good performance in terms of user experience if we block UI Thread for too long this can cause the app to get blocked completely, this action is known as an ANR’s problems.</p><p>ANR problems can be tracked inside the Google Play Console in the Android Vitals part, and as quoted in the <a href="https://developer.android.com/topic/performance/vitals/anr">documentation</a></p><blockquote>Android vitals considers ANRs excessive when an app:</blockquote><blockquote>Exhibits at least one ANR in at least 0.47% of its daily sessions.<br>Exhibits 2 or more ANRs in at least 0.24% of its daily sessions.</blockquote><p>We are not gonna talk about ANR right now, but I will write a new serial in a couple of weeks called <strong>“Spikes of Performance”</strong> when we are going to revisit all the problems we may have not only in threading but also in loading views and writing files.</p><p>Handling threading and concurrency of confined threads in the database is a primordial key part for a good performance, which some database like <em>Realm</em> already have callbacks that can be used to execute transactions in a kind way, for <em>Room</em> we need to use <em>Coroutines</em></p><h4>Coroutines</h4><p>Not only <em>Coroutines</em> are the recommended solution for Kotlin development they are also really simple to approach cause basically a coroutine is thin threads and can be used in Room, whatsoever this is not obligatory, cause Room has the possibility to use Synchronous and Asynchronous methods with only using the key world <em>suspend</em></p><p>These two functions look exactly the same, but let’s review the code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rHx_Wm0jjKXOY48GRG7PmA.png" /></figure><p><strong>Synchronous vs Asynchronous<br></strong>We know that Room autogenerates code to helps us with the integration processes and to take the boilerplate that was implied when we use to do SQLite on Android, one of the most important parts of this, cause these two images are the autogenerated code from Room for a non-suspend function and a suspend function</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Y2SNz_uHSDzun5mvyFOPIw.png" /></figure><p>The first one and second one are pretty much similar in these specific parts that represent the generated code of an <em>Insert</em> to a table, this does not change even in asynchronous or synchronous code:</p><ul><li><em>beginTransaction</em> — Begins a transaction in <em>EXCLUSIVE</em> mode, this mode is pretty similar to IMMEDIATE modes in SQLite, in that a write transaction is started at the moment that is called, except that this mode prevents other database connections from reading the database while the transaction is underway.</li><li><em>insert</em> — That will insert the object inside the required table</li><li><em>setTransactionSuccessful</em> — Marks the current transaction as successful</li><li><em>endTransaction</em> — End a transaction that was created at the beginning with the first method</li></ul><p>As an <em>Asynchronous</em><strong> </strong>function, we can appreciate that the code executed is happening in the UI thread, there’s no callback at all and for this specific <em>Insert</em> we may think this will not cause any ARN or any notorious performance bug, you may be correct, whatsoever, other patterns can cause this to create a problem that we can easily correct using a <em>coroutine</em>, for example, in the second image, the generated code has a callback with a new type called — <em>Continuation</em> that pretty much creates an interface representing a continuation after a suspension point that returns a value of type T as an instance with the given context (a dispatcher for the coroutine) and implementation of resumeWith method, and just like that, the <em>Insert</em> will happen outside the UI Thread and we will not allocate any retention frames.</p><p>We are still missing the other execute knows as <em>CoroutinesRooom</em> is the part in charge of switching to another dispatcher, depending on whether the status of the database, remember we can have an open, in the middle of a transaction or a closed database. If the function we are trying to execute is the first two options, Room will do the <em>Insert</em> right away, for the other status, Room will make sure that everything is happening in a secondary thread using a different dispatcher for the transaction, the generated code looks something like this, you can found this code in the <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/ktx/src/main/java/androidx/room/CoroutinesRoom.kt">Open Source code of Room</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_cx-q6jFRCQnG59TpiCZog.png" /></figure><h4>Concurrency</h4><p>We have been talking about the importance of having a secondary thread to execute our task, especially in databases, cause in Android’s SQLite transactions are thread confined if a <em>coroutine</em> is paused there a possibility that the resumed coroutine will not be executed in the same thread.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*JH7RXZ2ztG1z69f6LPVtkw.gif" /></figure><p>Let’s give it a look at this gif, we may have an Update and a Delete from a click and this will be executed in threads, we may want to have all this process in one ☝️ and only thread.<br>But imagine we end up with another click that will <em>Insert</em> other data, the first <em>Update</em> will execute in Thread #1 but if the <em>Insert</em> happens between the <em>Update</em> and <em>Delete</em>, the <em>Insert</em> will use Thread #1 because is not currently in use, so the <em>Delete</em> will not happen in Tread # 1 will happen in Thread #2 and this is also known as a concurrency problem, cause we may not know if the <em>Delete</em> was successful and this can cause a deadlock</p><p>What we need to do to make sure <em>Update</em> and <em>Delete</em> happens in the same thread is running these two methods inside a transaction.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NlPhpsl_J8MGTuFUF3IeNg.png" /></figure><p>A transaction will make sure to execute and only mark as successful as many methods that are depending on each other and they will be executed in a specific dispatcher that will guarantee that all the methods will be brought in the same thread.</p><p>The transaction can also be used as an annotation inside a DAO with abstract functions as mentioned in the <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/common/src/main/java/androidx/room/Transaction.java">documentation</a></p><p>This is all for this part of the post. For the last part, we will discuss Datastore and Shared preferences and I will talk a little about the security behind this!</p><p>If you need help, I’m always happy to help, you can find me here:<br>Medium as <a href="https://medium.com/u/676a20de80ad?source=post_page-----e74944f57a85--------------------------------">Dinorah Tovar</a><br>Twitter as <a href="https://twitter.com/DDinorahtovar">@ddinorahtovar</a><br>StackOverflow as <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">Dinorah Tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40f38992ca2d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/wild-storage-part-2-threading-and-concurrency-40f38992ca2d">Wild Storage | Part 2 — Threading and Concurrency</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Wild Storage | Part 1 — Performance for queries]]></title>
            <link>https://medium.com/knowing-android/wild-storage-part-1-performance-for-queries-661f11be9066?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/661f11be9066</guid>
            <category><![CDATA[sqlite]]></category>
            <category><![CDATA[room]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Fri, 05 Mar 2021 20:57:40 GMT</pubDate>
            <atom:updated>2021-03-22T14:28:05.602Z</atom:updated>
            <content:encoded><![CDATA[<h3>Wild Storage | Part 1 — Performance for queries</h3><p>For Android developers</p><p>Easy data layer for every Application, here is the list of the blogs in this series:</p><ul><li><a href="https://medium.com/knowing-android/wild-storage-part-1-performance-for-queries-661f11be9066"><strong>Part 1 — Performance for queries</strong></a></li><li><a href="https://medium.com/knowing-android/wild-storage-part-2-threading-and-concurrency-40f38992ca2d">Part 2 — Threading and Concurrency</a></li><li><a href="https://medium.com/knowing-android/wild-storage-part-3-datastore-and-sharedpreferences-b32e8686f22b">Part 3 — DataStore and SharedPreferences</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ohrCc7WLsN6VxrKPGOnu_w.jpeg" /><figcaption><a href="https://unsplash.com/photos/-IZ2sgQKIhM">This image is from Unsplash</a></figcaption></figure><p>This is the first part of the series <strong>“Wild Storage for Android developers”</strong> today we are gonna discuss <strong>Performance in the queries </strong>specifically for how to get better instances and responses, and especially how we should handle the database with an easy approach as a performance-wise solution.</p><p>Usually, for mobile, this is a common approach, the user may launch some type of action and we will call an API and this API will return a result that we may be written to a file, shared preferences, or a database, here is the first important part for the data layer of your app, the Network layer, if you are interested in more information about you can check my past serial <a href="https://medium.com/knowing-android/practical-network-for-android-developers-part-1-e74944f57a85">“Practical Network for Android Developers”</a></p><p>And the second part is the Local Data Layer that is handled by internal storage, for this part we are not gonna talk about files, and we will discuss SharedPreferences in the third part of this serial.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DRzGKw3jPIqatOiTJL6BNg.png" /></figure><p>We may have multiple types of cache and some are specifications to Network, but we may have Database caching, some examples are</p><ul><li><strong>CDN</strong> — Global network of edge locations to deliver a cached copy of your APIs content</li><li><strong>DNS</strong> — Every domain request made on the internet essentially queries DNS cache servers in order to resolve the IP address</li><li><strong>Database caching</strong> — Database provides an impactful factor in your app performance.</li></ul><h4><strong>Many Databases</strong></h4><p>There are too many databases some are relational and others non-relational, for many years the fixed solution for Android development was SQLite, SQLite is an incredible tool, scales well, and is wildly used in multiples companies, but for Android, there were some problems, for example, runtime crashes, the boilerplate was enormous, and after some consideration, many alternatives were created for example</p><ul><li>SQL Delight — Typesafe alternative for SQL statement, that understands your existing SQL schema.<br> • <strong>TypeSafe</strong> — Typesafe Kotlin APIs from your SQL statements<br> • <strong>Kotlin first</strong> — even for Multiplatform<br> • <strong>Threading</strong> — support for Coroutines, RxJava, and Android Paging</li><li>Room — Google alternative to SQLite that mostly a wrapper of the original SQLite implementation<br> • <strong>Compile-time</strong> — verification of SQL queries<br> • <strong>Less boilerplate</strong> — and follows the DAO pattern<br> • <strong>Threading</strong> — support for Coroutines, flows, and so many other things</li><li>Realm — Non-Relational and recently handled by MongoDB with an alternative for Sync on their own cloud <br> • <strong>Threading</strong> — Executables for transactions -&gt; executeTransactionAsync<br> • <strong>Listener</strong> — OnChangeListener<br> • <strong>Has a browser</strong> — RealmBrowser<br> • <strong>Easy Encryption</strong> — Using KeyChain can happen really easy</li></ul><h4>Performance</h4><p>But today, we are gonna talk about <strong>Room</strong> as one powerful solution with great performance for Android Development, Room works as an abstraction layer for SQLite, many applications use SQLite as a cache of relevant content from an enterprise RDBMS, there are some reasons we need to talk about why is a powerful solution.</p><ul><li>The addressed file in Insert, Update or Deletegenerates a small edition and only overwrites the parts of the file that change, reducing write time and wear on</li><li>All the Insert, Update or Delete can be created based on concise SQL queries instead of procedural routines, causing the least error-prone details</li><li>The database can be updated and migrated making it super flexible to address changes with the idea of preserving backward compatibility, if you are interested in Migrations and how to handle it you can review my past blog post <a href="https://medium.com/knowing-android/select-insert-indexes-and-foreign-keys-on-room-migrations-2a0dc556efd3"><strong>“</strong>Select, Insert, Indexes and Foreign Keys on Room Migrations<strong>”</strong></a></li><li>We can address performance problems, using Index, Foreign keys, and multiple other tools of integrity, avoiding redesign and revamping efforts</li></ul><p>Let’s talk about how to manage a better query performance using Room, there are some basic rules that we may need to address:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Gl3SKHALXgQ-2hxAp09NbA.png" /></figure><p><strong>Take what you need</strong><br>This is one of the most basics performance-wise actions we can take about extracting data from our database. Let’s imagine that we have a Product table that contains multiple data like name, price, type, promotions, offers, and many other things, It may be really simple for us to take all the information from the table indiscriminately, what so ever, by using, SELECT * you can return useless data that will be only using space in Runtime memory.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*viHoWJWfZWKEjKVzEEepSg.png" /></figure><p>Accessing databases and fetching data from them has an IO cost on the performance of our applications and if we are not careful we may end up with tons of wasteful IO cycles on the DB, also take into consideration that a SELECT * can make your query slower.</p><p><strong>Foreign keys, Primary keys, and Relations<br></strong> Foreign keys are more focused on the integrity of the database, but with Indexes, they boost performance, inside Room adding a Foreign key will not force you to add an Index key, but you should create indexes on all Foreign key fields to improve look-up times.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*17fxGgoPKSGi1F6Nd5Jcww.png" /></figure><p>Relation in Room gives us the opportunity to have “embed” some Entity inside a Data Class, @Relation which works as an annotation, when the info is returned from a query, all of its relations are also fetched automatically.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JhlQJHcydl5ZNQ9_ZZx2Jw.png" /></figure><p><strong>Transaction<br></strong>Transactions are annotations that can be used in functions to execute the non-abstract method of an abstract Dao class, the derived implementation of the method will execute the super method in a database transaction.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q9UY_7nTp8Jaczl8j79Qgg.png" /></figure><p>Transactions help us to handle a block of code that needs to be fully successful to be marked as that, the transaction will be marked as successful unless an exception is thrown in the method body. We will talk a little deeper about how Transactions work under the hood in the second part!</p><p><strong>Coroutines ✨<br></strong>Sounds like a pretty straight forward process to run all our queries in a secondary thread, to not block the main thread and this can be applied to anything inside Room just adding the keyword suspend</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rHx_Wm0jjKXOY48GRG7PmA.png" /></figure><p>From the insert to the transaction, we need to verify how the threading and the concurrency of the queries and functions are handled, but that will be addressed in the second part of this serial!</p><p>If you have a question about handle Foreign keys, migrations, and insertions on Room, you can review my past blog post about this topic<a href="https://medium.com/knowing-android/select-insert-indexes-and-foreign-keys-on-room-migrations-2a0dc556efd3"> <strong>“</strong>Select, Insert, Indexes and Foreign Keys on Room Migrations<strong>”</strong></a></p><p>If you need help, I’m always happy to help, you can find me here:<br>Medium as <a href="https://medium.com/u/676a20de80ad?source=post_page-----e74944f57a85--------------------------------">Dinorah Tovar</a><br>Twitter as <a href="https://twitter.com/DDinorahtovar">@ddinorahtovar</a><br>StackOverflow as <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">Dinorah Tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=661f11be9066" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/wild-storage-part-1-performance-for-queries-661f11be9066">Wild Storage | Part 1 — Performance for queries</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modern Security in Android (part 6)]]></title>
            <link>https://medium.com/knowing-android/modern-security-in-android-part-6-8b17b7a85cce?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/8b17b7a85cce</guid>
            <category><![CDATA[ssl]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[android-development]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Thu, 29 Oct 2020 16:32:47 GMT</pubDate>
            <atom:updated>2020-10-29T16:33:06.280Z</atom:updated>
            <content:encoded><![CDATA[<p>A fast guide to be safe</p><p>This post is related to my lastest talk about <strong>“Modern Security for Android Developers”</strong>.</p><p>Here is the list of the blogs in this series:</p><ul><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-1-6282bcb71e6c">Part 1 — Encryption Vol 1</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-2-743cd7c0941a">Part 2 — Encryption Vol 2</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-3-bea8cc6f984f">Part 3 — Encryption Vol 3</a></li><li><a href="https://medium.com/@dinorahto/modern-security-in-android-part-4-495655c7d4fe">Part 4 — Biometric as Local Auth</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-5-a814a9ab7a1f">Part 5 — Native Code Modules</a></li><li><a href="https://ddinorahtovar.medium.com/modern-security-in-android-part-6-8b17b7a85cce"><strong>Part 6 — SSL, TLS, Secure Data layer</strong></a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U_9XlSbr9euHKiWu95UJTw.jpeg" /><figcaption><strong>Modern Security for Android Developers</strong></figcaption></figure><p>This is the final part of the serial and probably the opening part of my second serial <strong>“Practical Network for Android Developers”</strong> that is gonna be available after this article. <br>In the Mobile world is common knowledge that you may need a couple of network services to make your app work, we usually assume that our services are gonna be okay if our connection is an https, but in reality, this is not completely true, putting some tools can make your request being available and sniffable from a Charles or a Wireshark.</p><p>Transport Layer Security (TLS) is the successor protocol to SSL. TLS is an improved version of SSL. It works in much the same way as the SSL, using encryption to protect the transfer of data and information. The two terms are often used interchangeably in the industry although SSL is still widely used. To keep your app secure you need an SSL certificate, usually, your server needs to have a private key and a public key, your app, and your server will do a handshake, the server using a private key of a certificate that has been signed by <a href="https://en.wikipedia.org/wiki/Public-key_cryptography">public-key cryptography</a>.</p><p>Whatsoever, a handshake does not prove anything, anyone can create one for any website, that’s why you need a Certificate Authority!</p><p>A Certificate Authority is an org or company that validates as an identity, if you work for FakeCompany, you can create one identify you as a website, email, or even person, this digital certificate is a cryptographic key, it gives us a way to authenticate us by using some credentials to validate us, and encrypts our data of communication over insecure networks, this helps us to make sure that nothing can be altered by any sniffer when transferring data, the certificate will create the two keys we need, a private and public, but will add a CSR, which is a file that includes information about the authority. We can have two types of CSR, one is CER and PFX</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*khSjz1w9r4UHGv0_JmqY-Q.png" /></figure><p>When a certificate is signed by a trusted certificate authority, or validated by other means, someone holding that certificate can rely on the public key it contains to establish secure communications with another parties, or validate documents that were signed with this authority.</p><p><strong>CER: </strong>Commonly used by SSL to identify web servers <br><strong>PFX: </strong>This contains cryptographic data of the authority, certificates chains, and private keys.</p><p>Both are cryptographically protected with passwords to keep private keys private and preserve the integrity of the certificates. Just ask your DevOps engineers for the certificate (if you don’t have this kind of team, just ask the person that make the server configuration)</p><p>You can add the certificate to your HttpClient call in a very simple way, let’s do it:</p><ol><li>You can keep your certificate in the Raw folder, if and only if, the password is not stored as plain text in your code.</li><li>Once you do this you can create an instance of the Keystore, remember we want to have this secure, so this certificate should happen in a trusted execution environment, depending on the type of your certificate you need to create a default type instance or a <strong>PKCS12</strong>, <br><strong>PKCS12</strong> defines a file that is storing many cryptography objects as a single file AKA PFX.</li><li>We also need a KeyManagerFactory integration for <strong>X509<br>X.509</strong> is a standard defining the format of public keys it contains a public key and an identity (a hostname, or an organization, or an individual), and is either signed by a Certificate Authority or self-signed.</li><li>Once we have this KeyManagerFactory and our Keystore with the certificate, we can create an instance of SSL with TLS</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4ybOYOLAtrEiTDbd7rBmdQ.png" /></figure><p>Depending on what you are using, you can add this SSL integration to your HttpClient, for this example, is OkHttpClient, adding the SSL socket factory line</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TQIc-2ATBoZzm7v8GGpQBA.png" /></figure><p>Using this, you made sure that your handshake will be secure and inaccessible for third parties and your data transfer will be secure!</p><p>This is all for this serial, thank you so much for keeping an eye on this, the serial was divided into multiple talks but you can found the final one on this website<br><strong>In English at </strong><a href="https://www.droidcon.com/media-detail?video=470490271"><strong>Droidcon EMEA</strong></a><br><strong>In Spanish at </strong><a href="https://www.youtube.com/watch?v=nGf6oOWohzM"><strong>DevFestLatam</strong></a><br><strong>Slides are available at </strong><a href="https://speakerdeck.com/dinorahto/modern-security-for-android-developers-33ab1676-b4bd-4919-9fe9-89bf89c4360d"><strong>my Speaker Deck</strong></a></p><p>If you need help:</p><p>I’m always happy to help, you can find me here:<br>Medium: <a href="https://medium.com/@dinorahto">https://medium.com/@dinorahto</a><br>StackOverflow: <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">https://stackoverflow.com/users/4613259/dinorah-tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8b17b7a85cce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/modern-security-in-android-part-6-8b17b7a85cce">Modern Security in Android (part 6)</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modern Security in Android (part 5)]]></title>
            <link>https://medium.com/knowing-android/modern-security-in-android-part-5-a814a9ab7a1f?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/a814a9ab7a1f</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[encryption]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[ndk]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Sun, 27 Sep 2020 03:56:39 GMT</pubDate>
            <atom:updated>2020-10-29T16:34:28.158Z</atom:updated>
            <content:encoded><![CDATA[<p>A fast guide to be safe</p><p>This post is related to my lastest talk about <strong>“Modern Security for Android Developers”</strong>.</p><p>Here is the list of the blogs in this series:</p><ul><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-1-6282bcb71e6c">Part 1 — Encryption Vol 1</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-2-743cd7c0941a">Part 2 — Encryption Vol 2</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-3-bea8cc6f984f">Part 3 — Encryption Vol 3</a></li><li><a href="https://medium.com/@dinorahto/modern-security-in-android-part-4-495655c7d4fe">Part 4 — Biometric as Local Auth</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-5-a814a9ab7a1f"><strong>Part 5 — Native Code Modules</strong></a></li><li><a href="https://ddinorahtovar.medium.com/modern-security-in-android-part-6-8b17b7a85cce">Part 6 — SSL, TLS, Secure Data layer</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U_9XlSbr9euHKiWu95UJTw.jpeg" /><figcaption><strong>Modern Security for Android Developers</strong></figcaption></figure><p>One of the things I usually say about Android that surprise people is that you can write code in C and C++ and usually they think is cool stuff cause Java and Kotlin code can be decompiled easily, (if a mobile application has obfuscation, probably the task will be a little harder) but C and C++ not, at least not in the same way that java, C code can’t be decompiled but can be <a href="https://en.wikipedia.org/wiki/Disassembler">disassembled</a></p><p>In Android, we have a special thing that manages runtime called ART (Android Runtime) is the predecessor of Dalvik, ART uses an executable format of Dalvik and Dex bytecode, this supports the JNI (Java Native Interface) that is the magic part that let Java code operate and interact with code written in C/C++, let’s remember that Android is a Linux based OS native code is packaged (compiled) into ELF dynamic libraries (*.so), which the Android app loads at runtime via the System.load</p><p>In the next example:</p><pre>init {<br>    try {<br>        System.loadLibrary(&quot;someKeyWeWantSafe&quot;)<br>    } catch (e: UnsatisfiedLinkError) {<br>        Log.e(TAG, &quot;Error loading library &quot; + e.toString());<br>    }<br>}</pre><p>This load happens using System.loadLibrary that is a library written in C/C++ if you navigate inside the code of loadLibrary, you will see a <em>Security Exception</em>, thrown by the security manager to indicate a security violation, whatsoever the violation is not called when dissembling the code.</p><p>You can create a module, and add your private secure key here, inside the C Module, using something like this:</p><pre>#include &lt;jni.h&gt;<br><br><br>JNIEXPORT jstring JNICALL<br>Java_com_secure_project_keymodule_NdkKeys_getKey(JNIEnv *env, jobject instance) {<br>    return (*env)-&gt;NewStringUTF(env, &quot;someCoolKey&quot;);<br>}</pre><p>When reversing an Android application containing native code, we need to understand a couple of data structures related to the JNI bridge between Java and native code. From the reversing perspective, we need to be aware of two key data structures: JavaVM and JNIEnv. Both of them are pointers to pointers to function tables:</p><ul><li>JavaVM provides an interface to invoke functions for creating and destroying a JavaVM. Android allows only one JavaVM per process and is not really relevant for our reversing purposes</li><li>JNIEnv provides access to most of the JNI functions which are accessible at a fixed offset through the JNIEnv pointer. This JNIEnv a pointer is the first parameter passed to every JNI function. Is also used for thread-local storage. For this reason, <strong>you cannot share a JNIEnv between threads</strong>. If a piece of code has no other way to get its JNIEnv, you should share the JavaVM, and use GetEnv it to discover the thread&#39;s JNIEnv.</li></ul><p>It is worth highlighting that it’s never a good idea to leave your API keys lying around your codebase in a way that’s easily decodable, analyzing disassembled C/C++ code is much more difficult than disassembled Java code.</p><p>While it is possible to get any key stored with the NDK, it makes it harder for beginners to get the information they are looking for inside your app, whatsoever, is easier for Internal Leaks to get what they want doing some basic research, is not a secure option for important keys, but it will make the trick for something simpler.</p><p>This is all for this part of the post, If you need help:</p><p>I’m always happy to help, you can find me here:<br>Medium: <a href="https://medium.com/@dinorahto">https://medium.com/@dinorahto</a><br>StackOverflow: <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">https://stackoverflow.com/users/4613259/dinorah-tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><p>I’m really happy to join Droidcon, Android Summit, and DevFest in the next couple of weeks for delivering this talk (especially the last part of this serial), I will show code, and I will try to answer all your questions! <br>Thank you so much for your support!</p><p>DroidconEMEA: Get your <a href="https://twitter.com/hashtag/dcEMEA?src=hashtag_click">#dcEMEA</a> ticket for as much as you want to pay until Oct. 2nd <a href="https://t.co/8mtzLCjrmx?amp=1">https://online.droidcon.com/emea2020</a> (please remember this is going to be at Central Time)</p><p>AndroidSummit: I have a special discount of 35% off <a href="https://t.co/PZyRLHL5U1?amp=1">https://eventbrite.com/e/android-summit-2020-tickets-116528595165?discount=AndroidSummitSpeakerDiscount2020…</a></p><p>DevFest Latam (this is only for Spanish speakers): <a href="https://www.meetup.com/es/gdg-costarica/events/272473635/">https://www.meetup.com/es/gdg-costarica/events/272473635/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a814a9ab7a1f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/modern-security-in-android-part-5-a814a9ab7a1f">Modern Security in Android (part 5)</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modern Security in Android (part 4)]]></title>
            <link>https://medium.com/knowing-android/modern-security-in-android-part-4-495655c7d4fe?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/495655c7d4fe</guid>
            <category><![CDATA[encryption]]></category>
            <category><![CDATA[jetpack-security]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[biometrics]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Mon, 24 Aug 2020 14:03:00 GMT</pubDate>
            <atom:updated>2020-10-29T16:34:17.638Z</atom:updated>
            <content:encoded><![CDATA[<p>A fast guide to be safe</p><p>This post is related to my lastest talk about <strong>“Modern Security for Android Developers”</strong>.</p><p>Here is the list of the blogs in this series:</p><ul><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-1-6282bcb71e6c">Part 1 — Encryption Vol 1</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-2-743cd7c0941a">Part 2 — Encryption Vol 2</a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-3-bea8cc6f984f">Part 3 — Encryption Vol 3</a></li><li><a href="https://medium.com/@dinorahto/modern-security-in-android-part-4-495655c7d4fe"><strong>Part 4 — Biometric as Local Auth</strong></a></li><li><a href="https://medium.com/knowing-android/modern-security-in-android-part-5-a814a9ab7a1f">Part 5 — Native Code Modules</a></li><li><a href="https://ddinorahtovar.medium.com/modern-security-in-android-part-6-8b17b7a85cce">Part 6 — SSL, TLS, Secure Data layer</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U_9XlSbr9euHKiWu95UJTw.jpeg" /><figcaption><strong>Modern Security for Android Developers</strong></figcaption></figure><p>We finish the overview of the Encryption in Android and is time to speak about how biometrics works and how to use it to your advantage.</p><p>In Android 6.0 privacy became one of the priorities for the mobile teams, in this version, Google introduced a <a href="https://source.android.com/compatibility/6.0/android-6.0-cdd.pdf">standardized API</a> for providers, focusing on fingerprints adding a standard for them.<br>In the first volume of this serial, we speak about <a href="https://en.wikipedia.org/wiki/Trusted_execution_environment">Trusted Execution Environments</a> (TEE), these spaces are part of every modern smartphone, this means that the biometric information is encrypted and stored in a separate part of the phone, completely inaccessible to the regular operating system. Making the biometric data unexportable, we can ask the TEE to authenticate the identity of our users, but the biometric data is not accessible, or injectable, making the biometrics a local authentication form.</p><p>Phones have evolved and now Android includes face and fingerprint biometric authentication. Android can be customized to support other forms of biometric authentication, for example, iris. Inside the code, Android has a class to handle the biometric authentication called <a href="https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt.html">BiometricPrompt</a> that includes Fingerprint and Face, Google has to validate that biometric implementation meets a couple of security specifications to join this class, principality it needs to have<strong> a secure architecture</strong> this means, that the biometric data should travel in a secure channel that guarantees that if the Kernel or the platform is compromised the raw biometric data will not be leaked and that data can not be injected in this secure channel, and secondly has to meet a metric called <strong>spoofability </strong>that is measured by three other metrics that are described at the <a href="https://source.android.com/security/biometric/measure">Spoof Acceptance Rate Guide (SAR)</a> to measure how resilient a biometric is against a professional attacker, includes:</p><ul><li><strong>False Accept Rate (FAR)</strong>: Mesures how often a model mistakenly accepts a randomly chosen incorrect input.</li><li><strong>Imposter Accept Rate (IAR)</strong>: Measures the possibility that a biometric model accepts data that mimics the original data. Imagine an Imitator of an actor or a singer with a similar face or a similar voice.</li><li><strong>Spoof Accept Rate (SAR)</strong>: Measures the possibility that a biometric model accepts a previously recorded data.</li></ul><p>After these tests, a biometric implementation can fall out in one of these three categories:</p><ul><li><strong>Strong</strong>: SAR(Spoof Accept Rate): 0–7% FAR (False accept rate): 1/50k FRR (False rejection rate): 10%</li><li><strong>Weak</strong>: SAR: 7–20% FAR: 1/50k FRR: 10%</li><li><strong>Convenience</strong>: SAR: &gt;20% FAR: 1/50k FRR: 10%</li></ul><p>That even contains the fallback (in hours) to the first-ever authentication, the probability of integration with BiometricPrompt class, and the possibility of using KeyStore. There’s a full document about the falling ratio in biometric sensors <a href="https://source.android.com/compatibility/10/android-10-cdd#7_3_10_biometric_sensors">here</a>, if you want me to go deeper on sensors and calibrations systems, please leave a message at the end of this post.</p><h4>BiometricPromp in Action</h4><p>On Android 9 the <a href="https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt.html">BiometricPrompt</a> give the developers a new way to handle FingerPrintManager (this class is already deprecated) without the need to add a new UI, BiometricPrompt permits the users to understand simple UX/UI making it a seamless experience.</p><p>To start using the BiometricPrompt class you can implement this at your gradle file, is a pretty much straight forward implementation:</p><pre>dependencies {<br>    implementation &quot;androidx.biometric:biometric:1.0.1&quot;<br>}</pre><p>To add a biometric prompt builder you only have to create this builder</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7d752dfedc50672fd689522b814b55b5/href">https://medium.com/media/7d752dfedc50672fd689522b814b55b5/href</a></iframe><p>We need to add a new listener to the actions and results of the user, that will give you Success, Failure, and Error if the user fails multiple times to authenticate the Biometric prompt will block the user for a couple of minutes till can try again, this will happen in the Error callback</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bb984c83570a323b23c2f11ea8720cd9/href">https://medium.com/media/bb984c83570a323b23c2f11ea8720cd9/href</a></iframe><p>If you have any problems with the implementation there is a full blog post from Sam Edwards (<a href="https://medium.com/u/55d3c15694bb">Sam Edwards</a>) in his blog: <a href="https://handstandsam.com/2020/05/07/unlocking-biometric-prompt-fingerprint-face-unlock/">https://handstandsam.com/2020/05/07/unlocking-biometric-prompt-fingerprint-face-unlock/</a></p><h4>Adding Biometric prompt to your encryption</h4><p>In the second part of this serial, we talk about the possibility of creating your own KeyPairGenerator, even if you are not using Jetpack Security, you can add the line 7 in the next gist to make sure the users has any type of security:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2711d8f73deed68940953f0c0d3b1268/href">https://medium.com/media/2711d8f73deed68940953f0c0d3b1268/href</a></iframe><p>You can use a secret key that allows you to use the biometric credentials for a specific validity time period, during this time period, your app can perform multiple cryptographic operations without the user needing to re-authenticate, you can do this too when you create your master key for Jetpack Security</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/095ba514c1b93f889ba0ddd7343124df/href">https://medium.com/media/095ba514c1b93f889ba0ddd7343124df/href</a></iframe><p>This is all for this part of the post, If you need help:</p><p>I’m always happy to help, you can find me here:<br>Medium: <a href="https://medium.com/@dinorahto">https://medium.com/@dinorahto</a><br>StackOverflow: <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">https://stackoverflow.com/users/4613259/dinorah-tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=495655c7d4fe" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/modern-security-in-android-part-4-495655c7d4fe">Modern Security in Android (part 4)</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[EditText with every letter as a circle view, for OTP]]></title>
            <link>https://medium.com/knowing-android/edittext-with-every-letter-as-a-circle-view-for-otp-42bea54ab711?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/42bea54ab711</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[pin]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[otp]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Sun, 19 Jan 2020 22:16:29 GMT</pubDate>
            <atom:updated>2020-01-19T22:16:29.704Z</atom:updated>
            <content:encoded><![CDATA[<p>Sometimes we need to play with some UI to make a success OTP</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*ajwxFxRXWcdsRhZ0l8s55Q.jpeg" /></figure><p>Usually, if you work for a company that needs a secondary login, something like a One time Password (OTP) you need to create this kind of UI. Maybe it will not be a circle but it will be an Edit Text with a special UI to match the correct UX.</p><p>Today, we will write this UI, in a simple way:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1786cf1cc07fcc3062afc4a20815b4e9/href">https://medium.com/media/1786cf1cc07fcc3062afc4a20815b4e9/href</a></iframe><p>So the first thing you need to know is that we are extending AppCompatEditText and not only EditText, this is because we are using AndroidX in our project, the second thing you need to know is to set the onDraw and the TextPain we want to use. <br>On the init function, we start our variables with our styles and colors selected by our UI experience, including the size and the stroke width and other multiple qualities of the view.</p><p>To use this view you only need to put this in your XML</p><pre>&lt;<strong>com.yourproject.PinEntryEditText<br>    android:id=&quot;@+id/pin_entry_edit&quot;<br>    android:layout_width=&quot;match_parent&quot;<br>    android:layout_height=&quot;wrap_content&quot;<br>    android:cursorVisible=&quot;true&quot;<br>    android:digits=&quot;1234567890&quot;<br>    android:focusable=&quot;true&quot;<br>    android:inputType=&quot;number|numberPassword&quot;<br>    android:maxLength=&quot;4&quot;<br>    android:textColor=&quot;@color/colorLightGray&quot;<br>    android:textIsSelectable=&quot;false&quot;<br>    android:textSize=&quot;15sp&quot; </strong>/&gt;</pre><p>The max length in your XML property will create the number of spaces you want, so take this in consideration, cause maybe you will end up with an ugly if you are not careful with the padding on the <strong>PinEntryEditText.</strong></p><p>This is a fast tutorial, If you have any question, feel free to reach me out<br>Happy Coding 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=42bea54ab711" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/edittext-with-every-letter-as-a-circle-view-for-otp-42bea54ab711">EditText with every letter as a circle view, for OTP</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Select, Insert, Indexes  and Foreign Keys on Room Migrations]]></title>
            <link>https://medium.com/knowing-android/select-insert-indexes-and-foreign-keys-on-room-migrations-2a0dc556efd3?source=rss----b5e76c10d720---4</link>
            <guid isPermaLink="false">https://medium.com/p/2a0dc556efd3</guid>
            <category><![CDATA[room]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Dinorah Tovar]]></dc:creator>
            <pubDate>Tue, 16 Jul 2019 15:53:46 GMT</pubDate>
            <atom:updated>2019-07-22T14:03:30.042Z</atom:updated>
            <content:encoded><![CDATA[<h3>Select, Insert, Indexes and Foreign Keys on Room Migrations</h3><p>A practical overview of Migration from SQLite to Room</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CSGSSBN1yuv3phnB9DjPdA.png" /></figure><p>In the new project, we are working on, we are making a huge migration from SQLite to Room, We usually always use <a href="https://realm.io/">Realm</a>, but we decide to give it a try to Coroutines and Room, to handle this huge migration from our side, but I found that sometimes you need a little more information about how to handle some parts of the code. So let&#39;s start with migrations:</p><p>Migrations are simpler than in pure SQLite, imagine we have this Data class entity, for our new Room implementation, with a twin but, in SQLite,</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/551bd1538b1f251b41e04e7785dbf07b/href">https://medium.com/media/551bd1538b1f251b41e04e7785dbf07b/href</a></iframe><h3>Migration and RoomDatabase</h3><p>All classes that are annotated with <a href="https://developer.android.com/reference/android/arch/persistence/room/Database.html">Database</a> must extend this class. RoomDatabase provides direct access to the underlying database implementation. Any query apart for the migration should never happen in this layer of the implementation, for that, you can use <a href="https://developer.android.com/reference/android/arch/persistence/room/Database.html">D</a>ao. You need a migration if there was any kind of database you want to conserve for your users, this is handled with Room, Rooms offers a migration wrapper like the next one:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cd83bdea6dc05253b244a820fe100869/href">https://medium.com/media/cd83bdea6dc05253b244a820fe100869/href</a></iframe><h3>Migration: SELECT and INSERT</h3><p>All the entities that your database will need, should be added to the superior part of the abstract class. <br>We can make a step by step guide for the migration: <br>1. You need to <em>create a table with your Room </em>entity with a different name<br>2.<em> Copy all the information</em>, from the SQLite Table to the Room table<br>3. <em>Drop</em> the table in SQLite <br>4. <em>Rename the table</em> to have a final entity with the same name that the table on SQLite</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2a4016498402836b6884e3fa9a202a79/href">https://medium.com/media/2a4016498402836b6884e3fa9a202a79/href</a></iframe><h3>Foreign Keys</h3><p>On the last step, we handle the copy and creation of the table, we use INSERT or REPLACE into the table selected. But this is not good enough yet, for our selected Entity, we need to create the Foreign keys over the UpdatedTableProduct, if we don’t do it, we will face this exception: <em>Foreign key constraint failed</em>, so when we create our table we will add this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cf31a98dcb45c35357574be55b071929/href">https://medium.com/media/cf31a98dcb45c35357574be55b071929/href</a></iframe><h3>Indexes</h3><p>The indexes in your table are important for multi-relational tables, for more efficient queries, remember a key to make this really efficient, is not to have many indexes, and this indexes should not change over time, because this will affect the efficiency, to create indexes for our entity:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/da97e4d66175cd5f24ff1eb2d40b92fe/href">https://medium.com/media/da97e4d66175cd5f24ff1eb2d40b92fe/href</a></iframe><h4>Add a new column</h4><p>Imagine your structure of columns change, maybe you add a new column to tell you if the user has viewed the detail of the product, so you need to alter your table first on SQLite:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f38917ceb2b286544165e1d463144911/href">https://medium.com/media/f38917ceb2b286544165e1d463144911/href</a></iframe><p>And this will be our final result, with all these changes, you will have a final migration that is successful, without exceptions, remember if you have more that one table, you probably are going to write the 4 steps to handle the migration a lot.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f6aae6cb370967e09b6910cddf417544/href">https://medium.com/media/f6aae6cb370967e09b6910cddf417544/href</a></iframe><p>If you need help, I’m always happy to help, you can find me here:<br>Medium: <a href="https://medium.com/@dinorahto">https://medium.com/@dinorahto</a><br>StackOverflow: <a href="https://stackoverflow.com/users/4613259/dinorah-tovar">https://stackoverflow.com/users/4613259/dinorah-tovar</a></p><p>Happy Coding! 👩🏻‍💻</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2a0dc556efd3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/knowing-android/select-insert-indexes-and-foreign-keys-on-room-migrations-2a0dc556efd3">Select, Insert, Indexes  and Foreign Keys on Room Migrations</a> was originally published in <a href="https://medium.com/knowing-android">Knowing Android</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>