Categories
android blog koin kotlin

Using Koin for dependency management in Android apps

So I have been using Dagger2 in previous apps and I was quite ok with it. But I always felt that Dagger may be an overkill for small apps and even medium apps. So when I started working on a new Android app I decided to look for alternative ways to manage my code dependencies. I had a couple of ideas on what I need:

  • Good integration with the Android ecosystem
  • Easy to understand for new team members
  • Good performance

I heard about Koin quite some time ago so I thought this is the perfect opportunity to try it out. I did have one issue with Koin, give that it resolves dependencies during the run time I was worried about the performance a bit. So I tried to find some benchmarks and luckily I found what I was looking for in this blog post! Koin 2.x had a huge performance upgrade compared to Koin 1.x, almost a 10x improvement. For 400 dependencies it takes Koin 2.x around 10 ms to walk up the dependency graph and inject required dependencies which is more than enough for my current project.

Now comes the fun part, how easy is it to setup Koin on a new project? I have to be honest here, it took me no more than 20 minutes to get the basics of Koin and have a couple of dependencies injected in my activities. I was blown away by how simple Koin is. There are three basic concepts in Koin

  • Modules
  • Injection
  • Module list

Lets quickly explain each concept.

Modules

Similar to Dagger, Koin uses a module to group actual instances you will inject. So in my app, I have ServiceModule (dependencies for a background service), PresentationModule (android ViewModels) and DataModule (various repositories)

val myModule : Module = applicationContext {
    // ViewModel instance of MyViewModel
    // get() will resolve Repository instance
    viewModel { MyViewModel(get()) }
    // Single instance of Repository
    single<repository> { MyRepository() }
}

Injection

After instances are being provided in the modules there is a special inject() method that can inject those dependencies into Activities, ViewModels or Repositories. To give an example:

class MyActivity : AppCompatActivity(){
    // Inject MyPresenter
    val presenter : MyPresenter by inject()
    override fun onCreate() {
        super.onCreate()
        // or directly retrieve instance
        val presenter : MyPresenter = get()
    }
}

Module list

Before everything is tied up together, Koin needs to be started and all modules have to be connected so that Koin can start connecting them together. This is done with a special startKoin function that lives in the application class.

 startKoin {
            // use AndroidLogger as Koin Logger - default Level.INFO
            androidLogger()
            // use the Android context given there
            androidContext(this@MainApplication)
            // module list
            modules(serviceModule, presentationModule, dataModule)
        }

And that is basically it. In the next couple of articles, we will dig a bit deeper into some nuances that Koin has in store for us and how I solved some problems with injection in my current android project.

Stay tuned!

Categories
blog

My goals for 2019

I am a bit late to the party, as you all know, new year resolutions were due January 1, yet here I am writing about my goals for 2019 now :). But it’s never too late. Lets start by listing my goals, sorted by priority:

  1. Turn this blog into a quick reference site for Algorithms and Data structures (for my self and others)
    • Solve selected exercises from Elements of programming interviews book (Table 1.2 from the book)
    • Solve selected exercises from Data structures and algorithms made easy book
    • Due date: June 30
  2. Read Pragmatic programmer
    • Read all chapters and implement all exercises
    • Due date: March 30
  3. Read Deep work
    • Construct a work environment where deep work is easy and the only option
    • Due date: April 30
  4. Read clean architecture
    • Read all chapters and implement all exercises
    • Due date: April 30
  5. Port my Green to work app for iOS
    • Due date: November 30
  6. Read the War of art
    • Due date: May
  7. Publish 12 new articles, tech related:
    • Due date: December

The basic idea behind these goals is to focus on areas where I think I can do better, so the number one goals is to focus on algorithms and data structures. After that I will shift my focus to improving my general software engineering skills: clean architecture and project delivery. Some dates are overlapping, and that is because I like to work on two projects simultaneously. Sometimes I get bored with the main project and I allow my self to be ‘distracted’ by a different project. I will do my best to finish them before the end of the year, by that time my priorities will shift, so I will definitely add something to the list by the end of the year (I hope).
 

