<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Android on Jamie Craane personal blog</title>
    <link>https://jamiecraane.dev/tags/android/</link>
    <description>Recent content in Android on Jamie Craane personal blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 13 Nov 2022 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://jamiecraane.dev/tags/android/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Jetpack Compose - Recompositions</title>
      <link>https://jamiecraane.dev/2022/11/13/compose_recompositions/</link>
      <pubDate>Sun, 13 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://jamiecraane.dev/2022/11/13/compose_recompositions/</guid>
      <description>&lt;h1 id=&#34;what-is-recomposition&#34;&gt;What is recomposition&lt;/h1&gt;&#xA;&lt;p&gt;A Compose function in Jetpack Compose represents some UI to be rendered:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-kotlin&#34; data-lang=&#34;kotlin&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@Composable&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;fun&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;UsersScreen&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;var&lt;/span&gt; usersScreenState &lt;span style=&#34;color:#ff79c6&#34;&gt;by&lt;/span&gt; remember {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        mutableStateOf(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            UsersScreenState(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                title = &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Users&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                body = &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;This is the users screen&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;..&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;40&lt;/span&gt;).toList().map { Person(&lt;span style=&#34;color:#ff79c6&#34;&gt;it&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Firstname Lastname &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;$it&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&lt;/span&gt;) },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            )&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        )&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Column() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Text(usersScreenState.title)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Text(usersScreenState.description)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Button(onClick = { usersScreenState = usersScreenState.copy(title = &lt;span style=&#34;color:#50fa7b&#34;&gt;Random&lt;/span&gt;.nextInt().toString()) }) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            Text(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Change title&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        PersonList(usersScreenState.persons)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that the usersScreenState is a var which means it can change. Any time the usersScreenState changes, the UI is recomposed. This is&#xA;also called recomposition. Smart recomposition means skipping Composables when their inputs have not changed and those inputs are considered stable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Standalone KMM Images</title>
      <link>https://jamiecraane.dev/2022/07/27/standalone_kmm_images/</link>
      <pubDate>Thu, 22 Sep 2022 00:00:00 +0000</pubDate>
      <guid>https://jamiecraane.dev/2022/07/27/standalone_kmm_images/</guid>
      <description>&lt;p&gt;Image by Dall-E: &lt;em&gt;&amp;ldquo;Factory which produces lots of the same products. Dark.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;context&#34;&gt;Context&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://jamiecraane.dev/2021/07/27/resource_images_kmm/&#34;&gt;https://jamiecraane.dev/2021/07/27/resource_images_kmm/&lt;/a&gt; describes how to use the &lt;a href=&#34;https://github.com/jcraane/kmm-images&#34;&gt;kmm-images plugin&lt;/a&gt; to share images between a Kotlin Multiplatform Mobile (short KMM) Android and iOS app. You can also use kmm-images in a standalone Android app. This post describes the advantages of doing this.&lt;/p&gt;&#xA;&lt;h2 id=&#34;benefits-of-using-kmm-images-in-an-android-app&#34;&gt;Benefits of using kmm-images in an Android app&lt;/h2&gt;&#xA;&lt;p&gt;Kmm-images unifies image handling in a KMM iOS and Android app. Using kmm-images in a standalone Android app has the following advantages:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Koin ViewModel Injection</title>
      <link>https://jamiecraane.dev/2022/07/27/koin_viewmodel_injection/</link>
      <pubDate>Wed, 27 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://jamiecraane.dev/2022/07/27/koin_viewmodel_injection/</guid>
      <description>&lt;p&gt;Image by Dall-E: &lt;em&gt;&amp;ldquo;Inside of a large factory assembling robots from parts. The scene is somewhat dark with neon lights. cyberpunk style.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;context&#34;&gt;Context&lt;/h2&gt;&#xA;&lt;p&gt;A ViewModel in Android (not to be confused with the term ViewModel in the MVVM architecture pattern) is a component scoped to the lifecycle&#xA;of another component, usually a fragment or an activity. To create maintainable code without becoming the ViewModel to large, the ViewModel delegates to other objects. When using&#xA;coroutines, those other objects might use suspending functions. Those functions are called from the ViewModel in a CoroutineScope. For a ViewModel this is the viewModelScope. When the ViewModel is cleared, the viewModelScope is cancelled.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Code re-usability</title>
      <link>https://jamiecraane.dev/2022/06/16/code_reusability/</link>
      <pubDate>Mon, 15 Nov 2021 00:00:00 +0000</pubDate>
      <guid>https://jamiecraane.dev/2022/06/16/code_reusability/</guid>
      <description>&lt;p&gt;Re-usability within software development means to reuse (part of) a solution in different products with the aim of:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;faster time to market&lt;/li&gt;&#xA;&lt;li&gt;lower costs&lt;/li&gt;&#xA;&lt;li&gt;less chance of introducing issues&lt;/li&gt;&#xA;&lt;li&gt;be able to use shared knowledge&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;re-usability-at-different-abstraction-levels&#34;&gt;Re-usability at different abstraction levels&lt;/h2&gt;&#xA;&lt;p&gt;Re-usability exists at many levels of abstraction in software development. Each abstraction offers some degree of advantages as well as disadvantages. Some examples, from high to low abstraction level:&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Infrastructure&lt;/strong&gt;&#xA;Using infrastructure to distribute software. This can be a cloud solution, but also an app store, for example.&lt;/p&gt;</description>
    </item>
    <item>
      <title>KMM adoption strategies</title>
      <link>https://jamiecraane.dev/2021/11/15/kmm_adoption_strategies/</link>
      <pubDate>Mon, 15 Nov 2021 00:00:00 +0000</pubDate>
      <guid>https://jamiecraane.dev/2021/11/15/kmm_adoption_strategies/</guid>
      <description>&lt;h1 id=&#34;kmm-adoption-strategies&#34;&gt;KMM adoption strategies&lt;/h1&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://kotlinlang.org/docs/kmm-getting-started.html#start-kmm-from-scratch&#34;&gt;Kotlin multiplatform Mobile&lt;/a&gt;, in short KMM, lets you write native cross platform mobile applications. It lets you share logic across iOS and Android while still leveraging all of the native features of the platform.&lt;/p&gt;&#xA;&lt;p&gt;There are several advantages of sharing code between platforms:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Reduced development time&lt;/li&gt;&#xA;&lt;li&gt;More consistent logic across platforms&lt;/li&gt;&#xA;&lt;li&gt;More consistent behavior across platforms&lt;/li&gt;&#xA;&lt;li&gt;Less bugs&lt;/li&gt;&#xA;&lt;li&gt;Improved team communication&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;KMM gives the flexibility to decide what code is shared. Without going into the details about what to share, some common strategies are:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Localized resources and images in KMM</title>
      <link>https://jamiecraane.dev/2021/07/27/resource_images_kmm/</link>
      <pubDate>Tue, 27 Jul 2021 00:00:00 +0000</pubDate>
      <guid>https://jamiecraane.dev/2021/07/27/resource_images_kmm/</guid>
      <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://kotlinlang.org/lp/mobile/&#34;&gt;Kotlin Multiplatform Mobile&lt;/a&gt; (in short KMM) allows you to share a lot of code which is normally duplicated across iOS and Android native platforms. KMM does not mandate that certain type of code is shared, it is up to you. It also does not mandate any particular architecture.&lt;/p&gt;&#xA;&lt;p&gt;Although KMM enables sharing of code between platforms it does not provide the ability to share localized string resources and images out-of-the box between iOS and Android.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Casting images with Chromecast</title>
      <link>https://jamiecraane.dev/2021/01/05/android_chromecast_images/</link>
      <pubDate>Tue, 05 Jan 2021 00:00:00 +0000</pubDate>
      <guid>https://jamiecraane.dev/2021/01/05/android_chromecast_images/</guid>
      <description>&lt;p&gt;Full source code can be found here: &lt;a href=&#34;https://github.com/jcraane/android-simple-image-cast&#34;&gt;https://github.com/jcraane/android-simple-image-cast&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;By adding Chromecast support to media rich apps like photo- and video players, users can display content to Chromecast enabled devices. This greatly enhances the user experience of those apps.&lt;/p&gt;&#xA;&lt;p&gt;This post demonstrates how to integrate the Chromecast SDK to add cast support for casting images. The app displays a list of publicly available images using an image carousel. When the user scrolls through those images, the images are cast to a connected receiver.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
