portaldacalheta.pt
  • Põhiline
  • Planeerimine Ja Prognoosimine
  • Elustiil
  • Ux Disain
  • Finantsprotsessid
Tagumine Ots

Kotlini tutvustus: Androidi programmeerimine inimestele



Androidi täiuslikus maailmas on Java põhikeel tõeliselt kaasaegne, selge ja elegantne, rohkem tehes saate vähem kirjutada ja iga kord, kui ilmub uus funktsioon, saavad arendajad seda versiooni suurendades kasutada Gradle . Kena rakenduse loomisega tundub see funktsioon täielikult testitav, laiendatav ja hooldatav. Meie tegevused pole liiga suured ja keerulised, saame andmeallikaid andmebaasist veebi muuta ilma liigsete erinevusteta ja nii edasi. Kõlab hästi? Kahjuks pole see Android-maailmas ideaalne. Google püüdleb jätkuvalt täiuslikkuse poole, kuid me kõik teame, et ideaalmaailmu pole olemas. Seetõttu peame end sellel suurel teekonnal Androidi maailmas aitama.

Kas Kotlin saab Java-d asendada?



Kotlin on Android-maailmas peamine mängija. Kuid kas see võib Java-d asendada? Mis on Kotlin ja miks peaksite seda kasutama?

Niisiis, esimene keel. Ma arvan, et Java ei ole elegantsi ega selguse meister ning see ei ole tänapäevane ega väljendusrikas (ja oletan, et olete nõus). Negatiivne külg on see, et allpool Android N-i oleme endiselt piiratud Java 6-ga (sealhulgas mõned Java 7 väikesed osad). Arendajad saavad ka manustada RetroLambda kasutada oma koodis lambda väljendeid, mis on selle kasutamisel väga kasulikud RxJava . Lisaks Android N-le saame kasutada mõnda uuemat Java 8 funktsionaalsust, kuid see on siiski vana raske Java. Väga sageli kuulen [Androidi arendajaid] (https://www.toptal.com/android) ütlevat: 'Ma soovin, et Android toetaks kenamat keelt, nagu iOS teeb seda Swiftiga.' Mis oleks, kui ma ütleksin teile, et saate kasutada väga kena ja lihtsat keelt, nullturvalisuse, lambdade ja paljude muude funktsioonidega? Tere tulemast Kotlinisse.



Mis on Kotlin?

Kotlin on uus keel (mõnikord tuntud kui Androidi jaoks Swift), mille töötas välja meeskond aadressil JetBrains ja nüüd on see oma versioonis 1.0.2. Androidi arenduses teeb selle kasulikuks see, et see kompileerib JVM-i baidekoodiks ja saab kompileerida ka JavaScripti abil. See on täielikult ühilduv Java-ga ja Kotlini koodi saab lihtsalt teisendada Java-koodiks ja vastupidi (on olemas sisse panema autor JetBrains). See tähendab, et Kotlin saab kasutada mis tahes Java-s kirjutatud raamistikku, teeki jne. Androidis on selle integreerinud Gradle. Kui teil on olemasolev Androidi rakendus ja soovite rakendada Kotlinis uut funktsiooni kogu rakendust ümber kirjutamata, alustage lihtsalt Kotlinis kirjutamist ja see töötab.



Kuid millised on 'suured uued funktsioonid'? Lubage mul loetleda mõned:

Nimetatud ja valikuliste funktsioonide parameetrid

Fecha de crear Diversión(day: Int, month: Int, year: Int, hour: Int = 0, minute: Int = 0, second: Int = 0) { print('TEST', '$day-$month-$year $hour:$minute:$second') }

Me võime meetodit kutsuda Loomise kuupäev Erinevatel viisidel

Fechacreación(1,2,2016) prints: ‘1-2-2016 0:0:0’ Fechacreación(1,2,2016, 12) prints: ‘1-2-2016 12:0:0’ Fechacreación(1,2,2016, minute = 30) prints: ‘1-2-2016 0:30:0’

Turvalisus tühi

Kui muutuja võib olla null, siis kood ei kompileeru, kui me seda ei sunni. Järgmisel koodil on viga: tühistatav Var võib olla null:



var nullableVar: String? = “”; nullableVar.length;

Koostamiseks peame kontrollima, kas see on null või mitte:

if(nullableVar){ nullableVar.length }

Või isegi lühem:



nullableVar?.length

Nii, kui nullableVar on null, ei juhtu midagi. Vastasel juhul võime muutuja märkida tühiseks, ilma tüübi järel küsimärgita:

var nonNullableVar: String = “”; nonNullableVar.length;

See kood on kompileeritud ja kui tahame mitte-NullableVar'ile omistada nulli, näitab kompilaator viga.



Elvise operaator on ka väga kasulik:

var stringLength = nullableVar?.length ?: 0

Nii et kui nullableVar on null (nii nullableVar?. Pikkus annab tulemuseks null), on stringLength väärtus 0.



Muutuvad ja muutumatud muutujad

Ülaltoodud näites kasutan kus muutuja määratlemisel. See on muutlik, me saame selle igal ajal uuesti määrata. Kui tahame, et see muutuja oleks muutumatu (paljudel juhtudel peaksime), siis kasutame tunnid (väärtusena, mitte muutujana):

mis keeles on rubiin kirjutatud
val immutable: Int = 1

Pärast seda ei luba kompilaator meil muutumatut ümber teha.



Lambdas

Me kõik teame, mis on lambda, nii et siin näitan, kuidas saame seda Kotlinis kasutada:

button.setOnClickListener({ view -> Log.d('Kotlin','Click')})

Või kui funktsioon on ainus või viimane argument:

button.setOnClickListener { Log.d('Kotlin','Click')}

Laiendused

Laiendused on väga kasulik keelefunktsioon, tänu millele saame olemasolevaid klasse 'pikendada' isegi siis, kui need on lõplikud või meil pole juurdepääsu nende lähtekoodile.

Näiteks redigeeritava tekstistringi väärtuse saamiseks võime selle asemel, et kirjutada editText.text.toString () iga kord, kui kirjutame funktsiooni:

fun EditText.textValue(): String{ return text.toString() }

Või isegi lühem:

fun EditText.textValue() = text.toString()

Ja nüüd, iga juhtumiga EditText :

editText.textValue()

Või võime lisada atribuudi, mis tagastab sama:

var EditText.textValue: String get() = text.toString() set(v) {setText(v)}

Operaatori ülekoormus

Mõnikord on see kasulik, kui tahame objekte lisada, korrutada või võrrelda. Kotlin lubab üle koormata: binaaroperaatoreid (pluss, miinus, plusAssign, vahemik jne), massiivioperaatoreid (get, set, get range, set range) ning võrdseid ja unaarseid toiminguid (+ a, -a jne.) .

Andmeklass

Mitu koodirida on vaja Java-kasutajaklassi juurutamiseks kolme atribuudiga: copy, equal, hashCode Y toString ? Kotlinis vajate ainult ühte rida:

Usuario de Clase de Datos(nombre del val: String, apellido del val: String, edad del val: Int)

See andmeklass pakub võrdseid (), hashCode () ja copy () meetodeid toString (), mis prindib Kasutaja järgmiselt:

Usuario(nombre=John, apellido=Doe, edad=23)

Andmeklassid pakuvad ka muid kasulikke funktsioone ja omadusi, mida saab näha Kotlini dokumentatsioonis.

Anko pikendused

Kasutage Võinuga või Androidi laiendused, eks? Mis siis, kui te ei pea seda teeki isegi kasutama ja pärast vaadete deklareerimist XML-is kasutate seda lihtsalt koodi järgi ID-ga (nagu C # -ga XAML-i puhul):

loginBtn.setOnClickListener{} import kotlinx.android.synthetic.main.activity_main.*

Kotlinil on väga kasulikud [Anko laiendused] (https://github.com/Kotlin/anko) ja sellega pole vaja tema tegevusele öelda, mis see on loginBtn , teate seda lihtsalt xml-i 'importimisega':

graafiline kommunikatsioon ja graafiline disain
interface CreateUserView : View { fun showEmptyNameError() /* show error when name is empty */ fun showEmptySurnameError() /* show error when surname is empty */ fun showUserSaved() /* show user saved info */ fun showUserDetails(user: User) /* show user details */ }

Ankol on palju muud kasulikku, sealhulgas alustajad, keskmised tegevused jne. See pole Anko peamine eesmärk - see on loodud hõlpsalt koodipaigutuste loomiseks. Nii et kui peate looma programmeerimispaigutuse, on see parim viis.

See on vaid lühike ülevaade Kotlinist. Soovitan lugeda Antonio Leiva ajaveebi ja tema raamatut - Kotlin Androidi arendajatele ja muidugi ametlik Kotlini sait.

Mis on MVP ja miks?

Kena, jõuline ja selge keel ei ole piisav. Kõigi keeltega räpaseid rakendusi on väga hea ilma hea arhitektuurita kirjutada. Androidi arendajad (peamiselt need, kes alles alustavad, aga ka edasijõudnumad) lasevad tegevusel sageli vastutada kõige ümbritseva eest. Tegevus (või jupp või muu vaade) laadib alla andmed, salvestab need saatmiseks, esitleb neid, reageerib kasutajate interaktsioonidele, redigeerib andmeid ja haldab kõiki alamvaateid. . . Ja mitu korda palju rohkem. See on liiga ebastabiilsete objektide jaoks nagu Tegevused või Fragmendid (lihtsalt pöörake ekraani ja tegevuses öeldakse 'Nägemist ...').

Väga hea mõte on eraldada arvamuste vastutus ja muuta need võimalikult rumalateks. Vaated (tegevused, sisulõigud, kohandatud vaated või mis tahes muu teave kuvab ekraanil) peaksid vastutama ainuisikuliselt nende allvaadete haldamise eest. Vaadetel peaksid olema saatejuhid, kes suhtlevad modelliga ja ütlevad neile, mida teha. Lühidalt öeldes on see muster Mudel-vaade-ettekandja (minu jaoks peaks see olema nimi Mudel-saatejuht-vaade kihtide vaheliste seoste näitamiseks).

MVC vs MVP

'Hei, ma tean midagi sellist ja selle nimi on MVC!' - kas sa ei arva? Ei, MVP ei ole sama mis MVC. MVC mustris saab teie vaade mudeliga suhelda. MVP-i kasutamise ajal ei luba te nende kahe kihi vahel ainsat viisi suhelda Vaade saab suhelda Mudel on läbi Saatejuht . Ainus, mis Vaade teada Mudel see võib olla andmete struktuur. Vaade oska näiteks näidata Kasutaja , kuid ei tea, millal. Siin on lihtne näide:

Vaatepilt teab, et „ma olen tegevus, mul on kaks EditTexts ja nuppu. Kui keegi nuppu klõpsab, pean selle oma saatejuhile ütlema ja edastan väärtused EditTexts . Ja see selleks, ma saan magada järgmise klõpsuni või saatejuht ütleb, mida teha ”.

Saatejuht ta teab, et kusagil on vaade, ja teab, milliseid toiminguid see vaade saab teha. Samuti teate, et kui saate kaks stringi, peate looma kasutaja nendest kahest stringist ja saatma andmed salvestamiseks mudelisse ning kui see salvestub edukalt, öelge vaade 'Kuva eduteave'.

Mudel teab ainult seda, kus andmed asuvad, kuhu need tuleb salvestada ja milliseid toiminguid tuleb andmetega teha.

MVP-s kirjutatud rakendusi on lihtne testida, hooldada ja uuesti kasutada. Puhas saatejuht ei tohiks Androidi platvormist midagi teada. See peab olema puhas Java (või meie puhul Kotlini) klass. Tänu sellele saame oma saatejuhti taaskasutada teistes projektides. Samuti saame hõlpsalt kirjutada ühikutestid, testides eraldi Mudel , Vaade Y Saatejuht .

MVP muster viib parema ja vähem keeruka koodibaasini, hoides kasutajaliidese ja äriloogika tõeliselt lahus.

Väike kõrvalepõige: MVP peaks olema osa sellest Onu Bobi puhas arhitektuur muuta rakendused veelgi paindlikumaks ja hästi kujundatud. Püüan sellest järgmine kord kirjutada.

Näidisrakendus koos MVP ja Kotliniga

See on piisavalt teooria, vaatame mõnda koodi! Proovime luua lihtsa rakenduse. Selle rakenduse peamine eesmärk on kasutaja loomine. Esimesel ekraanil on kaks EditTexti (esimene ja viimane) ja nupp (Salvesta). Pärast ees- ja perekonnanime sisestamist ning nupule „Salvesta“ klõpsamist peaks rakendus kuvama „Kasutaja on salvestatud“ ja minema järgmisele ekraanile, kus kuvatakse salvestatud ees- ja perekonnanimi. Kui ees- või perekonnanimi on tühi, ei tohiks rakendus kasutajat salvestada ja siis kuvatakse viga, mis näitab valet.

Esimene asi, mida teha pärast projekti loomist Android Studio on Kotlini konfigureerimine. Sa peaksid installige Kotlini pistikprogramm ja pärast taaskäivitamist klõpsake menüüs Tööriistad> Kotlin nuppu 'Konfigureeri Kotlin projektis'. IDE lisab Gradle'i Kotlini sõltuvused. Kui teil on olemasolevat koodi, saate selle hõlpsasti teisendada Kotliniks (Ctrl + Tõst + Alt + K või Kodeerimine> Teisenda Java-fail Kotliniks). Kui midagi ei toimi ja projekti ei kompileerita või Gradle Kotlinit ei näe, saate kontrollida GitHubis saadaolevat rakenduse koodi.

Kotlin mitte ainult ei toimi hästi Java-raamistike ja teekidega, vaid võimaldab jätkata enamiku samade tööriistade kasutamist, mis on teile juba tuttavad.

Nüüd, kui meil on projekt, alustame esimese vaate loomisega: Kasutajavaate loomine . Sellel vaatel peavad olema eespool nimetatud funktsioonid, nii et saame selle jaoks kirjutada liidese:

interface View

Nagu näete, on Kotlin funktsioonide deklareerimisel sarnane Java-ga. Kõik on funktsioonid, mis ei tagasta midagi ja viimastel on parameeter. See on erinevus, parameetri tüüp tuleb nime järele. Kuva liides pole Android: see on meie lihtne ja tühi liides:

interface Presenter { var view: T? fun onDestroy(){ view = null } }

Kasutajaliides Saatejuht Basicul peab olema tüübivaate omadus ja vähemalt meetodis (näiteks onDestroy), kus selle atribuudi väärtuseks määratakse null:

interface CreateUserPresenter: Presenter { fun saveUser(name: String, surname: String) }

Siin näete veel ühte Kotlini funktsiooni: saate deklareerida liideste omadusi ja rakendada seal ka meetodeid.

Meie CreateUserView vajadus suhelda CreateUserPresenter . Ainus lisafunktsioon, mida see saatejuht vajab saveUser kahe stringi argumendiga:

data class User(val name: String, val surname: String)

Vajame ka mudeli määratlust - seda on klassitüübis varem mainitud:

class CreateUserPresenterImpl(override var view: CreateUserView?): CreateUserPresenter { override fun saveUser(name: String, surname: String) { } }

Pärast kõigi liideste deklareerimist saame hakata rakendama.

CreateUserPresenter rakendatakse aastal CreateUserPresenterImpl :

CreateUserPresenterImpl(override var view: CreateUserView?)

Esimene rida koos klassi määratlusega:

class MainActivity : AppCompatActivity(), CreateUserView { private val presenter: CreateUserPresenter by lazy { CreateUserPresenterImpl(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) saveUserBtn.setOnClickListener{ presenter.saveUser(userName.textValue(), userSurname.textValue()) /*use of textValue() extension, mentioned earlier */ } } override fun showEmptyNameError() { userName.error = getString(R.string.name_empty_error) /* it's equal to userName.setError() - Kotlin allows us to use property */ } override fun showEmptySurnameError() { userSurname.error = getString(R.string.surname_empty_error) } override fun showUserSaved() { toast(R.string.user_saved) /* anko extension - equal to Toast.makeText(this, R.string.user_saved, Toast.LENGTH_LONG) */ } override fun showUserDetails(user: User) { } override fun onDestroy() { presenter.onDestroy() } }

See on konstruktor, me kasutame seda liideses määratletud vaate atribuudi määramiseks.

MainActivity , mis on meie oma CreateUserView rakendamine vajab viidet CreateUserPresenter :

private val presenter: CreateUserPresenter by lazy { CreateUserPresenterImpl(this) }

Näite alguses määratleme oma saatejuhi:

override fun saveUser(name: String, surname: String) { val user = User(name, surname) when(UserValidator.validateUser(user)){ UserError.EMPTY_NAME -> view?.showEmptyNameError() UserError.EMPTY_SURNAME -> view?.showEmptySurnameError() UserError.NO_ERROR -> { UserStore.saveUser(user) view?.showUserSaved() view?.showUserDetails(user) } } }

See on määratletud muutumatuna (val) ja selle on loonud laisk delegaat, kellele määratakse esmakordne vajadus. Teisalt oleme kindlad, et see ei ole null (definitsiooni järel pole küsimärki).

Kui kasutaja klõpsab nuppu Salvesta, saadab vaade Presenteri teabe EditTexts väärtustega. Kui see juhtub, tuleb kasutaja salvestada, seega peame Presenteris rakendama meetod saveUser (ja mõned mudeli funktsioonid):

enum class UserError { EMPTY_NAME, EMPTY_SURNAME, NO_ERROR } object UserStore { fun saveUser(user: User){ //Save user somewhere: Database, SharedPreferences, send to web... } } object UserValidator { fun validateUser(user: User): UserError { with(user){ if(name.isNullOrEmpty()) return UserError.EMPTY_NAME if(surname.isNullOrEmpty()) return UserError.EMPTY_SURNAME } return UserError.NO_ERROR } } Lo más interesante aquí es *UserValidator.* Mediante el uso de la palabra objeto, podemos crear una clase *Singleton*, sin preocupaciones de hilos, constructores privados y así sucesivamente. Adicionalmente: en el método validateUser (usuario), existe con (usuario) {} expresión. El código dentro de dicho bloque se ejecuta en contexto de objeto, se pasa con el nombre y el apellido son las propiedades del Usuario. También hay otra pequeña cosa. Todo el código anterior, de enum a *UserValidator*, la definición se coloca en un archivo (la definición de clase de usuario también está aquí). Kotlin no te obliga a tener cada clase pública en un solo archivo (o nombre de la clase exactamente como archivo). Por lo tanto, si tienes algunos fragmentos cortos de código relacionados con (clases de datos, extensiones, funciones, constantes - Kotlin no requiere clase para función o constante), puedes colocarlos en un solo archivo en lugar de propagarlos a través de todos los archivos del proyecto. Cuando un usuario se guarda, nuestra aplicación debería mostrarlo. Necesitamos otra vista: puede ser cualquier vista de Android, vista personalizada, fragmento o actividad. Elige la Actividad. Por lo tanto, vamos a definir la interfaz de*UserDetailsView*. Puede mostrar al usuario, pero también debe mostrar un error cuando el usuario no está presente: ~~~ kotlin interface UserDetailsView { fun showUserDetails(user: User) fun showNoUserError() }

Kui kasutaja on loodud, saadetakse see kasutajale UserValidator selle kehtivuse kontrollimiseks. Seejärel kutsutakse valideerimise tulemuse põhjal sobiv meetod. Konstruktsioon When () {} on sama, mis Java / switch / case. Kuid see on võimsam - Kotlin lubab kasutada „juhul” mitte ainult enumit või int, vaid ka vahemikke, stringe või objektitüüpe. Peab sisaldama kõiki võimalusi või omama avaldist. Seejärel katke kõik UserErrori väärtused.

Vaate kasutamisel? .showEmptyNameError () (küsimärgiga pärast vaadet) kaitseme end selle eest NullPointer Vaate saab meetodil tühistada hävitage , ja selle konstruktsiooniga ei juhtu midagi.

Kui kasutajamudelil pole vigu, ütleb ta UserStore salvestage see ja seejärel käskige vaade, et näidata edu ja näidata üksikasju.

Nagu eespool mainitud, peame rakendama mõningaid olulisi asju:

interface UserDetailsPresenter: Presenter { var user: User? }

Järgmine on UserDetailsPresenter. Sellel peaks olema kasutaja omadus:

class UserDetailsPresenterImpl(override var view: UserDetailsView?): UserDetailsPresenter { override var user: User? = null set(value) { field = value if(field != null){ view?.showUserDetails(field!!) } else { view?.showNoUserError() } } }

See liides rakendatakse aastal UserDetailsPresenterImpl . Peate kasutaja vara üle kirjutama. Iga kord, kui see atribuut määratakse, tuleb kasutajat vaates värskendada. Saame kasutada a setter vara selle jaoks:

class UserDetailsActivity: AppCompatActivity(), UserDetailsView { private val presenter: UserDetailsPresenter by lazy { UserDetailsPresenterImpl(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user_details) val user = intent.getParcelableExtra(USER_KEY) presenter.user = user } override fun showUserDetails(user: User) { userFullName.text = '${user.name} ${user.surname}' } override fun showNoUserError() { toast(R.string.no_user_error) finish() } override fun onDestroy() { presenter.onDestroy() } }

Rakendamine UserDetailsView , UserDetailsActivity , See on väga lihtne. Nagu varemgi, on meil ka laisa laadimisega loodud saatejuht. Kasutaja peab kuvamisel olema läbitud tahtlikult. Praegu on sellega väike probleem ja me lahendame selle hetkega. Kui meil on tahtlik kasutaja, peab View selle määrama oma saatejuhile. Pärast seda värskendatakse kasutajat ekraanil või kui see on null, ilmub viga (ja tegevus lõpeb, kuid saatejuht ei tea):

anular divertido showUserDetails(usuario: Usuario) { startActivity(USER_KEY to user) /* extensión anko – empieza UserDetailsActivity y pasa el usuario a USER_KEY in intent */ }

Objektide edastamine kavatsuste kaudu nõuab, et see objekt rakendaks liidest Parcelable. See on väga 'räpane' töö. Isiklikult ma vihkan seda teha kõigi loojate, kinnisvara, säästude, restaureerimise jms tõttu. Õnneks on olemas sisse panema sobib, pakendatav Kotlinile. Pärast selle installimist saame paki luua vaid ühe klõpsuga.

Viimane asi, mida peame tegema, on rakendamine showUserDetails (kasutaja: kasutaja) meie põhitegevuses:

|_+_|

Ja see ongi kõik.

Demo Androidi rakendus Kotlinis

Meil on lihtne rakendus, mis salvestab kasutaja (pole tegelikult salvestatud, kuid saame selle funktsiooni lisada ilma saatejuhti või vaadet puudutamata) ja esitage see ekraanil. Tulevikus, kui soovime muuta seda, kuidas kasutaja ekraanil kuvatakse, näiteks: kaks tegevust ühes tegevuses kaheks fragmendiks või kaks kohandatud vaadet; muudatusi nähakse ainult vaate klassides. Muidugi, kui me ei muuda mudeli funktsionaalsust ega struktuuri. Saatejuht, kes täpselt ei tea, mis View on, ei vaja muudatusi.

Kas teil on probleeme oma Android-rakenduste arendamisega? Vaadake neid optimeerimisnõuandeid ja -võtteid.

Mis järgmiseks?

Meie rakenduses luuakse Presenter iga kord, kui mõni tegevus on loodud. See ettekujutus või vastupidi, kui ettekandja soovib püsida ka aktiivsete juhtumite kaudu, on kogu Internetis palju arutelusid pakkuv teema. Minu jaoks sõltub see rakendusest, selle vajadustest ja arendajast. Mõnikord on parem saatejuht hävitada, mõnikord mitte. Kui otsustate ühe jätkata, on kasutada väga huvitavat tehnikat LoaderManager Selle eest.

Nagu eespool mainitud, peab MVP olema osa Onu Bobi puhas arhitektuur . Teisalt peaksid head arendajad kasutama Pistoda süstida tegevusse saatejuhi sõltuvusi. Samuti aitab see teie koodi hooldada, testida ja tulevikus uuesti kasutada. Praegu töötab Kotlin väga hästi Daggeriga (enne ametlikku väljaandmist polnud see nii lihtne) ja ka teiste kasulike Androidi raamatukogudega.

järeldus

Minu jaoks on Kotlin suurepärane keel. See on kaasaegne, selge ja väljendusrikas, samas kui seda arendavad endiselt suured inimesed. Ja me võime kasutada mis tahes uut versiooni mis tahes Android-seadmes ja -versioonis. Mis mind Java-s vihaseks ajab, Kotlin teeb selle paremaks.

kuidas koostada tarkvaraprojekti dokumentatsiooni

Muidugi, nagu ma ütlesin, pole miski ideaalne. Kotlinil on ka mõned varjuküljed. Gradle'i pistikprogrammide uuemad versioonid (peamiselt alfa või beeta) ei tööta selles keeles hästi. Paljud inimesed kurdavad, et koostamisaeg on natuke pikem kui puhas Java ja apksidel on mõned täiendavad MB-d. Sellest hoolimata Android Studio Y Gradle Need muutuvad aina paremaks ja telefonides on üha rohkem ruumi rakendustele. Seetõttu arvan, et Kotlin võib olla kõigile Androidi arendajatele väga kena keel. Proovige lihtsalt ja jagage oma arvamust allpool olevas kommentaaride jaotises.

Näidisrakenduse lähtekood on saadaval aadressil Github .

Tuleviku toitmine: ülevaade põllumajandusliku toiduainete tehnoloogiast

Investorid Ja Rahastamine

Tuleviku toitmine: ülevaade põllumajandusliku toiduainete tehnoloogiast
Põhjalik teatiste kujundamise juhend

Põhjalik teatiste kujundamise juhend

Mobiilne Disain

Lemmik Postitused
Serveripoolsete renderdatud Vue.js-rakenduste loomine Nuxt.js-i abil
Serveripoolsete renderdatud Vue.js-rakenduste loomine Nuxt.js-i abil
HTTP-päringute testimine: arendaja ellujäämisriist
HTTP-päringute testimine: arendaja ellujäämisriist
Bridgewateri Ray Dalio: Big Data, masinõppe ja Fintechi vaikne pioneer
Bridgewateri Ray Dalio: Big Data, masinõppe ja Fintechi vaikne pioneer
Magento 2 õpetus: kuidas moodustada terviklikku moodulit
Magento 2 õpetus: kuidas moodustada terviklikku moodulit
Välja tasemel rööbaste vahemälu valideerimine: DSL-i lahendus
Välja tasemel rööbaste vahemälu valideerimine: DSL-i lahendus
 
Sisuka UX-i disaini kunst
Juhend kasutajate tõhusaks kasutuselevõtuks parimate tavade kohta
Juhend kasutajate tõhusaks kasutuselevõtuks parimate tavade kohta
Disainilitsents pole lahendus
Disainilitsents pole lahendus
Liitreaalsuse vs. Virtuaalne reaalsus vs. Segareaalsus: sissejuhatav juhend
Liitreaalsuse vs. Virtuaalne reaalsus vs. Segareaalsus: sissejuhatav juhend
Mis on PMO? Juhend projektijuhtimise kontorisse
Mis on PMO? Juhend projektijuhtimise kontorisse
Lemmik Postitused
  • kuidas discordi robotit kasutada
  • node js veebirakenduse näide
  • mis vahe on s-korporatsioonil ja c-korporatsioonil
  • Fintechi mõju pankadele
  • erinevus s ja c corp
  • mis on pmo kontor
Kategooriad
  • Planeerimine Ja Prognoosimine
  • Elustiil
  • Ux Disain
  • Finantsprotsessid
  • © 2022 | Kõik Õigused Kaitstud

    portaldacalheta.pt