Categories
algorithms EPICh6 kotlin

Problem 6.4 from EPI -> Advance through an array

This problem is quite interesting, at first I thought the only solution to this is using recursion or some sort of graph traversal algorithm. But the problem is much simpler than that if you think about it, we don’t care for all possible paths, we just wan to know if end is reachable. So an easier way is to just keep the maximum index we can reach, and check at the end if we reached last index. How to calculate the next maximum index? nodeMax = i + A[i]. Check out the solution here.

Categories
algorithms EPICh6 kotlin

Problem 6.2 from EPI -> Increment an arbitrary precision decimal number

This one is very cool, what if you have to implement a plus one operation to a very large number, in most languages you have that like in Java there is a BigInteger, but what if you have to write it in c++? Then you would implement your own addition, so the problem requires to implement +1 operations, which can be easily transformed into two number addition, check out the solution here.
I have also added a solution for the variation of problem 6.2. The variation requires addition of two strings that contain binary representation of two numbers. The solution is not that difficult, there is this hard coded version and a more elegant version with bitwise operations, check out the solution here.

Categories
algorithms EPICh6 kotlin

Problem 6.1 from EPI -> Variants 1,2,3

In the first variant of the problem 6.1 we have to sort an array such that all items with the same categories are grouped. If you think about it, this is the same as the pivot partition, check out the solution here.
Second variant is a bit more difficult, we need to group items that can fall into one of four categories. I used the same technique that can sort three categories but with a twist, we keep an index of group two right most item and group three left most item. When they cross it means we have solved the problem. We iterate through the array from the beginning and the end (in the three categories variant we need to just look at the items from the beginning), and keep incrementing end index (category three left most index) and beginning index (category two right most index). Check the solution here.
Third variant is quite simple, items can fall into one of two categories, we need to group them. This is easier than variant 1, we just keep an index for right most category 1 item and left most index for category 2 items and move new items into those categories. When those two indexes reach we are done. Check out the solution here.

Categories
algorithms EPICh6 kotlin

Problem 6.1 from EPI -> National Duch flag

So this one is interesting, the problem requires you to perform a crucial part of a quick sort algorithm the pivot ordering. Basically you need to pick a pivot, and move all elements that are less then the pivot to the left side of an array and bigger elements to the right side of the array. This can be done in various complexities as shown here in code. The trick with this problem is to realize you can make multiple passes for an array, it does not increase the complexity of the solution, so instead of sticking with one pass, break the algorithm into stages, and perform simpler algorithms in each stage. Those simpler algorithms combined will have a solution that works.

Categories
algorithms kotlin

Problem 5.4 from EPI -> Closest integer with the same weight

This seems like a greedy problem but its quite simple. Look at a place where you can swap 1 and 0 in the given number, the right most the location is the smaller difference will be, that is why the right most is called the least significant bit. So go from right to left and the moment you encounter two bits that differ swap them, take a look at a solution here.

Categories
algorithms kotlin

Problem 5.3 from EPI -> Reverse bits

This one is similar to computing a parity, since we need to check every bit, we can build a cache of already solved parts and just return from cache a solution exists. The key to the solution is to think about what a reverse means, it is basically last two bits reversed will be the first two bits, and second last two bits reversed will be next two bits, etc. Check out the solution here.

Categories
algorithms kotlin

Problem 5.1 from EPI -> Compute parity of a word

The solution I present here is not a complete solution, in the book there is log(n) solution which exploits the 32 bit CPU xor and shift operation. Here I am implemented the second best option which has a time complexity of (N/L), n is the word size while l is the cache size. The trick to this solution is to use a mask which can help you to extract bits, once that is done use a cache which will have an index and a value, value will be the parity of that index. While we are calculating the cache we also calculate the parity in a variable called result. Take a look at the solution here.

Categories
algorithms kotlin

Problem 5.2 from EPI -> Swap bits

The problem 5.2 is quite simple, it asks for bit swapping, so we need to check if i-th or j-th bit are different, if not no need to swap, if they are then just xor the number with 1 shifted left by i bits and 1 shifted left by j bits. Take a look at the code here.