<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Android &amp; iOS development Archives - Creatronix</title>
	<atom:link href="https://creatronix.de/category/software-engineering/android-ios/feed/" rel="self" type="application/rss+xml" />
	<link>https://creatronix.de/category/software-engineering/android-ios/</link>
	<description>My adventures in code &#38; business</description>
	<lastBuildDate>Wed, 17 Dec 2025 10:07:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Anatomy of a Gradle file</title>
		<link>https://creatronix.de/anatomy-of-a-gradle-file/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sat, 12 Feb 2022 13:49:28 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=3884</guid>

					<description><![CDATA[<p>Motivation Understanding Gradle is mandatory if you want to build good Android apps Bare Minimum This is the bare minimum you need to be able to compile and run an Android application: plugins { id 'com.android.application' id 'kotlin-android' } android { compileSdk 30 defaultConfig { applicationId "de.creatronix.myapplication" minSdk 21 } } dependencies { implementation 'androidx.core:core-ktx:1.6.0'&#8230;</p>
<p>The post <a href="https://creatronix.de/anatomy-of-a-gradle-file/">Anatomy of a Gradle file</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Understanding Gradle is mandatory if you want to build good Android apps</p>
<h2>Bare Minimum</h2>
<p>This is the bare minimum you need to be able to compile and run an Android application:</p>
<pre>plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdk 30

    defaultConfig {
        applicationId "de.creatronix.myapplication"
        minSdk 21
    }
    
}

dependencies {
    implementation 'androidx.core:core-ktx:1.6.0'
}</pre>
<p>Let&#8217;s dissect the parts</p>
<h2>Plugins</h2>
<p>Plugins are programs which extend the gradle build process</p>
<p>When you need special feature like annotation processing the Plugin goes here</p>
<p><a href="https://creatronix.de/what-is-kapt/">What is kapt?</a></p>
<h2>Android</h2>
<p>In this section you define for which specific android version you are developing:</p>
<p>minSdk means that your app isn&#8217;t supported on devices with an API level below.</p>
<p>targetSdk is the preferred Android version you like to run on</p>
<p>You can add buildTypes section to distinguish between release and debug builds.</p>
<p>In the release build you can e.g. enable the minification</p>
<p><a href="https://creatronix.de/how-to-enable-r8-in-your-build-process/">How to enable R8 in your build process</a></p>
<p><a href="https://creatronix.de/what-is-proguard/">What is ProGuard?</a></p>
<p><a href="https://creatronix.de/how-to-fix-android-view-inflateexception-error-inflating-class-fragment/">How to fix android.view.InflateException: Error inflating class fragment</a></p>
<h2>Depencencies</h2>
<p>Dependencies come in many flavors:</p>
<h3>implementation</h3>
<p>These are dependencies which are needed to run the application</p>
<p>Until gradle 7.0 these dependencies were called &#8220;compile&#8221;. Now they are deprecated, so use implementation</p>
<h3>testImplementation</h3>
<p>The dependency is only available in the <strong>test</strong> source set.</p>
<h3>androidTestImplementation</h3>
<p>The dependency is only available in the <strong>androidTest</strong> source set.</p>
<p>&nbsp;</p>
<p>The post <a href="https://creatronix.de/anatomy-of-a-gradle-file/">Anatomy of a Gradle file</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dependency Injection with Koin and Kotlin in Android</title>
		<link>https://creatronix.de/dependency-injection-with-koin-and-kotlin-in-android/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sun, 16 Jan 2022 13:31:53 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<category><![CDATA[Kotlin & Java]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=4528</guid>

					<description><![CDATA[<p>This article is a guest post from Caroline Riekert Motivation There are a lot of reasons to use Dependency Injection, or even a Framework for it. In this Article you&#8217;ll learn what Dependency Injection is, what benefits and downsides it has and how to use it with the usage of the Koin Framework. Let&#8217;s look&#8230;</p>
<p>The post <a href="https://creatronix.de/dependency-injection-with-koin-and-kotlin-in-android/">Dependency Injection with Koin and Kotlin in Android</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This article is a guest post from <a href="https://twitter.com/mahoca6">Caroline Riekert</a></p>
<h2>Motivation</h2>
<p>There are a lot of reasons to use Dependency Injection, or even a Framework for it.</p>
<p>In this Article you&#8217;ll learn what Dependency Injection is, what benefits and downsides it has and how to use it with the usage of the Koin Framework.</p>
<p>Let&#8217;s look at a example of a House with a Doorbell to better understand what dependency injection is.</p>
<p>The House class has a function that returns a String representing the current Ringtone according to the installed doorbell.</p>
<p>Without Dependency Injection:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>class House() {
    private val myDoorbell: Doorbell
   
   init {
       myDoorbell = SpeakingDoorbell()
   }
   
   fun ringDoorbell(): String {
       return "Current ringtone " + myDoorbell.getRingtone()
   }
}

fun main() {
    val myHouse = House()
   
    println(myHouse.ringDoorbell())
}
</code></pre>
</div>
<p>With Dependency Injection:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>class House(private val myDoorbell: Doorbell) {
   fun ringDoorbell(): String {
       return "Current ringtone " + myDoorbell.getRingtone()
   }
}

fun main() {
    val myDoorbell: Doorbell = SpeakingDoorbell()
    val myHouse = House(myDoorbell)
   
    println(myHouse.ringDoorbell())
}</code></pre>
</div>
<p>As you can see in the variant without Dependency Injection the House class has a direct dependency to the SpeakingDoorbell class.</p>
<p>With Dependency Injection this reference no longer exists. The only reference<br />
remaining is to the generalized Doorbell Interface.</p>
<h2>Benefits of Dependency Injection</h2>
<h3>Flexibility</h3>
<p>Lets suppose another class FunnyDoorbell should be used in the future, which also implements the <strong>Doorbell</strong> interface.</p>
<p>Exchanging the SpeakingDoorbell class later on is less work with Dependency Injection.</p>
<p>In the first example the House class would have to change its implementation to switch to the FunnyDoorbell class.</p>
<p>But with Dependency Injection this change can be done without touching the House class.</p>
<p>In fact the House class does not even know whether it got an instance of SpeakingDoorbell or FunnyDoorbell.</p>
<p>This allows to write more flexible code which can be modified and extended easier.</p>
<p>A looser coupling between classes is achieved.</p>
<h3>Testability</h3>
<p>When writing tests one cannot test the House class in the first example in isolation to the SpeakingDoorbell class.</p>
<p>With Dependency Injection it&#8217;s very easy to insert mocks instead of the real instance.</p>
<h2>Downsides of Dependency Injection</h2>
<p>There is one part that got more complex though. The main function now knows not only the House class, but also the SpeakingDoorbell class.</p>
<p>This ultimately leads to a really big main function, that knows almost every component.</p>
<p>In this small example this is no issue, but when developing large applications we want the benefits of Dependency Injection, but as few downsides as possible.</p>
<p>This is exactly where Dependency Injection Frameworks comes into play!</p>
<p>They help to structure the whole block how and when to instantiate which classes and usually bring with them a bunch of useful features.</p>
<p>So let us look into the Dependency Injection Framework Koin.</p>
<h2>Setting up Koin</h2>
<h3>Gradle</h3>
<p>Add the following to your gradle configuration.<br />
Get the latest Koin version [here](https://insert-koin.io/docs/setup/v3).</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Gradle"><code>// Add Maven Central to your repositories if needed
repositories {
    mavenCentral()    
}
dependencies {
    // Koin for Android
    implementation "io.insert-koin:koin-android:$koin_version"
}</code></pre>
</div>
<h3>Application</h3>
<p>Create an application class if you have none yet (don&#8217;t forget to add it to the manifest).</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
     
        startKoin {
            androidContext(this@MyApplication)
            modules(
                module {
                    single { House(get()) }
                    single&lt;Doorbell&gt; { SpeakingDoorbell() }
                }
            )
        }
    } 
}</code></pre>
</div>
<h3>Profit</h3>
<p>That&#8217;s it! This is the basic Koin setup. As you can see the House class now even fetches its needed instance of Doorbell.<br />
Simply call <strong>startKoin</strong>, configure the AndroidContext and define some Beans. These can also be injected like this into Android components like activities:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>val myVariable: MyVariableType by inject()</code></pre>
</div>
<h3>ViewModel injection</h3>
<p>The avid reader might already have noticed something. &#8220;What about our ViewModels. They have a lifecycle and should not get created just like that&#8221;.</p>
<p>To fix this issue there exists an extension for Koin.</p>
<p>Instead of declaring a Bean like that</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>single { MyClass() }
</code></pre>
</div>
<p>we use</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>viewModel&lt;MyViewModelType&gt; { MyViewModel() }
</code></pre>
</div>
<p>The injection is then done inside the fragment like that:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>val myViewModel: MyViewModelType by viewModel()
</code></pre>
</div>
<h2>Conclusion</h2>
<p>Using Dependency Injection, especially with a framework, can be intimidating for a new programmer.</p>
<p>But in the most cases the positive aspects outweigh the negatives and the complexity of setting up a dependency<br />
injection framework is quite low.</p>
<p>There are a lot of other things Koin can do like defining factories instead of singles, directly helping out with tests, instantiating fragments, or much more.</p>
<p>Have a glance at the <a href="https://insert-koin.io/docs/reference/introduction">official documentation</a></p>
<p>The post <a href="https://creatronix.de/dependency-injection-with-koin-and-kotlin-in-android/">Dependency Injection with Koin and Kotlin in Android</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to fix android.view.InflateException: Error inflating class fragment</title>
		<link>https://creatronix.de/how-to-fix-android-view-inflateexception-error-inflating-class-fragment/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sun, 21 Nov 2021 10:09:17 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<category><![CDATA[Error inflating class fragment]]></category>
		<category><![CDATA[InflateException]]></category>
		<category><![CDATA[keepnames]]></category>
		<category><![CDATA[parcelize]]></category>
		<category><![CDATA[proguard]]></category>
		<category><![CDATA[r8]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=4148</guid>

					<description><![CDATA[<p>I got the error E/AndroidRuntime: FATAL EXCEPTION: main Process: de.creatronix.levelup, PID: 17026 java.lang.RuntimeException: Unable to start activity ComponentInfo{de.creatronix.levelup/de.creatronix.levelup.MainActivity}: android.view.InflateException: Binary XML file line #18: Error inflating class fragment after enabling minification in my build. The issue is that with the usage of safeargs with custom objects we use the the @parcelize annotation which seems to&#8230;</p>
<p>The post <a href="https://creatronix.de/how-to-fix-android-view-inflateexception-error-inflating-class-fragment/">How to fix android.view.InflateException: Error inflating class fragment</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I got the error</p>
<pre>E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.creatronix.levelup, PID: 17026
java.lang.RuntimeException: Unable to start activity ComponentInfo{de.creatronix.levelup/de.creatronix.levelup.MainActivity}: android.view.InflateException: Binary XML file line #18: Error inflating class fragment</pre>
<p>after enabling minification in my build.</p>
<p>The issue is that with the usage of <a href="https://creatronix.de/pass-custom-objects-via-safeargs/">safeargs with custom objects</a> we use the the @parcelize annotation which seems to be <a href="https://creatronix.de/how-to-enable-r8-in-your-build-process/">optimized away with R8</a><span id="more-4148"></span></p>
<h2>Fix</h2>
<p>Add</p>
<pre>-keepnames class * extends android.os.Parcelable</pre>
<p>to your <a href="https://creatronix.de/what-is-proguard/">proguard-rules.pro file</a></p>
<p>The post <a href="https://creatronix.de/how-to-fix-android-view-inflateexception-error-inflating-class-fragment/">How to fix android.view.InflateException: Error inflating class fragment</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to use ViewModel in Android</title>
		<link>https://creatronix.de/how-to-use-viewmodel/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Wed, 17 Nov 2021 14:35:43 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<category><![CDATA[activityViewModels]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[livedata]]></category>
		<category><![CDATA[observer]]></category>
		<category><![CDATA[viewmodel]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=3871</guid>

					<description><![CDATA[<p>Dependencies dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0' ViewModel class and LiveData class PracticeProgressViewModel : ViewModel() { private val _text = MutableLiveData&#60;String&#62;().apply { value = "" } val text: MutableLiveData&#60;String&#62; = _text fun setText(value: String){ _text.value = value } } Fragment class PracticeProgressFragment : Fragment() { private val homeViewModel: PracticeProgressViewModel by activityViewModels() Observer Pattern override fun onCreateView( inflater:&#8230;</p>
<p>The post <a href="https://creatronix.de/how-to-use-viewmodel/">How to use ViewModel in Android</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Dependencies</h2>
<pre>dependencies {
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
</pre>
<h2>ViewModel class and LiveData</h2>
<p><span id="more-3871"></span></p>
<pre>class PracticeProgressViewModel : ViewModel() {
    
    private val _text = MutableLiveData&lt;String&gt;().apply {
        value = ""
    }

    val text: MutableLiveData&lt;String&gt; = _text

    fun setText(value: String){
        _text.value = value
    }
}</pre>
<h2>Fragment</h2>
<pre>class PracticeProgressFragment : Fragment() {

    private val <strong>homeViewModel</strong>: PracticeProgressViewModel by activityViewModels()
</pre>
<p>Observer Pattern</p>
<pre>    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        <strong>homeViewModel</strong>.text.observe(viewLifecycleOwner, {
            textView.text = it
        })
</pre>
<p>Update the ViewModel</p>
<pre>    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val button = binding.button
        button.setOnClickListener(View.OnClickListener {
        
            val totalAmoint = practiceDao.getTotalAmount()
            <strong>homeViewModel</strong>.setText(totalAmoint.toString())
        })
    }

</pre>
<p>The post <a href="https://creatronix.de/how-to-use-viewmodel/">How to use ViewModel in Android</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Stetho &#8211; A debug bridge for Android applications</title>
		<link>https://creatronix.de/stetho-a-debug-bridge-for-android-applications/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Tue, 09 Nov 2021 11:19:55 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=4011</guid>

					<description><![CDATA[<p>Stetho is a sophisticated debug bridge for Android applications. When enabled, developers have access to the Chrome Developer Tools feature natively part of the Chrome desktop browser. Developers can also choose to enable the optional dumpapp tool which offers a powerful command-line interface to application internals. Gradle implementation 'com.facebook.stetho:stetho:1.6.0' Initialization class PracticeTrackerApplication : Application() {&#8230;</p>
<p>The post <a href="https://creatronix.de/stetho-a-debug-bridge-for-android-applications/">Stetho &#8211; A debug bridge for Android applications</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<blockquote><p><a href="https://github.com/facebook/stetho">Stetho</a> is a sophisticated debug bridge for Android applications. When enabled, developers have access to the Chrome Developer Tools feature natively part of the Chrome desktop browser. Developers can also choose to enable the optional dumpapp tool which offers a powerful command-line interface to application internals.</p></blockquote>
<h2>Gradle</h2>
<pre>implementation 'com.facebook.stetho:stetho:1.6.0'</pre>
<h2>Initialization</h2>
<pre>class PracticeTrackerApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        Stetho.initializeWithDefaults(this)
    }</pre>
<h2>Chrome DevTools</h2>
<pre>chrome://inspect/#devices</pre>
<p>The post <a href="https://creatronix.de/stetho-a-debug-bridge-for-android-applications/">Stetho &#8211; A debug bridge for Android applications</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What is kapt?</title>
		<link>https://creatronix.de/what-is-kapt/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Tue, 09 Nov 2021 07:34:29 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=3869</guid>

					<description><![CDATA[<p>kapt is short for Kotlin annotation processor tool. Why do I need it? tl;dr; every time you use an annotation in a Kotlin file you need to use kapt. E.g. @Parcelize  in Pass custom objects via SafeArgs Prerequisites dependencies { kapt("groupId:artifactId:version") } plugins { kotlin("kapt") version "1.5.31" } Further reading https://kotlinlang.org/docs/kapt.html</p>
<p>The post <a href="https://creatronix.de/what-is-kapt/">What is kapt?</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>kapt is short for Kotlin annotation processor tool.</p>
<h2>Why do I need it?</h2>
<p>tl;dr; every time you use an annotation in a Kotlin file you need to use kapt.</p>
<p>E.g. @Parcelize  in <a href="https://creatronix.de/pass-custom-objects-via-safeargs/">Pass custom objects via SafeArgs</a></p>
<h2>Prerequisites</h2>
<pre id="code-ZqpmCV6pioh" class="code-block__pre language-kotlin">dependencies {
    kapt("groupId:artifactId:version")
}</pre>
<pre id="code-qLGZXkxhmo_" class="code-block__pre language-kotlin">plugins {
    kotlin("kapt") version "1.5.31"
}</pre>
<h2>Further reading</h2>
<p><a href="https://kotlinlang.org/docs/kapt.html">https://kotlinlang.org/docs/kapt.html</a></p>
<p>The post <a href="https://creatronix.de/what-is-kapt/">What is kapt?</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What is Ninja?</title>
		<link>https://creatronix.de/what-is-ninja/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Tue, 09 Nov 2021 07:33:36 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=3956</guid>

					<description><![CDATA[<p>Ninja is a build system which replaces the GNU make in AOSP Up to Marshmallow / 6,0 the build system was based on GNU Make In Nougat / 7.0 and later, the build is run by ninja Ninja works from a pre-processed manifest generated by kati and soong kati kati converts Android.mk files into ninja&#8230;</p>
<p>The post <a href="https://creatronix.de/what-is-ninja/">What is Ninja?</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Ninja is a build system which replaces the GNU make in AOSP</p>
<ul>
<li>Up to Marshmallow / 6,0 the build system was based on GNU Make</li>
<li>In Nougat / 7.0 and later, the build is run by ninja</li>
<li>Ninja works from a pre-processed manifest generated by kati and soong</li>
</ul>
<h2>kati</h2>
<p><a href="https://github.com/google/kati">kati</a> converts Android.mk files into ninja manifests</p>
<h2>soong</h2>
<p><a href="https://android.googlesource.com/platform/build/soong/+/refs/heads/master/README.md">soong</a> converts blueprint files (Android.bp) into ninja manifests</p>
<p>Example bp file</p>
<p><a href="https://android.googlesource.com/platform/system/core/+/refs/tags/android-11.0.0_r46/logcat/Android.bp">https://android.googlesource.com/platform/system/core/+/refs/tags/android-11.0.0_r46/logcat/Android.bp</a></p>
<h2>Further reading</h2>
<p><a href="https://ninja-build.org/">https://ninja-build.org/</a></p>
<p>The post <a href="https://creatronix.de/what-is-ninja/">What is Ninja?</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dababase Stuff with Room</title>
		<link>https://creatronix.de/dababase-stuff-with-room/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Mon, 08 Nov 2021 15:13:43 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=3831</guid>

					<description><![CDATA[<p>What a nice room! Room is an ORM which runs on Android and persists its data into an sqlite database. Gradle Room makes use of the kotlin annotation processing tool KAPT. So we need to apply the plugin: plugins { ... id 'kotlin-kapt' } These are the dependencies we need to use room and kapt:&#8230;</p>
<p>The post <a href="https://creatronix.de/dababase-stuff-with-room/">Dababase Stuff with Room</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>What a nice room!</h2>
<p>Room is an ORM which runs on Android and persists its data into an sqlite database.<span id="more-3831"></span></p>
<h2>Gradle</h2>
<p>Room makes use of the kotlin annotation processing tool KAPT. So we need to apply the plugin:</p>
<pre>plugins {
    ...
    id 'kotlin-kapt'
}</pre>
<p>These are the dependencies we need to use room and kapt:</p>
<pre>    implementation "androidx.room:room-runtime:2.3.0"
    kapt "androidx.room:room-compiler:2.3.0"

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation "androidx.room:room-ktx:2.3.0"</pre>
<h2>Entity class</h2>
<p>an entity class represents the entry which is persisted in the database</p>
<pre>import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "practice_session")
data class PracticeSession(
    @PrimaryKey(autoGenerate = true) val uid: Int = 0,
    @ColumnInfo(name = "start_time") val startTime: Long,
    @ColumnInfo(name = "stop_time") val stopTime: Long
)</pre>
<h2>DAO</h2>
<p>DAO is short for data access object</p>
<pre>import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query

@Dao
interface PracticeDao {
    @Query("SELECT * FROM practice_session")
    fun getAll(): List&lt;PracticeSession&gt;

    @Insert
    fun insert(drink: PracticeSession)
}</pre>
<h2>RoomDatabase</h2>
<pre>@Database(entities = [PracticeSession::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun practiceDao(): PracticeDao

    companion object {
        // Singleton prevents multiple instances of database opening at the
        // same time.
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getDatabase(context: Context): AppDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "practice_session"
                ).allowMainThreadQueries().build()
                INSTANCE = instance
                // return instance
                instance
            }
        }
    }
}</pre>
<h2>Own application class</h2>
<p>tbd</p>
<p>&nbsp;</p>
<p>Hint: Database Inspector is now called App Inspection</p>
<p>Hint 2: just works with API Level &gt;= 26</p>
<p>Hint 3 Action -&gt; Navigate to database folder</p>
<p><a href="https://developer.android.com/codelabs/kotlin-android-training-room-database">https://developer.android.com/codelabs/basic-android-kotlin-training-intro-room-flow#0</a></p>
<p>The post <a href="https://creatronix.de/dababase-stuff-with-room/">Dababase Stuff with Room</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How can you use StrictMode in your Android app?</title>
		<link>https://creatronix.de/how-can-you-use-strictmode-in-your-android-app/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Mon, 08 Nov 2021 13:56:32 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=4032</guid>

					<description><![CDATA[<p>import android.os.StrictMode import android.os.StrictMode.ThreadPolicy import android.os.StrictMode.VmPolicy class LevelUpApplication : Application() { override fun onCreate() { if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy( ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build() ) StrictMode.setVmPolicy( VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build() ) } super.onCreate() https://developer.android.com/reference/android/os/StrictMode</p>
<p>The post <a href="https://creatronix.de/how-can-you-use-strictmode-in-your-android-app/">How can you use StrictMode in your Android app?</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<pre>import android.os.StrictMode
import android.os.StrictMode.ThreadPolicy
import android.os.StrictMode.VmPolicy


class LevelUpApplication : Application() {
    override fun onCreate() {
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(
                ThreadPolicy.Builder()
                    .detectDiskReads()
                    .detectDiskWrites()
                    .detectNetwork()
                    .penaltyLog()
                    .build()
            )
            StrictMode.setVmPolicy(
                VmPolicy.Builder()
                    .detectLeakedSqlLiteObjects()
                    .detectLeakedClosableObjects()
                    .penaltyLog()
                    .penaltyDeath()
                    .build()
            )
        }
        super.onCreate()</pre>
<p><a href="https://developer.android.com/reference/android/os/StrictMode">https://developer.android.com/reference/android/os/StrictMode</a></p>
<p>The post <a href="https://creatronix.de/how-can-you-use-strictmode-in-your-android-app/">How can you use StrictMode in your Android app?</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Replace findViewById with View Binding</title>
		<link>https://creatronix.de/replace-findviewbyid-with-view-binding/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Mon, 08 Nov 2021 13:16:49 +0000</pubDate>
				<category><![CDATA[Android & iOS development]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=4025</guid>

					<description><![CDATA[<p>Perhaps you have code that looks like that: val mImageView = findViewById&#60;ImageView&#62;(R.id.img_view) mImageView.setOnClickListener(View.OnClickListener This has worked properly over the last years but what are the drawbacks? Or what are the promises of the new View Binding concept? View Binding is always null-safe and type-safe It compiles faster Gradle Enable View Binding in gradle: android {&#8230;</p>
<p>The post <a href="https://creatronix.de/replace-findviewbyid-with-view-binding/">Replace findViewById with View Binding</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Perhaps you have code that looks like that:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>val mImageView = findViewById&lt;ImageView&gt;(R.id.img_view) 
mImageView.setOnClickListener(View.OnClickListener</code></pre>
</div>
<p>This has worked properly over the last years but what are the drawbacks?</p>
<p>Or what are the promises of the new View Binding concept?</p>
<ul>
<li>View Binding is always null-safe and type-safe</li>
<li>It compiles faster</li>
</ul>
<h2>Gradle</h2>
<p>Enable View Binding in gradle:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-gradle" data-lang="Groovy"><code>android { 
    ... 
    buildFeatures { 
        viewBinding true 
    } 
}</code></pre>
</div>
<h2>Implementation</h2>
<p>In your Fragment or Activity you need to instantiate the View Binding class for your layout:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>private var _binding: YourFragmentBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
_binding = YourFragmentBinding.inflate(inflater, container, false)</code></pre>
</div>
<p>Now you can use it as follows:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-java" data-lang="Kotlin"><code>binding.imgView.setOnClickListener { ... }</code></pre>
</div>
<p>Instead of searching via findViewById ViewBinding generates properties which you can access directly.</p>
<h2>Further Reading</h2>
<p><a href="https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc">https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc</a></p>
<p>&nbsp;</p>
<p>The post <a href="https://creatronix.de/replace-findviewbyid-with-view-binding/">Replace findViewById with View Binding</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
