<?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[Tech Log - Medium]]></title>
        <description><![CDATA[Droid Log focuses on sharing the knowledge on what the community learns everyday about Android development - Medium]]></description>
        <link>https://medium.com/droid-log?source=rss----ac549fb65f65---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Tech Log - Medium</title>
            <link>https://medium.com/droid-log?source=rss----ac549fb65f65---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 20:39:26 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/droid-log" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[MVVM using MediatorLiveData and Kotlin Flow]]></title>
            <link>https://medium.com/droid-log/mvvm-using-mediatorlivedata-and-kotlin-flow-8b96254cf74f?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/8b96254cf74f</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[mvvm]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[livedata]]></category>
            <category><![CDATA[kotlin-coroutines]]></category>
            <dc:creator><![CDATA[Deepan Elango]]></dc:creator>
            <pubDate>Thu, 30 Jul 2020 09:31:30 GMT</pubDate>
            <atom:updated>2021-10-24T08:13:22.038Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*T820QTdb2pODEMgh-7QqaA.png" /></figure><blockquote>This article would be a short one as I am not going to dive deep into what MVVM or LiveData or Kotlin Flow is. We are going to look at what are the basic things needed in order to achieve MVVM and compare how we used to do it and with the new implementation with Kotlin Flow and MediatorLiveData.</blockquote><h3>Why Kotlin Flow?</h3><p>Right after the stable releases of Kotlin Coroutines that had “<strong>suspending</strong>” functions that can <strong>asynchronously</strong> return a single value, questions were raised on how to return multiple values or a stream of data. Kotlin Flow came into the picture that solved the problem of handling streams just like how RxJava does. Flow is fairly new and consists of a considerable amount of experimental APIs inside which performs really good, so it is not recommended to use those functionalities in your production code just yet but that doesn’t stop us from experimenting with it.</p><p>Let’s say, you hit a network request from an app and it returns data preferably a list and you need to observe them through your MVVM data-flow. It involves creating LiveData everywhere and observing them in your Activity. Suspending functions allowed you to achieve that with ViewModel scopes but that is just not enough. You have to write another function to perform operations on those returned data and state handling is challenging. You can also do the same without Coroutines but you may need to include LiveData in your repositories which are not recommended, your interactors/repositories must never have Android dependencies, this is architecture 101.</p><p>Kotlin Flow comes to the rescue here by allowing you to get those streams of data and convert them to LiveData by using Kotlin “<strong>ktx</strong>” extension function <strong>(asLiveData(viewModelContext))</strong>. Your Repository function should return a <strong>Flow&lt;Data&gt;</strong> and the calling function in your ViewModel should convert them to LiveData for your Activity to start observing them. Now let’s see the difference between them in code.</p><p>I would never recommend this approach as it is a bad design to use LiveData in your repositories.</p><p>So, our next thing to work on would be how to remove the LiveData dependency and replace it with Kotlin Flow. Flow like RxJava has asynchronous capabilities and allows you to run a block of code in the background thread.</p><p><strong>flowOn()</strong> is an extension function that allows you to specify the dispatcher on which the block should run on <strong>Dispatchers.IO</strong> should work in our case. There are a lot of operations available for us to use in the returned flow from the repository, you can <strong>collect</strong> them, specify <strong>onStart</strong> code block (what should be done before the flow block is executed), and convert the returned Flow to LiveData using <strong>asLiveData()</strong> extension function.</p><p>Now let’s look at how the code would look like when we use Flow with LiveData.</p><p>Note that your Activity code is left unchanged but your Repository and ViewModel have adapted to use Kotlin Flow. Flow is fairly simple and easy to adapt, most of all, you can do asynchronous operations without having to define a Coroutine scope every time.</p><h3>MediatorLiveData</h3><p><a href="https://developer.android.com/reference/androidx/lifecycle/MediatorLiveData"><strong>MediatorLiveData</strong></a> are used to merge multiple LiveData and enable a set of Transformation operations to perform on their results. Moreover, it helps you to ensure the state of the LiveData Observer that it observes only LiveData that doesn’t return stale values. Let’s take the ExampleActivity from the above example and look at what went wrong. You can see that <strong>viewModel.getData()</strong> is being called before the <strong>Observer</strong> code, so what happens when you switch them? Your observer starts to observe meaningless LiveData that returns nothing, so you see nothing on your screen. How do we solve this issue of code order conformity?</p><p>Well, MediatorLiveData comes to the rescue. It is a LiveData that observes other LiveData and returns a single stream of LiveData (one-to-many dependency). Now, let’s look at the changes that had to be made from the example to achieve this.</p><p>You can see that <strong>getData()</strong> can now be called after the <strong>Observer</strong> code which is convenient and you don’t have to worry about the order now.</p><h3>Thank You for reading</h3><p>That concludes this article. I believe I’ve covered the basics of MediatorLiveData and I hope that I was of help. Thanks for your time and please upvote if you liked the read, I’d appreciate it. You can find the sample project where I’ve implemented the concepts below.</p><p><a href="https://github.com/tizisdeepan/android-hilt-sample">tizisdeepan/android-hilt-sample</a></p><p><strong>Github Profile:</strong> <a href="https://github.com/tizisdeepan/dots">https://github.com/tizisdeepan</a></p><p><strong>LinkedIn Profile:</strong> <a href="http://www.linkedin.com/in/tizisdeepan">www.linkedin.com/in/tizisdeepan</a></p><p><strong>Happy Coding!</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8b96254cf74f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/mvvm-using-mediatorlivedata-and-kotlin-flow-8b96254cf74f">MVVM using MediatorLiveData and Kotlin Flow</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dagger-Hilt Dependency Injection on Android]]></title>
            <link>https://medium.com/droid-log/dagger-hilt-dependency-injection-on-android-57ee4ca24106?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/57ee4ca24106</guid>
            <category><![CDATA[dagger-2]]></category>
            <category><![CDATA[dependency-injection]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[dagger-hilt]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Deepan Elango]]></dc:creator>
            <pubDate>Tue, 28 Jul 2020 17:33:47 GMT</pubDate>
            <atom:updated>2020-07-29T11:47:02.954Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9YvVuOFK165EEN7ebv1LEQ.png" /></figure><h3>What is Dependency Injection?</h3><p>Before heading on to the what let’s stick to the why. I would like to see Dependency Injection as vaccination for your project and when do you get it done? Right when the project is a baby. I know that it involves a huge learning curve and you must be wondering why should you do it with any project, well you are not forced to adapt to DI, you start a project thinking it is small and it solves a specific set of problems without the need for thinking ahead that there might be more new problems in the future that requires more modules to be built on your app. Complexity increases over time even if you follow a really good architecture with clean code, so DI is basically to avoid that.</p><p><strong>Dependency Injection (DI) </strong>is a system that ensures the simplicity of your app’s architecture and lets you forget about the worries about the scalability of your app. S.O.L.I.D principles help you make the code simple, dependency injection makes the architecture simple. It prevents your code from getting more complex in the future and easily manageable. <strong>Dagger2</strong> and <strong>Koin</strong> are one of the most used dependency injection frameworks, <strong>Hilt</strong> is fairly new to the game but my hopes are up because even at its early stages, it has promised a lot of good things.</p><h3><strong>Why Hilt?</strong></h3><h4>Boilerplates</h4><p>One thing that fears most of the developers to adapt to dependency injection, (even me back in the days), is that DI by itself is complex, hard to configure, and requires a lot of things to look at and put together for it to work. Google always ensures eliminating boilerplates in their frameworks right at the start or in the middle for some frameworks, just like how they managed to bring Kotlin as the go-to language for Android instead of Java. Dagger2 has a lot of boilerplates, right from modules, providers to injections, you have to write them all with respect to how you want them to work. Hilt eliminates all the boilerplates and does all the work for you with the help of a set of pre-defined components and scopes. No more creating components by yourself and creating a component factory.</p><h4>Complexity</h4><p>Dagger2 is a complex library that does DI by annotations. So, you have components, modules, scopes, and ways to inject them in different parts of your application which can be done in multiple ways. The problem with Dagger2 is, there is no one way in achieving something, so, when a new developer looks at your code, a base knowledge on the components and how you did it is required for them to understand the code better. Hilt, on the other hand, has wrapped all those different possibilities and gives you a clear cut way of implementing DI in your application. One look at it, and you can understand what’s happening under the hood.</p><h4>ViewModel Injections</h4><p>Injecting ViewModels in your Activities was the hardest part with DI using Dagger2. You had to create a ViewModel factory that took in the type and with map bindings and then injecting it via the component in your Activity — I even get tired when explaining it to people. Well, all that has vanished with Hilt. All that it takes is a @ViewModelInject for your constructor injections and a “by viewModels() ktx” extension in your activity. Yup, it’s that good.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2Fl41YkFIiBxQdRlMnC%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2Fl41YkFIiBxQdRlMnC%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2Fl41YkFIiBxQdRlMnC%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="237" frameborder="0" scrolling="no"><a href="https://medium.com/media/742f7ddca2a83e1160ca9b97699daf48/href">https://medium.com/media/742f7ddca2a83e1160ca9b97699daf48/href</a></iframe><h3>Hilt Application</h3><p>With Dagger2, it is mandatory that you create your own components and map it to the required modules before trying to inject the module functionalities, so you go ahead and create an application-level component mapped to the modules and you write a Factory provider that helps to inject classes across the specified scope.</p><p>You need to create components for each scope types and you may also need to do custom scopes based on your requirements. We will deep dive into what components and modules are, later on when we discuss them with respect to Hilt but here’s the difference in creating an application-level component between Dagger2 and Hilt. With Dagger2, you need an AppComponent that has DaggerApplication access and you need to extend your Application class with <strong>DaggerApplication</strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a786b96701e45601a241b4142b8c83fc/href">https://medium.com/media/a786b96701e45601a241b4142b8c83fc/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0b451ee11bbcec82d5521f39c0b524ad/href">https://medium.com/media/0b451ee11bbcec82d5521f39c0b524ad/href</a></iframe><p>With <strong>Hilt</strong>, all you need to do is annotate your Application class with <strong>@HiltAndroidApp</strong> annotation and that’s it, done, Hilt takes care of all the rest of the boilerplates by itself. Isn’t this fun? There’s more coming our way, stay tuned.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2cff04e1f3a0515ab5c1af587584f404/href">https://medium.com/media/2cff04e1f3a0515ab5c1af587584f404/href</a></iframe><h3><strong>Hilt Components</strong></h3><p><strong>Components</strong> are basically different parts of your application at the top-level which may have sub-components under them or modules that are installed under them. Components help the DI framework to generate the contract for you.</p><p>Dagger2 requires you to instantiate components directly which is complex to do and repetitive. Rest assured, Hilt packs in with a set of <strong>pre-defined components</strong> that comes to the rescue. We don’t anymore have to worry about all the components that we had to create and keep track of, you are asked to choose between the components that are already there. This is a good approach to programming as it standardizes your way of approach to DI overall and it is easy to adapt between different developers and easy to onboard basically anybody into your app.</p><p>Each component available in Hilt comes with a Scope by itself which derives from its name and easy to understand. For example, <strong>ActivityComponent</strong> is <strong>@ActivityScoped</strong>. Here are all the pre-defined components that are readily available for you to use from Hilt. The hierarchies and scopes are accessible just like what is found in the graph below, a provided service declared in the ApplicationComponent is accessible right down till ViewComponents. This is fairly simple rather than defining your own components which mostly becomes a mess at some point.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/644/1*ZOz3xw-cm7IDjqeCrFLj-A.png" /><figcaption>Hilt Components</figcaption></figure><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F1nCfZ1mDXGcyk%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F1nCfZ1mDXGcyk%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2F1nCfZ1mDXGcyk%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="244" frameborder="0" scrolling="no"><a href="https://medium.com/media/1731ccca5fd201dda867be8eec33c11c/href">https://medium.com/media/1731ccca5fd201dda867be8eec33c11c/href</a></iframe><h3>Hilt Modules</h3><p>A Module is installed in a Hilt Component by using <strong>@Module</strong> and <strong>@InstallIn(ApplicationComponent::class)</strong> and that’s it, you don’t need to mention the module name in any component class.</p><p>You can do any number of providers in a Module that takes care of providing the service when required if the scope is satisfied. Which means, you can’t inject a provided service by a module installed in ActivityComponent in a code block that has an application-level scope.</p><p><strong>@Provides</strong> helps you to write the provider for a particular service. <strong>@Singleton</strong> is to specify that the provider is always accessible across the mentioned scope (component) since all components are by default mapped to a scope.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c0bb788ff65c4983dc09fbd5e428073f/href">https://medium.com/media/c0bb788ff65c4983dc09fbd5e428073f/href</a></iframe><h3>Hilt Entry Points</h3><p>Entry Points allow Hilt to know where exactly to inject what. You can use <strong>@AndroidEntryPoint</strong> on <strong>Activities, Fragments, Views, Services, and BroadcastReceivers</strong>. You can use this annotation to start using the injected values right away. You get access to modules depending on the scope of your entry points. For example, an entry point on an activity will allow you to use all the provided services specified on the activity as well as application modules.</p><p><strong>@Inject</strong> helps you to get the values from the providers, yes, it&#39;s that easy, you will never have the need to instantiate/create your components at any point during the development when Hilt is being used. <strong>@Inject</strong> can also be used for construction injections.</p><p><strong>@ViewModelInject</strong> is used to inject repository/use-case on your constructor in a ViewModel</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/778c910805f9ae9d8ea93915c937a9ae/href">https://medium.com/media/778c910805f9ae9d8ea93915c937a9ae/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/611b1a300abc14f58453485218a32864/href">https://medium.com/media/611b1a300abc14f58453485218a32864/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FMBVemoHuyw9Ik%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FMBVemoHuyw9Ik%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FMBVemoHuyw9Ik%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="207" frameborder="0" scrolling="no"><a href="https://medium.com/media/52a786c19510959cd7e65caf61489171/href">https://medium.com/media/52a786c19510959cd7e65caf61489171/href</a></iframe><h3>Testing in Hilt</h3><p>Testing is also easy with Hilt as it provides separate bindings for your tests by using specific Hilt test tests and rules. You get to use annotations like <strong>@HiltAndroidTest, @Rule — HiltAndroidRule, </strong>and<strong> HiltTestApplication</strong> for testing your application class.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8e43befbbc345a36c6c4bde6448b3833/href">https://medium.com/media/8e43befbbc345a36c6c4bde6448b3833/href</a></iframe><h3>Thank You for reading</h3><p>That concludes this article. I believe I’ve covered the basics of Hilt and I hope that I was of help. Thanks for your time and please upvote if you liked the read, I’d appreciate it. You can find the sample project where I’ve implemented Hilt below.</p><p><a href="https://github.com/tizisdeepan/android-hilt-sample">tizisdeepan/android-hilt-sample</a></p><p><strong>Github Profile:</strong> <a href="https://github.com/tizisdeepan/dots">https://github.com/tizisdeepan</a></p><p><strong>LinkedIn Profile:</strong> <a href="http://www.linkedin.com/in/tizisdeepan">www.linkedin.com/in/tizisdeepan</a></p><p><strong>Happy Coding!</strong></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FQT9SVRVexMgOk%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FQT9SVRVexMgOk%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FQT9SVRVexMgOk%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="219" frameborder="0" scrolling="no"><a href="https://medium.com/media/6dc7366bc0fdbb2c796b7aa92f42e1cf/href">https://medium.com/media/6dc7366bc0fdbb2c796b7aa92f42e1cf/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=57ee4ca24106" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/dagger-hilt-dependency-injection-on-android-57ee4ca24106">Dagger-Hilt Dependency Injection on Android</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kotlin Type inference — Quick Look]]></title>
            <link>https://medium.com/droid-log/kotlin-type-inference-quick-look-f966a3f41770?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/f966a3f41770</guid>
            <category><![CDATA[kotlin-beginners]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[type-inference]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Tue, 30 Jun 2020 05:05:08 GMT</pubDate>
            <atom:updated>2020-06-29T11:09:04.144Z</atom:updated>
            <content:encoded><![CDATA[<h3>Kotlin Type Inference — Quick Look</h3><p>In Kotlin most of the time, you won’t need to specify the type of the objects you are working with, as long as the compiler can infer it.</p><p>So, we just need to write <strong>var or val</strong> depending on the type of variable we want to generate, and the type can normally be inferred. We can always specify a type explicitly as well. Say, for instance, you define val REQUEST_CODE = 100. Behind the scenes, REQUEST_CODE initializes with the Int datatype since the value of REQUEST_CODE is of type Int, the compiler infers that REQUEST_CODE is also a Int. Note that Kotlin is a <em>statically-typed</em> language. This means that the type is resolved at compile time and never changes.</p><p>Although Kotlin uses <strong>Type Inference</strong> ( <em>automatically identify something</em> ), which means we also have the option to specify the data type when we initialize the variable like below:</p><p>val REQUEST_CODE: Int = 100</p><p>Both act the same while converting it to byte code.</p><blockquote><strong><em>What the heck, How do Kotlin determine the data type of numbers if we use implicit declaration?</em></strong></blockquote><p>Good question, Kotlin provides a set of built-in types that represent numbers. For integer numbers, there are four types with different sizes and, hence, value ranges.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/629/0*L8ak1LLnBElqMV9T.png" /></figure><p>All variables initialized with integer values not exceeding the maximum value of Int have the inferred type Int. If the initial value exceeds this value, then the type is Long. To specify the Long value explicitly, append the suffix L to the value. <strong>So, whenever you strictly want to save memory it is advisable to use explicit type declaration for data types like </strong><strong>Byte &amp; </strong><strong>Short.</strong></p><pre>val one = 1 // Int<br>val threeBillion = 3000000000 // Long<br>val oneLong = 1L // Long<br>val oneByte: Byte = 1</pre><h4>Reference</h4><ul><li><a href="https://kotlinlang.org/docs/reference/basic-types.html">https://kotlinlang.org/docs/reference/basic-types.html</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f966a3f41770" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/kotlin-type-inference-quick-look-f966a3f41770">Kotlin Type inference — Quick Look</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WebView darkening — Force Dark Mode for Web Contents]]></title>
            <link>https://medium.com/droid-log/webview-darkening-force-dark-mode-for-web-contents-d76d86ff9efa?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/d76d86ff9efa</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[dark-mode]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[webview]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Wed, 24 Jun 2020 06:27:38 GMT</pubDate>
            <atom:updated>2020-06-24T07:09:07.095Z</atom:updated>
            <content:encoded><![CDATA[<h3>WebView darkening — Force Dark Mode for Web Contents</h3><p>Now you can automatically render all web contents using a dark theme in Android WebView. If you see <a href="https://developer.android.com/jetpack/androidx/releases/webkit#1.3.0-beta01">androidx.webkit:webkit:1.3.0-beta01</a> changelogs you could see ForceDark API added to control if WebView should be rendered in dark mode. You can use <a href="https://developer.android.com/reference/kotlin/androidx/webkit/WebSettingsCompat#setforcedarkstrategy">ForceDarkStrategy</a> API to control WebView darkening (CSS/web content darkening versus auto-darkening).</p><p>Prior try to access this feature, ensure that it is supported by the Webview is being used in. For this, the <a href="https://developer.android.com/reference/androidx/webkit/WebViewFeature">WebViewFeature</a> class have an <a href="https://developer.android.com/reference/kotlin/androidx/webkit/WebViewFeature#isfeaturesupported">isFeatureSupported()</a> function, which can be used to check if a given feature is supported. So before we go ahead and set the support for dark mode check if it is supported:</p><pre>if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { ... }</pre><p>There are 3 different constants available in <a href="https://developer.android.com/reference/androidx/webkit/WebSettingsCompat">WebSettingsCompat</a> to configure</p><ul><li><strong>FORCE_DARK_OFF</strong> — Disable the force dark mode for the webview, meaning the content of the webview will be rendered as-is</li><li><strong>FORCE_DARK_ON</strong> — Enable the force dark mode for the webview, meaning the content of the webview will always be rendered with a dark theme</li><li><strong>FORCE_DARK_AUTO</strong> — Enable the force dark mode for the webview depending on the state of the parent view, meaning that the system dark mode setting will be followed when rendering the content of the webview.</li></ul><p>Apply it accordingly using <a href="https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setForceDark(android.webkit.WebSettings,%20int)">setForceDark</a> function-</p><pre>WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)</pre><blockquote><strong>Note:</strong> The setForceDark fun requires Android System WebView V<strong>ersion 76 or/+ </strong>to be installed on the device. There is no other straight forward way to enable dark mode in WebView if it doesn’t support. This is a major problem for the apps that uses a dark theme. OTOH, If you want to support WebView that doesn’t support dark theme google’s recommendation is to modify your WebView content with custom styling for Dark Theme. The prefers-color-scheme: dark @media query provides developers with a way to define custom styling for a Dark Theme similar to the way Android allows you to provide night-conditional resources.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d76d86ff9efa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/webview-darkening-force-dark-mode-for-web-contents-d76d86ff9efa">WebView darkening — Force Dark Mode for Web Contents</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Good Read’s — Variable Name & Code Style Guidelines]]></title>
            <link>https://medium.com/droid-log/good-reads-variable-name-code-style-guidelines-6fc98b5489a0?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/6fc98b5489a0</guid>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[code-readability]]></category>
            <category><![CDATA[naming-conventions]]></category>
            <category><![CDATA[code-style-guide]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Thu, 11 Jun 2020 05:33:21 GMT</pubDate>
            <atom:updated>2020-05-05T13:22:22.785Z</atom:updated>
            <content:encoded><![CDATA[<h3>Good Read’s — Variable Name &amp; Code Style Guidelines</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*8HCQ8608GsglSy6_HFMdmg.jpeg" /></figure><blockquote>“If you struggle to read the code, how the hell are you meant to fix it !!” ????</blockquote><p>Having a well named variable is definitely one of the most important thing for code readability. A good variable name should also provide meaning. That way it’s easy for others to read your code or even yourself in the future. You should be descriptive with your naming. Say, for instance, if you give a meaningful name to a method, you could probably save at least a line in the comment section in most scenarios.</p><p>Avoid these bad variable names:</p><ul><li>❌ Single-letter names</li><li>❌ Acronyms</li><li>❌ Abbreviations</li><li>❌ Meaningless names</li></ul><p>Good Read’s ( Variable Name &amp; Code Style Guidelines ) -</p><p>“Tips on naming boolean variables — Cleaner Code” -<a href="https://dev.to/michi/tips-on-naming-boolean-variables-cleaner-code-35ig">https://dev.to/michi/tips-on-naming-boolean-variables-cleaner-code-35ig</a></p><p>“AOSP Java Code Style for Contributors” — <a href="https://source.android.com/setup/contribute/code-style">https://source.android.com/setup/contribute/code-style</a></p><p>“Google Java Style Guide” — <a href="https://google.github.io/styleguide/javaguide.html">https://google.github.io/styleguide/javaguide.html</a></p><p>“Android Project and Code Guidelines” — <a href="https://github.com/ribot/android-guidelines/blob/master/project_and_code_guidelines.md">https://github.com/ribot/android-guidelines/blob/master/project_and_code_guidelines.md</a></p><p>“XML naming convention” — <a href="https://jeroenmols.com/blog/2016/03/07/resourcenaming">https://jeroenmols.com/blog/2016/03/07/resourcenaming</a></p><p>“5 Tips to Increase your Code Quality” — <a href="https://simpleprogrammer.com/5-tips-code-quality/">https://simpleprogrammer.com/5-tips-code-quality</a></p><p>“Code readability metrics” — <a href="https://dev.to/stereobooster/code-readbility-metrics-5393">https://dev.to/stereobooster/code-readbility-metrics-5393</a></p><p>“Why Code Readability is important” — <a href="https://crmbusiness.wordpress.com/2014/12/08/why-code-readability-is-important/">https://crmbusiness.wordpress.com/2014/12/08/why-code-readability-is-important/</a></p><p><strong>#DEVcommunity</strong> <strong>#AndroidDev</strong> <strong>#JavaDev</strong> <strong>#KotlinDev</strong> <strong>#NamingConventions</strong> <strong>#CodingStyle</strong> <strong>#ReadabilityMatters #TheBuddySystem</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6fc98b5489a0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/good-reads-variable-name-code-style-guidelines-6fc98b5489a0">Good Read’s — Variable Name &amp; Code Style Guidelines</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android: MVVM with Clean Architecture Prototype Written In Kotlin — GithubTrendingRepos]]></title>
            <link>https://medium.com/droid-log/android-mvvm-with-clean-architecture-prototype-written-in-kotlin-githubtrendingrepos-4eeab463dfca?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/4eeab463dfca</guid>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[clean-architecture]]></category>
            <category><![CDATA[kotlin-coroutines]]></category>
            <category><![CDATA[mvvm]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Thu, 11 Jun 2020 05:32:01 GMT</pubDate>
            <atom:updated>2020-04-11T13:48:42.141Z</atom:updated>
            <content:encoded><![CDATA[<h3>Android: MVVM with Clean Architecture Prototype Written In Kotlin</h3><p>GithubTrendingRepos — An #Android app consuming @github Trending Rest API’s to display the current trending <a href="https://www.facebook.com/hashtag/github?source=feed_text&amp;epa=HASHTAG">#Github</a> repositories. It has been built using Kotlin with clean architecture principles, Repository Pattern and MVVM pattern as well as Architecture Components.</p><p>Github Repo Link -<a href="https://github.com/anoopmaddasseri/GithubTrendingRepos?fbclid=IwAR21fPV9Fi5jzHULd8et5XfAaM_6-BqPI8QRhgwnKETH2o7z_PJFnn8TRrQ">https://github.com/anoopmaddasseri/GithubTrendingRepos</a></p><p>App Features -</p><p>✅ Trending Repository Listing<br>✅ Repository sorting by stars and name<br>✅ Take the user to the corresponding repository on long press<br>✅ Pull to force refresh repository<br>✅ Offline Storage ( Scheduled repo remote controller syncing, App will sync with backend server in every 2hrs )</p><p>Trending Libraries Demonstration -<br><a href="https://www.facebook.com/hashtag/materialdesign?source=feed_text&amp;epa=HASHTAG">#MaterialDesign</a> <a href="https://www.facebook.com/hashtag/dagger2?source=feed_text&amp;epa=HASHTAG">#Dagger2</a> <a href="https://www.facebook.com/hashtag/retrofit?source=feed_text&amp;epa=HASHTAG">#Retrofit</a> <a href="https://www.facebook.com/hashtag/jetpack?source=feed_text&amp;epa=HASHTAG">#Jetpack</a> <a href="https://www.facebook.com/hashtag/viewmodel?source=feed_text&amp;epa=HASHTAG">#Viewmodel</a> <a href="https://www.facebook.com/hashtag/databinding?source=feed_text&amp;epa=HASHTAG">#DataBinding</a> <a href="https://www.facebook.com/hashtag/roompersistence?source=feed_text&amp;epa=HASHTAG">#RoomPersistence</a> <a href="https://www.facebook.com/hashtag/moshi?source=feed_text&amp;epa=HASHTAG">#Moshi</a> <a href="https://www.facebook.com/hashtag/kotlinx_coroutines?source=feed_text&amp;epa=HASHTAG">#kotlinx_coroutines</a> <a href="https://www.facebook.com/hashtag/leakcanary?source=feed_text&amp;epa=HASHTAG">#LeakCanary</a></p><p>Unit &amp; Instrumentation tests with -<br><a href="https://www.facebook.com/hashtag/androidxjunit?source=feed_text&amp;epa=HASHTAG">#AndroidXJUnit</a> <a href="https://www.facebook.com/hashtag/junit4?source=feed_text&amp;epa=HASHTAG">#JUnit4</a> <a href="https://www.facebook.com/hashtag/mockito?source=feed_text&amp;epa=HASHTAG">#Mockito</a> <a href="https://www.facebook.com/hashtag/mockwebserver?source=feed_text&amp;epa=HASHTAG">#MockWebServer</a> <a href="https://www.facebook.com/hashtag/espresso?source=feed_text&amp;epa=HASHTAG">#Espresso</a> <a href="https://www.facebook.com/hashtag/robolectric?source=feed_text&amp;epa=HASHTAG">#Robolectric</a> <a href="https://www.facebook.com/hashtag/truth?source=feed_text&amp;epa=HASHTAG">#Truth</a></p><p>Please feel free to hit the 🌟 button and support on Github if you find it helpful.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4eeab463dfca" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/android-mvvm-with-clean-architecture-prototype-written-in-kotlin-githubtrendingrepos-4eeab463dfca">Android: MVVM with Clean Architecture Prototype Written In Kotlin — GithubTrendingRepos</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gauging React Native and Ionic 2 — Which Is Really Better..?]]></title>
            <link>https://medium.com/droid-log/gauging-react-native-and-ionic-2-which-is-really-better-38b165b6e5e8?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/38b165b6e5e8</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[ionic2]]></category>
            <category><![CDATA[ionic-framework]]></category>
            <category><![CDATA[react-native]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Tue, 09 Jun 2020 13:45:55 GMT</pubDate>
            <atom:updated>2017-10-24T10:21:12.299Z</atom:updated>
            <content:encoded><![CDATA[<p>Choosing the best tool depends on the developer’s preferences and needs. Here we look at the pros and cons of React Native and Ionic 2 for developing apps.</p><p><em>“The bitterness of poor quality remains long after the sweetness of low price is forgotten” — </em><strong><em>Benjamin Franklin</em></strong></p><p>Providing a product at the lowest price point with outstanding quality of the product, sounds like a sure way to attract customers and gain an edge on the competition — but it’s not always that easy. It is normal for clients to expect quality and at the same time try to save money and time. After all, the clients are paying the company so they want to make sure their finances are spent efficiently.</p><p>It is well-known that development costs are quite high even to develop on one platform, either Android or iOS. Development for two platforms makes the costs grow twice as much (or even more).</p><p>Price has always been, and will always be, a significant indicator of quality, so making a high-quality product affordable and valuable is a fine line to walk and that’s what hybrid platforms do for you.</p><p>Thanks to a collection of new technologies that have emerged over the past two years. With these technologies, you can design, build, and deploy robust mobile apps faster than you could with native technologies, all while incurring little to no app performance penalties.</p><p>Using new technology is always a bit risky as you cannot be 100% sure of it. In this article, let’s compare two frameworks that is best in this business as of now, React Native and Ionic 2, and point out the main pros and cons of each.</p><p><strong>Ionic 2</strong></p><p>Ionic’s ultimate goal is to make it easier to develop native mobile apps also known as Hybrid apps and it proved that it’s a great solution in this business. Ionic apps are essentially websites embedded in a mobile app through what we call a webview. They are developed using HTML5, CSS, and Javascript and execute the same code regardless of the platform in which they run. They can, with tools like PhoneGap and Cordova, use the native features of a device, like GPS or camera.</p><p>A step up, Ionic is a breeze to learn &amp; work with, and cross-compiles to iOS and Android (since it’s just Webview) using per-device differentiator classes to theme accordingly — <em>“write once, run anywhere“</em>.</p><p>Mixing Ionic code with native mobile app code in <a href="https://cordova.apache.org/">PhoneGap </a>(now called Apache Cordova) allows for higher performance of the resulting product: utilizing <a href="https://angular.io/">AngularJS </a>(rather than jQuery) allows Ionic to rely on native hardware acceleration (rather than extensive DOM manipulation). Ionic leverages CSS transitions and transforms for animation as a way to leverage the <a href="https://en.wikipedia.org/wiki/Graphics_processing_unit">GPU</a> and maximize available processor time.</p><p><strong>React Native</strong></p><p>React Native is a platform for building mobile apps using the highly popular and quickly growing React view library. The resulting apps run on both iOS and Android. However, unlike other cross-platform SDK’s like PhoneGap, Ionic, etc which basically run JavaScript powered apps in a web browser, React Native compiles to native code for the respective OS, Android or iOS. That means there is no performance compromise and the apps built with React Native run just as smoothly as apps built using the actual native tools like Xcode.</p><p>With React Native, you don’t build a “mobile web app”, an “HTML5 app”, or a “hybrid app”. You build a real mobile app that’s indistinguishable from an app built using Objective-C or Java. React Native uses the same fundamental UI building blocks as regular iOS and Android apps. You just put those building blocks together using JavaScript and React.</p><p>React Native doesn’t have the luxury <em>“ write once, run anywhere. “</em> — their motto is <em>“ learn once, write anywhere “</em> — meaning you’re using the same framework, and maybe even shared components, but maintaining separate code for your iOS &amp; Android apps. This means more work, on top of the steeper learning curve. That’s the time/effort cost, now let’s consider the quality cost.</p><p><strong>Now, Let’s Compare</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/12c3798827dc540502a8fd25cd13f547/href">https://medium.com/media/12c3798827dc540502a8fd25cd13f547/href</a></iframe><p><strong>Showcase — Who’s using?</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/662/1*7z59ciyyeGqTP-TDzQDkLg.png" /></figure><p><strong>OK. But Which is Better?</strong></p><p>They both do different things, and both do it well. Choosing between the two depends more on your project requirements. React Native is a great option for creating performant iOS and Android apps that feel at home on their respective platforms, all while building on any previous web development experience. If your requirement is decent performance apps, with support for <a href="https://developers.google.com/web/progressive-web-apps/">Progressive Web Apps</a> and Native Browser Apps, then go for ionic 2 with no hesitation in mind.</p><p>Nevertheless, If you value native rendering more than the rest and if you need apps to be extremely fast and responsive, then you can opt for React Native.</p><h3>References</h3><ul><li><a href="https://facebook.github.io/react-native/">React Native — Learn once, write anywhere: Build Mobile app with React</a></li><li><a href="https://ionicframework.com/">Ionic framework</a></li><li><a href="http://ionicframework.com/present-ionic/slides/#/">Building Hybrid Apps with AngularJS and Ionic</a></li></ul><h4><em>Go forth and build something awesome!</em></h4><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=38b165b6e5e8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/gauging-react-native-and-ionic-2-which-is-really-better-38b165b6e5e8">Gauging React Native and Ionic 2 — Which Is Really Better..?</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Perform asynchronous I/O operations using CoroutineScope]]></title>
            <link>https://medium.com/droid-log/perform-asynchronous-i-o-operations-using-coroutinescope-d6ca6309946c?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/d6ca6309946c</guid>
            <category><![CDATA[kotlin-coroutines]]></category>
            <category><![CDATA[multithread]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[viewmodel]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Tue, 09 Jun 2020 13:38:58 GMT</pubDate>
            <atom:updated>2020-04-13T08:46:51.352Z</atom:updated>
            <content:encoded><![CDATA[<h3>Perform asynchronous I/O operations using CoroutineScope/LifecycleScope</h3><p>Perform asynchronous I/O operations using CoroutineScope ( <a href="https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/">https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope</a> ) that define a scope for new coroutines.</p><p>In Android, CoroutineScope ships with lifecycle aware architecture components. The KTX extension is ViewModelScope, we can use <em>androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0-beta01</em> or higher.</p><blockquote>A ViewModelScope is defined for each ViewModel in your app. Any coroutine launched in this scope is automatically canceled if the ViewModel is cleared. CoroutineScope tied with the ViewModel.</blockquote><p>The viewModelScope code is <a href="https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/lifecycle/lifecycle-viewmodel-ktx/src/main/java/androidx/lifecycle/ViewModel.kt">publicly available in AOSP</a> implemented as follows:</p><p><a href="https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/lifecycle/lifecycle-viewmodel-ktx/src/main/java/androidx/lifecycle/ViewModel.kt">https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/lifecycle/lifecycle-viewmodel-ktx/src/main/java/androidx/lifecycle/ViewModel.kt</a></p><p>Usage of ViewModelScope — <a href="https://github.com/anoopmaddasseri/GithubTrendingRepos/blob/3940457412f6dc7f06e86c0a7db2c76ff5c2996f/app/src/main/kotlin/com/mvvmclean/trendingrepos/features/trendingrepo/TrendingRepositoryViewModel.kt#L33">https://github.com/anoopmaddasseri/GithubTrendingRepos/blob/3940457412f6dc7f06e86c0a7db2c76ff5c2996f/app/src/main/kotlin/com/mvvmclean/trendingrepos/features/trendingrepo/TrendingRepositoryViewModel.kt#L33</a></p><p>We could also use Coroutines with LifecycleScope as a life cycle aware worker.</p><p>A LifecycleScope is defined for each <a href="https://developer.android.com/topic/libraries/architecture/lifecycle">Lifecycle</a> object. Any coroutine launched in this scope is canceled when the Lifecycle is destroyed. You can access the CoroutineScope of the Lifecycle either via lifecycle.coroutineScope or lifecycleOwner.lifecycleScope properties.</p><p>Usage of LifecycleScope—</p><pre>activity.lifecycleScope.launch {<br> // scope tied to Activity Lifecycle<br>}</pre><pre>fragment.lifecycleScope.launch {<br> // scope tied to Fragment Lifecycle <br>}</pre><pre>fragment.viewLifecycleOwner.launch{<br> // scope tied to Fragment View<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d6ca6309946c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/perform-asynchronous-i-o-operations-using-coroutinescope-d6ca6309946c">Perform asynchronous I/O operations using CoroutineScope</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android 11 — Developer focused updates [DP3]]]></title>
            <link>https://medium.com/droid-log/android-11-developer-focused-updates-dp3-22f1199e982a?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/22f1199e982a</guid>
            <category><![CDATA[android-11-feature]]></category>
            <category><![CDATA[android-developer-preview]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-11]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Tue, 09 Jun 2020 13:28:48 GMT</pubDate>
            <atom:updated>2020-05-09T11:32:02.972Z</atom:updated>
            <content:encoded><![CDATA[<h3>Android 11 — Developer focused updates [DP3]</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/760/1*Wm87p29dIjG5LKZqrbDTww.jpeg" /></figure><p>This article will take you through the new Android 11 developer-focused features and APIs updates -</p><ul><li><strong>App exit reasons updates:</strong> Google updated the exit reasons API including the <a href="https://developer.android.com/reference/kotlin/android/app/ActivityManager#gethistoricalprocessexitreasons">ActivityManager.getHistoricalProcessExitReasons()</a> method, allowing developers to request details surrounding their app’s recent exits. Apps can exit for many reasons, including crashes. This update helps developers get a better understanding of their app’s stability and how to improve its performance.</li><li><strong>Scoped storage enhancement:</strong> You can no longer use the <a href="https://developer.android.com/reference/android/content/Intent#ACTION_OPEN_DOCUMENT_TREE">ACTION_OPEN_DOCUMENT_TREE</a> intent action to request access to the root directory of the internal storage volume, download directory, and to the root directory of each SD card. Apps that require broad access file can declare the <a href="https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE">MANAGE_EXTERNAL_STORAGE</a> permission and use the <a href="https://developer.android.com/reference/android/provider/Settings#ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION">ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION</a> intent action to direct users to a system settings page where they can enable the <strong>Allow access to manage all files </strong>option for your app. With <a href="https://developer.android.com/reference/android/Manifest.permission#MANAGE_EXTERNAL_STORAGE">MANAGE_EXTERNAL_STORAGE</a> permission, apps can read &amp; write files in the <a href="https://developer.android.com/training/data-storage/shared">shared storage</a> and access the content of <a href="https://developer.android.com/reference/android/provider/MediaStore.Files">MediaStore.Files</a></li><li><strong>ADB incremental installations:</strong> Installing large (2GB or larger) APKs using ADB can be a slow process. In Android 11, developers can load these APKs onto devices up to 10x faster thanks to incremental APK installations. It works by installing enough of the APK to launch the app while streaming the remaining data in the background. This is particularly useful for developers working on mobile games. It only works on Pixel 4 devices as of DP3, but handsets that launch with Android 11 will also tout this feature.</li><li><strong>Wireless debugging improvements: </strong>Android 11 supports deploying and debugging your app wirelessly from your workstation via ADB. It allows the developers to connect multiple remote devices wirelessly using a pairing code, but Google plans to add QR code syncing in an upcoming Android Studio release.</li><li><strong>Improved data access auditing: </strong><a href="https://developer.android.com/reference/android/app/AppOpsManager.OnOpNotedCallback">AppOpsManager.OnOpNotedCallback</a> provides the insights to better identify and rectify potentially unexpected data access. Your app can register an instance of the callback to better understand how the app access user information.</li><li><strong>Better support for curved/waterfall displays:</strong> <a href="https://developer.android.com/reference/android/view/DisplayCutout#getWaterfallInsets()">DisplayCutout.getWaterfallInsets()</a> to get exact dimensions of the waterfall inset to support <em>waterfall displays</em>, displays that wrap around the edge of the device. The existing <a href="https://developer.android.com/reference/android/view/DisplayCutout">DisplayCutout</a>.getSafeInset…() methods now return the safe inset to avoid waterfall areas as well as cutouts.</li><li><strong>Conversation improvements &amp; Chat Bubbles:</strong> Improvements to enhance the way <em>conversations</em> are handled. <a href="https://developer.android.com/guide/topics/ui/bubbles">Bubbles</a> are now available to developers to help surface conversations across the system.</li><li><strong>Large datasets secured sharing using data blobs:</strong> To help reduce data redundancy, both over the network and on disk, Android 11 caches shared datasets that support <strong>use cases such as machine learning and media playback</strong>. When your app needs access to a shared large dataset, it can first look for these cached datasets, called <em>shared data blobs</em>, before determining whether to download a new copy. The system maintains shared data blobs and controls which apps can access them using a <a href="https://developer.android.com/reference/android/app/blob/BlobHandle">BlobHandle</a> object. Each instance of BlobHandle contains a cryptographically-secure hash and some identifying details for the dataset.</li><li><strong>Synchronized IME transitions: </strong><a href="https://github.com/android/user-interface-samples/tree/master/WindowInsetsAnimation">WindowInsetsAnimation</a> API that let’s sync your app’s content with the onscreen keyboard and system bars as they animate on and offscreen. This will hopefully allow devs to create more natural, intuitive, and “jank-free” IME transitions. To synchronize your app’s views with the appearance and disappearance of the IME, set a listener on a view by providing a <a href="https://developer.android.com/reference/android/view/View#setWindowInsetsAnimationCallback(android.view.WindowInsetsAnimation.Callback)">WindowInsetsAnimation.Callback</a> to <a href="https://developer.android.com/reference/android/view/View#setWindowInsetsAnimationCallback(android.view.WindowInsetsAnimation.Callback)">View.setWindowInsetsAnimationCallback()</a></li><li><strong>Variable refresh rate:</strong> In Android 11, apps and games can now set a preferred frame rate for each window. On devices with variable refresh rates, the system will now use the app’s preferred frame rate to choose the best refresh rate for the app. You can read more about this new Frame rate API <a href="https://developer.android.com/guide/topics/media/frame-rate">here</a>.</li><li><strong>5G state API:</strong> Developers can now quickly check whether a user is currently connected on a 5G New Radio or Non-Standalone network.</li><li><strong>Call screening service improvements:</strong> New APIs to let call-screening apps do more to keep calls from bugging users. These apps will now be able to report a call rejection reason, as well as see if a call is being made to or from a number in the user’s contacts.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oj7WkDacmXnL2IeyTpHzug.png" /><figcaption>Android 11 release timeline</figcaption></figure><p>Read more in Features &amp; APIs Overview section of Android Developer site: <a href="https://developer.android.com/preview/features">https://developer.android.com/preview/features</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=22f1199e982a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/android-11-developer-focused-updates-dp3-22f1199e982a">Android 11 — Developer focused updates [DP3]</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AndroidX Activity Result APIs —  The new way!]]></title>
            <link>https://medium.com/droid-log/androidx-activity-result-apis-the-new-way-7cfc949a803c?source=rss----ac549fb65f65---4</link>
            <guid isPermaLink="false">https://medium.com/p/7cfc949a803c</guid>
            <category><![CDATA[android-activity]]></category>
            <category><![CDATA[jetpack]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[androiddev]]></category>
            <dc:creator><![CDATA[Anoop M. Madasseri]]></dc:creator>
            <pubDate>Tue, 09 Jun 2020 13:28:27 GMT</pubDate>
            <atom:updated>2020-06-11T09:35:31.183Z</atom:updated>
            <content:encoded><![CDATA[<h3>AndroidX Activity Result APIs<strong> —</strong> The new way!</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/773/1*hMXMxbH-yuWuP2gnHYFb7Q.png" /></figure><p>Traditionally, we use <a href="https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int)">startActivityForResult</a>() and <a href="https://developer.android.com/reference/android/app/Activity#onActivityResult(int,%20int,%20android.content.Intent)">onActivityResult</a>() APIs to start another activity and receive a result back that is available on the Activity classes on all API levels.</p><p><em>With JetPack, it’s strongly recommended to get the business done with all-new Activity Result APIs introduced in AndroidX </em><a href="https://developer.android.com/jetpack/androidx/releases/activity#1.2.0-alpha02"><em>Activity 1.2.0-alpha02</em></a><em> and </em><a href="https://developer.android.com/jetpack/androidx/releases/fragment#1.3.0-alpha02"><em>Fragment 1.3.0-alpha02</em></a><em> roll out</em>.</p><p>You now have a nice abstraction which allows you to handle onActivityResult() method in a very clean and reusable structure, You can register a callback for an Activity Result, The Activity Result APIs provide components for registering for a result, launching the result, and handling the result once it is dispatched by the system.</p><h4><strong>Activity Result APIs </strong>—</h4><ul><li><a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller#registerForActivityResult(androidx.activity.result.contract.ActivityResultContract%3CI,%20O%3E,%20androidx.activity.result.ActivityResultCallback%3CO%3E)">registerForActivityResult()</a>— For registering the result callback</li><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContract">ActivityResultContract</a>— A contract specifying that an activity can be called with an input of type I and produce an output of type O Makes calling an activity for result type-safe.</li><li><a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultCallback">ActivityResultCallback</a> — A type-safe callback to be called when an <a href="https://developer.android.com/reference/android/app/Activity.html#onActivityResult(int,%20int,%20android.content.Intent)">activity result</a> is available. It’s is a single method interface with an <a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultCallback#onActivityResult(O)">onActivityResult()</a> method that takes an object of the output type defined in the ActivityResultContract</li><li><a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultLauncher">ActivityResultLauncher</a> — A launcher for a previously-<a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller#registerForActivityResult(androidx.activity.result.contract.ActivityResultContract%3CI,%20O%3E,%20androidx.activity.result.ActivityResultCallback%3CO%3E)">prepared call</a> to start the process of executing an <a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContract">ActivityResultContract</a>.</li></ul><blockquote>registerForActivityResult() takes an <a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContract">ActivityResultContract</a> and an <a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultCallback">ActivityResultCallback</a> and returns an <a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultLauncher">ActivityResultLauncher</a> which you’ll use to launch the other activity.</blockquote><p>You can either use different contracts or want separate callbacks for multiple activity result call, you can call registerForActivityResult() multiple times to register multiple ActivityResultLauncher instances.</p><p>registerForActivityResult() is safe to call before your fragment or activity is created, allowing it to be used directly when declaring member variables for the returned ActivityResultLauncher instances. But you cannot launch the <strong>ActivityResultLauncher</strong> until the fragment or activity’s <a href="https://developer.android.com/reference/androidx/lifecycle/Lifecycle.State#CREATED"><strong>CREATED</strong></a>.</p><h4>Launching an activity for the result —</h4><p>Calling <a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultLauncher#launch(I)">launch()</a>starts the process of producing the result. When the user is done with the subsequent activity and returns, the onActivityResult() from the ActivityResultCallback is then executed</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/abf38ae66482cc7b09d46ec70e0e72f1/href">https://medium.com/media/abf38ae66482cc7b09d46ec70e0e72f1/href</a></iframe><p>You can use the prebuilt ActivityResultContract from <a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts">ActivityResultContracts</a>. Alongside this, you can create custom contracts as well. You can read <a href="https://developer.android.com/training/basics/intents/result#custom">here</a> to learn more about creating a custom contract.</p><h4>Generic StartActivityForResult contract —</h4><p><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.StartActivityForResult">StartActivityForResult</a> can be used for the generic purposes. This is an <a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContract">ActivityResultContract</a> that doesn’t do any type conversion, taking raw <a href="https://developer.android.com/reference/android/content/Intent.html">Intent</a> as an input and <a href="https://developer.android.com/reference/androidx/activity/result/ActivityResult">ActivityResult</a> as an output. Can be registered with <a href="https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller#registerForActivityResult(androidx.activity.result.contract.ActivityResultContract%3CI,%20O%3E,%20androidx.activity.result.ActivityResultCallback%3CO%3E)">ActivityResultCaller.registerForActivityResult(ActivityResultContract, ActivityResultCallback)</a> to avoid having to manage request codes when calling an activity API for which a type-safe contract is not available.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5dac5cca5c2979ca712645f655ffc6d8/href">https://medium.com/media/5dac5cca5c2979ca712645f655ffc6d8/href</a></iframe><h4>Ready to Use Contracts —</h4><ul><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.RequestPermission">RequestPermission</a></li><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.RequestMultiplePermissions">RequestMultiplePermissions</a></li><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.TakePicture">TakePicture</a></li><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.OpenDocument">OpenDocument</a></li><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.OpenDocumentTree">OpenDocumentTree</a></li><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.StartActivityForResult">StartActivityForResult</a></li></ul><p>You can find more <a href="https://developer.android.com/reference/androidx/activity/result/contract/package-summary">here</a></p><h4>Dependencies —</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1de4cc59296ad1d75b63ff297c3af568/href">https://medium.com/media/1de4cc59296ad1d75b63ff297c3af568/href</a></iframe><h4>Package Summary —</h4><ul><li><a href="https://developer.android.com/reference/androidx/activity/result/package-summary">androidx.activity.result</a></li><li><a href="https://developer.android.com/reference/androidx/activity/result/contract/package-summary">androidx.activity.result.contract</a></li></ul><blockquote>We need to be conservative when developing apps that run in the Android ecosystem which is targeted to a vast and wide variety of OEM manufacturers, When starting an activity for a result, it is possible (and, in cases of memory-intensive operations such as camera usage, almost certain) that your process and your activity will be destroyed due to low memory. For this reason, the Activity Result APIs decouple the result callback from the place in your code where you launch the other activity. As the result callback needs to be available when your process and activity are recreated, the callback must be unconditionally registered every time your activity is created.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7cfc949a803c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/droid-log/androidx-activity-result-apis-the-new-way-7cfc949a803c">AndroidX Activity Result APIs —  The new way!</a> was originally published in <a href="https://medium.com/droid-log">Tech Log</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>