Rozpoczęcie implementacji, różnice pomiędzy aplikacją a biblioteką – DSP#04

Czwarty wpis w ramach konkursu a tak naprawdę dopiero zaczynamy tworzenie kodu. Cóż, jak pisałem poprzednio projekt jest malutki i jednym z moich celów jest skończyć go i zrobić jako „prawdziwy open source”. Dlatego nie skupię się na ilości, ale raczej jakości, dokumentacji i promocji. Ale małymi kroczkami, zacznijmy od utworzenia nowego projektu..

Rozpoczęcie implementacji biblioteki nie stanowi wielkiej filozofii: File -> New -> New project. Projekt nazwę DayViewDemo, z kolei pakiet będzie nosił nazwę digitalzombielab, tak jak moje konto w sklepie Play.

Rozpoczęcie implementacji, różnice pomiędzy aplikacją a biblioteką

Kolejnym krokiem jest utworzenie modułu, który będzie naszym docelowym projektem, czyli biblioteką android.

Rozpoczęcie implementacji, różnice pomiędzy aplikacją a biblioteką

Czyli klikamy File -> New -> New module i z listy dostępnych wybieramy Android library. Co nowego czego nie było w aplikacji pojawia się po tych modyfikacjach. Po pierwsze plik settings.gradle zawiera teraz dwa moduły.

include ':app', ':dayview'

Dodatkowo pojawił się nowy plik build.gradle, który jest niemalże identyczny (nie posiada załączonej biblioteki do layoutu, oraz support design) jak ten sam plik z modułu app.

Rozpoczęcie implementacji, różnice pomiędzy aplikacją a biblioteką

Na powyższym zrzucie widać również różnicę w strukturach katalogów, moduł biblioteki nie zawiera np layoutu, ani menu. Plik manifestu w libce również jest krótszy, ponieważ nie zawiera żadnej aktywności, wygląda w ten sposób.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="pl.digitalzombielab.dayview">

    <application android:allowBackup="true" android:label="@string/app_name"
        android:supportsRtl="true">

    </application>

</manifest>

Zajrzyjmy teraz do kodziku aktywności, a tam.. Java. 53 linie które generują się na początku każdego projektu. Uruchomienie aktywności, obsługa layoutu, menu, etc.. A miał być Kotlin. Z racji tego, że nie lubię bezsensownej roboty nie będę przepisywał auto-wygenerowanego kodu. Skrót ctrl+shift+a daje nam dostęp do czegoś, co nazwano „akcje”, czyli możemy sobie stamtąd uruchomić jakieś funkcje naszego IDE, etc.. Wpisuje plugins, i wyszukuję w otwartym okienku Kotlina.

Rozpoczęcie implementacji, różnice pomiędzy aplikacją a biblioteką

Instaluję wtyczkę, restartuję intelliJ. To dobry moment na zapisanie zmian, dlatego włączam kontrolę wersji i wrzucam pliki do „first commit”. I po tych czynnościach naciskam kombinację klawiszy Ctrl+Alt+Shift+K i dzieje się magia, klasa javowa konwertuje się do Kotlina i daje nam taki rezultat.

package pl.digitalzombielab.dayviewdemo

import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.View
import android.view.Menu
import android.view.MenuItem

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val toolbar = findViewById(R.id.toolbar) as Toolbar
        setSupportActionBar(toolbar)

        val fab = findViewById(R.id.fab) as FloatingActionButton
        fab.setOnClickListener { view ->
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        val id = item.itemId


        if (id == R.id.action_settings) {
            return true
        }

        return super.onOptionsItemSelected(item)
    }
}

Z racji tego, że Kotlin pracuje na jvm, możemy w ramach jednego projektu łączyć klasy Javy i Kotlina, ale akurat tutaj nie będziemy tego robić. Bieżące zmiany zostały zaccomitowane jako „auto convert to Kotlin”.

Próbujemy uruchomić aplikację i.. nie uruchamia się. Brakuje jeszcze jednej rzeczy, skonfigurowania Kotlina w projekcie. Aby to zrobić ponownie uruchamiamy akcje, wpisujemy „Configure Kotlin in Project” wyskoczy nam okienko w którym ja wybieram wszystkie moduły, ponieważ chcę aby zarówno demo jak i biblioteka pracowały z Kotlinem.

Rozpoczęcie implementacji, różnice pomiędzy aplikacją a biblioteką

Po tej operacji odrobinę zmieniają nam się pliki gradle, tzn w modułach aplikacji i biblioteki dochodzi

apply plugin: 'kotlin-android'

...

    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}
repositories {
    mavenCentral()
}

Z kolei w głównym pliku gradle dla projektu

buildscript {
    ext.kotlin_version = '1.1.1'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

To wszystko co musimy zrobić. Po kliknięciu przycisku debug aplikacja się nam uruchomi, tym razem już bez niespodzianek. Bieżące zmiany zostały zaccomitowane jako „configure Kotlin in project”.

To by było tyle na dzisiaj, udało nam się skonfigurować środowisko pod pracę z Kotlinem, a następnym razem będzie trochę więcej mięska, bo zaczniemy implementację biblioteki i przyjrzymy się trochę temu, jak wygląda ten język. A jest na co popatrzeć 😉