Home » Approfondimenti » Computer Science » Kotlin – Android app
  []

  1. Preview
  2. IDE
  3. Linguaggio Kotlin
  4. Package
  5. POO
  6. Android
  7. Gestione del layout
  8. Android Studio

 

Preview

  • Caratteristiche principali =>
    • Nato nel 2011 grazie a JetBrains (Praga – 2000)
      • IntelliJ IDEA (IDE per Java)
    • Statically-typed language
      • Se definisco una variabile string non posso dargli un valore boolean (per esemipo). Infatti una volta lanciata la compilatore riceverei un errore.
      • Kotlin permette in questo modo di scrivere programmi più affidabili.
    • Compilazione
      • Bytecode => 
        • Eseguito in una JVM (Java virtual machine).
        • Utilizzato quindi lato server (es: il backend di un sito web)
      • Javascript =>
        • Utilizzato quindi lato client
      • Android
    • Differeneze con Java
      • Più sicuro perché capta una serie di errori direttamente alla compilazione 
      • Più conciso
        • //Nuova classe
          data class Person(var name: String, var age: Int)
      • Compatibile
        • Con tutte le versioni di Android.
        • Con quasi tutte le librerie Java esistenti.
        • E’ possibile nella stessa applicazione scrivere delle pagine in Java e in Kotlin
    • Ufficialmente supportato da Google.
    • Supporta Android Studio.
  • Installazione (su Windows) =>
    • Android Studio (developer.android.com)
      • Android SDK
      • Emulatore
      • Intel x86 Emulator Accelerator (HAXM installer)
    • USB Driver (per connettere il telefono al computer)
  • Interoperabilità con Java
    • Da un file kotlin é possibile chiamare una classe Java et viceversa

 

IDE

  • Shortcut
    • Ctrl+Shift+A (Apre una finestra per trovare tutti i differenti shortcut offerti dall’IDE)
  • Tab
    • Logcat (equivale a output in Visual Studio)
    • Profiler
      • Mostra l’utilizzo di risorse nel device connesso dove la nostra applicazione é stata deploiata e eseguita.
  • Emulatore Android
    • E’ un programma che si esegue sulla macchina di sviluppo e replica un sistema android.
    • Permette il deploy dell’applicazione da installare più rapida.
    • L’emulatore permette di:
      • Testare l’applicazione su differenti ‘form factors‘ (dimensioni del monitor).
      • Testare l’applicazione su differenti versioni di Android.
  • Creare nuovo emulatore
    • Proprietà
      • Nome
      • Play Store (si o no)
        • Tips:
          • Ccegliere un’immagine che non contiene il Google ‘Play Store’ se si vuole avere un’ampia capacità di configurare il proprio emulatore.
          • Nelle immagini con il Google ‘Play Store’ disponibile le configurazioni possibili sono più limitate.
      • Dimensione del monitor
      • Risoluzione
        • Tips: puo’ essere utile selezionare una risoluzione simile a quella del computer di sviluppo per vedere meglio).
      • Densità
    • Immagine di sistema
      • Scegliere quale versione di Android usare nell’emulatore che stiamo creando.
      • Proprietà
        • Nome
        • API Level (nome tecnico della versione Android)
        • ABI (Application Binary Interface)
          • Architettura del processore sul quale l’emulatore viene eseguito.
          • es: x86 o x64.
          • Tips : puo’ essere utile usare la stessa architettura del computer di sviluppo
        • Nome commerciale della versione Android target.
  • Connettere un device fisico
    • 1 – Trovare la versione Android presente nel device fisico che si vuole usare
    • 2 – Sbloccare la modalità sviluppatore
      • 3 – Cliccare più volte sul ‘Parametri’ => ‘Sistema’ => ‘Informazione sul telefono’ => ‘Build Number’
        • Voce di menuù ‘Opzioni di sviluppo
      • Nel menù ‘Parametri’ ora deve esserci un’opzione menu’ in più
        • 4- Attivare Debug USB

 

Linguaggio Kotlin

  • Dichiarazione variabili =>
    • var age: Int = 45 
      var name: String = "John" 
      var height: Float = 1.60F
    • Number (variabile generica di tipo numberico che puo’ essere una qualsiasi dei tipi seguenti)
      • Byte (-128, +127)
      • Short
      • Int
      • Long
      • Float (es: 42.5F)
      • Double (es: 42.5)
    • Char (es: ‘a’)
    • String (es: “Helllo”)
      • String template simple
        • //scrivo nella console (tab 'Run' dell'IDE)
          println("String template simple : $name ha $age anni")
      • String template complex
        • //!! Posso fare delle operazioni all'interno delle parentesi graffe !!
          println("String template complex : ${name.uppercase()} ha ${age*2} anni")
        • Raw string (“””)
          • //E' possibile scrivere del testo su più linee
            //Devo stare attento agli spazi che metto perché saranno visibili nel mio testo
            println("""String template complex:
            Name : $name
            Age  : $age""")
        • Raw string tim (“”” |)
          • trimMargin()
            //Usando il simbolo pipe (|) per ogni nuova riga 
            // risolvo il problema degli spazi vuoti usati solo per indentare meglio
            println("""String template complex trim: 
                    |Name : $name
                    |Age : $age
                    |""".trimMargin())
            
            marginPrefix
            /posso customizzare il carattere che indica l'inizio della nuova riga della mia stringa raw
            println("""String template complex trim: 
                    >Name : $name
                    >Age : $age
                    >""".trimMargin(">"))
  • Operatori logici
    • Operatore di confronto valore (==)
    • //contronto tra valori
      //diverso da Java
      if(name == "bob'){
      } else if (){
      } else {
      }
    • Operatore di confronto referenza (===)
    • //contronto tra indirizzi di memoria
      if(name === "bob'){
      }
    • Operatore ternario
      • val type = if (age < 18) "child" else "adult"
    • When (lo switch di C#)
      • Permette il pattern matching 
      • when(age) {
          5 ->
          10 ->
          else -> 
        }
        
        oppure
        
        when {
           age == 5 ->
           height >= 1.50f ->
           else -> 
        }
        
        oppure
        
        when(age) {
         in 1..5 -> println("${name} é troppo giovane")
         in 6..10 -> println("${name} puo' giocare a basket")
         !in 1..18 -> println("${name} non puo' giocare con i giovani") 
         else -> println("condizione non gestita")
        }
        
        var canPlayBasketball = when (age) {
         in 1..5 -> true
         else -> false
        }
  • Mutabilità di una variabile
    • var => variabile puo’ cambiare valore.
    • val (final in Java) => la variabile NON puo’ cambiare valore.
      • Permette di rendere il codice più robusto
  • Nullabilità (?)
    • Per poter dare il valore null ad una variabile é necessario dichiararla con il punto ? (come in C#)
    • var name: String? = "Bob"
      name = null
      
      //Come usare una variabile null
      //1 - Fare un test se la variabile é nulla
      if(name != null) {
         println(name.length); 
      }
      
      //2 - Operatore safe call (come C#)
      //l'applicazione non dà errore nel caso name=null
       println(name?.length); 
      
      //3 - Operatore assert not-null (simile C#)
      //posso forzare il compilatore a ignorare il caso NULL => la variabile avrà sicuramente un valore
      //l'applicazione dà errore nel caso invece name=null
       println(name!!.length);
  • Funzioni
    • E’ possibile dichiarare delle funzioni fuori di una classe 
    • fun name(age : int, p2...): TypeRetour {
      }
      
      //senza ritorno
      fun name(age : int, p2...) {
      }
  • Lambda expression (=)
    • //Se la funzione ha una sola linea é possibile utilizzare una sintassi simile alle labda expression di C#
      //Mettendo = al posto di => e senza usare la parola chiave return
      fun CanPlayBasket(age: Int) : Boolean = (age>15)
  • Array
    • L’indice di base é 0 
    • Definire un array di taglia fissa
      
      //Metodo 1 - Uso il costruttore 'Array'
      val ages = Array<Int>(10) { 0 }  //0, 0, 0, 0, 0, 0, 0, 0, 0, 0
      
      //Metodo 2 - Uso la factory 'arrayOf'
      //Da usare se si conosco già tutti gli elementi dell'array
      //ho definito un array di interi lungo 3
      val ages = arrayOf(4, 7, 15)    //4, 7, 15
      
      // Recuperare un valore
      var myage = ages.get(index) 
      
      // Modificare un valore
      ages.set(index, value) 
      oppure
      ages[index} = value
      
      //Display tutti gli elementi di un array
      Arrays.toString(myArray)
  • For 
    • //senza indicare esplicitamente step, il contatore avanza di 1
      for (i in 1..5) {
         println(i)  //1, 2, 3, 4, 5
      }
      
      //step
      //nell'esempio il contatore avanza di 2
      for (i in 1..5 step 2) {
         println(i) //1, 3, 5
      }
      
      //downTo
      //nell'esempio il contatore indietreggia di 1
      for (i in 5 downTo 1) {
         println(i) //5, 4, 3, 2, 1
      }
      
      //downTo + step
      //nell'esempio il contatore indietreggia di 2
      for (i in 5 downTo 1) {
         println(i) //5, 3, 1
      }
      
  • For each / continue (come C#)
    • for(item in colleciton)
      {
         if(condition)
            continue
      }
      
      var name = arrayOf("Bob", "John", "Rosy");
      for((index,name) in names.withIndex())
      {
         println("$name é all'indice $index")
      }
  • While / Break (come C#)
    • while(condition)
      {
         ..
      }
      
      do 
      {
        ..
      }
      while(condition)

 

Package

  • Una serie di file contenuti in una stessa cartella
    • Creare un nuovo package (verrà creata una cartella con il nome scelto)
    • Aggiungere a tale package i file desiderati (i file verranno aggiunti fisicamente alla cartella constituente il package)
      • File
      • Class
  • Dichiarazione
    • //aggiungo un file (package) con delle funzioni utility da usare negli altri package
      //questo file lo metto in una cartela 'common'
      package com.example.helloword.nico.common
  • Visibilità
    • package com.example.helloword.nico.common
      
      //Caso 1 (default)
      //name é visibile in tutti gli altri package (file sorgente)
      public val name = value
      
      //Caso 2
      //name é visibule in tutti gli altri package ma non puo' essere modificata
      public val name = value
      private set
      
      //Caso 3
      //name é visibile solo nel file dove é dichiarata
      private val name = value
  • Import
    • //Da un altro file devo importare la variabile definita nel file common
      //Import specifico
      Import package com.example.helloword.nico.common.name
      
      //Import global (importo tutti gli elementi public presenti nel package commmon)
      Import package com.example.helloword.nico.common.*

       

POO

  • Class
    • class MyClass(val age: Int = 10, val name: String){
         fun MyMethod(){
         }
      }
      
      var myClass = MyClass(20, "John")
  • Costruttore
    • //Costruttore primario
      class MyClass(val age: Int = 10, val name: String)
      
      
      //Blocco di inizializzazione
      class MyClass(val age: Int = 10, val name: String) {
      
         var myVar..
      
         init {
            ...
            myVar
         }
      }
      
      //Costruttore secondario (deve chiamare il costruttore primario)
      class MyClass(val age: Int = 10, val name: String)
      {
         constructor(a: Int) : this(a, 10)
      }
  • Ereditarietà
    • Utile per estendere la funzionalità di una classe esistente 
    • Open (virtual in c#)
      • Le classi sono di default chiuse alla ereditarietà 
      • Usare ‘open’ per rendere una classe ereditabile
      • Usare ‘open’ per poter fare l’override di un metodo
    • Una classe figlio puo’ derivare solo da una classe padre
    • //classe padre
      open class Parent(val var1: Int){
          open fun myMethod(){
             println("Hello from parent");
          }
      }
      
      //classe figlio
      class Child : Parent(4){
         override fun MyMethod(){
             println("Hello from child");
         }
      }
  • Interfacce
    • Utile per dare accesso a un comportamento predefinito.
    • Possono definire dei metodi al loro interno (come nelle ultime versioni di C#)
    • interface IFeul {
         var fuelGauge: Double
      
         fun fillGasTank(){
             println("Riempio il serbatorio")
             fuelGauge = 100.0
         }
      }
      
      class Car: IFuel
      {
         override fuelGauge: Double = 0.0
      }
      
      class Motorcycle: IFuel
      {
          override fuelGauge: Double = 0.0
         
          override fillGasTank() {
             super.fillGasTank();
             honk();
          }
      
           fun honk(){
               ...
           }
      }
  • Verifica del tipo (come C#)
    • var vehicle: Vehicle = Car()
      
      //smart-cast
      if(vehicle is Car){
         //il compilatore riconosce il controllo if che ho fatto
         //quindi la variabile vehicle si comportamento necessariamente e implicitamete come Car
      }
      
      //usafe-cast
      //se non é possibile fare il cast di vehicle alla classe Car 
      //allora a runtime ricevero' un errore
      var jeep: Car = vehicle as Car
      
      //safe-cast 
      //se non é possibile fare il cast di vehicle alla classe Car 
      //allora a runtime NON ricevero' un errore ma jeep sarà null
      var jeep: Car? = vehicle as? Car
  • Data class (non esiste in JAVA)
    • Una classe che contiene solo dati
    • Non accetta gli access modifier (open, abstract,…)
    • Kotlin genera in automatico i metodi
      • equals() =>  compara 2 oggi della stessa classe di tipo data verificando se sono uguali (compara ogni variabili della classe)
      • hashCode() => genera un identificatore unico per la nostra istanza della classe di tipo data
      • toString() 
      • copy() => fa una copia dell’oggetto partendo dai valori forniti
      • componentN()
    • data class User(val name: string, val age: Int)f
  • Nested class
    • la classe ha NON accesso ai membri della classe contenitore
    • class Outer(val age: Int){
         class Nested(){
            fun foo() = 42
         }
      }
      
      //non ho bisogno di inizializzare la classe Outer
      val temp = Outer.Nested().foo()  //42
  • Inner class
    • la classe interna ha accesso ai membri della classe contenitore
    • class Outer(val age: Int){
         inner class Inner(){
            fun foo() = age
         }
      }
      
      //devo inizializzare la classe Outer
      val temp = Outer(42).Inner().foo()  //42
  • Generic
    • Permette di applicare lo stesso comportamento a classi differenti
    • es: stoccare degli elementi in una lista accettando diversi tipi di variabili (Int, String, MyClass…)
    • //metodi generici
      fun<T> myFunction(var1: T){
         ..
      }
      
      //classi generiche
      class MyClass<T>(val var1: T)
      val instance = MyClass<Int>(5)
      val instance = MyClass<String>("my_text")
      
      oppure
      
      //posso limitare il tipo generico da usare
      class MyClass<T: string>(val var1: T)
      val instance = MyClass<Int>(5)
      val instance = MyClass<String>("my_text")
  • lateinit (lazy loading)
    • Permette di fare una inizializzazione tardiva di una variabile 
    • La variabile lateini deve essere membro di una classe.
    • Non deve essere dichiarata nel costruttore della classe.
    • La variabile non puo’ essere di un tipo primitivo.
    • class User(val name String, val age: Int){
         lateinit var nickename: String
      }
      
      val bob = User("bob"; 10)
      bob.nickname = "MJ"
      println("l'utente ${bob.Name} é soprannominato ${bob.Nickname}");
      
      Attenzione: le variabili lateinit DEVONO essere inizializzate prima che siano utilizzate per non avere un errore.
  • Companion object (Singleton)
    • Non esiste static in Kotlin
    • Permette la retro compatibilità con Java
    • Simplifica la dichiarazione di un singleton
    • Ogni istanza della mia classe ha  a che fare con lo stesso ‘comanion oggetto ‘
    • class MyClass {
         companion object {
           val MY_CONSTANT: Int = 42;
         }
      }

       

Android

  • Componenti principali di un progetto Android
    • Dossier java
      • Cartella con i file sorgente veri e propri ((Java, Kotlin, C++).
      • Cartella con i test da lanciare sul device.
      • Cartella con i test unitari da eseguire sulla macchina di sviluppo.
    • Dossier res
      • Layout
        • File di layout (descrive interfaccia di una schermata).
      • Values
        • File di traduzione.
        • File di configurazione dello stile dell’applicazione.
        • Cartella con le immagini.
    • AndroidManifest.xml (carta d’identità dell’applicazione)

 

      • Definisce il punto d’entrata dell’applicazione.
      • Definisce le permssion richieste dalla nostra appli.
      • Definisce le ‘activity’ che costituiscono la nostra applicazione.
    • Build.gradle =>
      • Alcuni parametri di configurazione che vanno a sovrascrivere certi presenti nel manifest.xml.
      • Direttive di compilazione.
        • Release
        • Debug
      • Lista delle dipendenze della nostra applicazione.
  • Activity
    • 1 attività  = 1 schermo
    • Divisa in 2 parti
      • Comportamento (Kotlin) 
        • Creare una classe che definisce la mia ‘activity’. Tale classe deve
          1. Derivare da AppCompatActivity o Activity.
          2. Chiamare il metodo setContentView(<activity.xml>) per legare la classe all’interfaccia grafica indicata.
          3. Essere aggiunta al file manifest.xml.
        • class MainActivity : AppCompatActivity() {
              override fun onCreate(savedInstanceState: Bundle?) {
                  super.onCreate(savedInstanceState)
                  setContentView(R.layout.activity_main) //indica quale file xml é legato a questo componente
              }
          
              val helloWorldTextViez : TextView = findViewById<TextView>(R.id.helloWorldText)
             
              oppure
          
              //per avere questa sintassi installare le Kotlin Android Extensions
              textView.setText("Hello world!);
          }
        • Kotlin Android Extensions
          • Permettono tra l’altro di richiamare i differenti componenti di una schermata con una sintassi semplificata.
          • build.gradle (Module:app)
            • //per poter usare le Kotlin Android Extensions
              //aggiungere questo plugin al file build.gradle e rilanciare una sincronizzazione
              plugins {
                  id 'kotlin-android-extensions'
              }
      • Interfaccia grafica (Xml)
    • Ciclo di vita complesso 

 

      • Deve interagire con molte componenti
      • Esempi 
        • Rotation d’ecran => Girando lo schermo, l’activity passa ad uno stato diverso ridisegnandosi.
        • Bottone Home => L’activity deve essere messa in ‘pausa’ nel caso l’utente che ha cliccato su ‘home’ ritorni sulla nostra ‘activity’.
        • Bottone  Return => Quando si clicca sul bottone back si torna allo schermo precedente o si esce dall’applicazione.
    • OS Android
      • Crea le istanze delle activity.
      • Avverte l’applicazione dei differenti cambi di stato e che gestisce il ciclo di vita di un ‘activity’.
  • Backstack

 

    • Sequenza delle ‘activity’ eseguiti in un’applicazione secondo un ordine FIFO.
    • Ogni nuova ‘activity’ eseguita si pone in cima alla pila. E’ la sola visibile e quando l’utente uscirà da tale attività sarà la seconda ad essere visualizzata.
    • Per ogni applicazione Android tiene in memoria il backstack relativo.
  • logcat

 

    • Esiste la possibilità di usare 6 livelli di log
  • Intent
    • Classe usata per fare comunicare moduli Android tra di loro
    • Esprime un’intenzione
      • Aprire un’activity
      • Inviare un messaggio ad un’altra applicazione
      • Azioni di Android
    • action
      • ACTION_VIEW
      • ACTION_EDIT
    • data (uri)
      • numero di telefono (tel:123)
      • contatto (content://contacts/people/1)
    • category
      • CATEGORY_LAUNCHER per eseguire l’attività principale dell’applicazione
      • CATEGORY_BROWSABLE per aprire un link web
    • extras (bundle)
      • Int, Float; String
      • Oggetti complessi
    • //classe chiamante
      val intent = Intent(this, MyActivity)
      intent.action = Intent.ACTION_VIEW
      intent.addCategory("UserViewer")
      intent.putExtra("name", "Bob")
      intent.putExtra("age", 10)
      
      //classe chiamata
      val action = intent.action //android.intent.action.VIEW
      val isUser = intent.hasCategory("UserViewer") //true
      val extras: Bundle = intent.extras
      val name = extras.getString("name")  //Bob
      val age = extras.getInt("age") //10
  • Parcelable =>
    • Serializzazione/Deserializzazione
    • Una volta creato un oggetto di tipo parcelable sarà Android che si incarica di gestirlo
    • Invio di un oggetto parcelabe (tra 2 activity o 2 applicazioni):
      1. L’oggetto deve derivare l’interfaccia Parcelable 
        • class MyClass : Parcelable { ... }
      2. Nella ‘activity’ del  mittente é necessario metere l’oggetto da inviare come l’extra di un Intent
        • intent.putExtra("mykey", myClass)
      3. Nella ‘activity’ del destinatario l’ogetto inviato verrà letto dall’intent
        • intent.getParcelableExtra<MyClass>("myKey")
    • //Esempio di classe parcelable
      data class User(val name: String?, val age:Int) : Parcelable {
          //usato del destinatario per deserializzare l'oggetto User
          constructor(parcel: Parcel) : this(
              //l'ordine é importante (uguale a writeToParcel)
              parcel.readString(),
              parcel.readInt()
          )
      
          //usato del mittente per serializzare l'oggetto User
          override fun writeToParcel(parcel: Parcel, flags: Int) {
              //l'ordine é importante (uguale a constructor)
              parcel.writeString(name)
              parcel.writeInt(age)
          }
      
          override fun describeContents(): Int {
              return 0
          }
      
          //Permette di creare gli oggetti User a partire dell'oggetto parcel ricevuto come parametro
          //companion = static
          companion object CREATOR : Parcelable.Creator<User> {
              //singolo User
              override fun createFromParcel(parcel: Parcel): User {
                  return User(parcel)
              }
      
              //lista di User
              override fun newArray(size: Int): Array<User?> {
                  return arrayOfNulls(size)
              }
          }
      }
      
      //classe mittente
      //Invio di User come parcelable
      val user = User("Bob", 10)
      findViewById(R.id.show_user_detail_button).setOnClickListener {
         val intent = Intent(this, DestinationActivity::class.java
         intent.putExtra("user", user)
         startActivity(intent)
      }
      
      //classe destinatario
      //Ricezione di User
      val user = Intent.getParcelableExtra<User>("user")
      
      val name = user.Name
      val age = user.Age

       

Gestione del layout

  • Usare più unità di misura
    • dp
      • Usato per tutti gli elementi tranne che per i testi.
      • E’ la scelta migliore per avere la massima coerenza possibile nel visualizzare lo schermo su più device differenti.
    • sp
      • Usato per la dimensione dei testi.
      • La dimensione varia in base ai setting che l’utente ha impostato nel suo Android..

  • Usare dimensioni dinamiche (larghezza, lunghezza)
    • wrap_content = imposta la taglia minima affiché l’elemento sia visibilie
    • match_parent = importa la taglia massima possibile par rapporto all’elemento parent
  • LinearLayout
    • Orizontal / Vertical
    • Ogni elemento puo’ avere un peso che indica la sua dimensione in rapporto agli altri elementi.

    • Non esagerare nell’annidare un LinearLayout in un altro => C’é un problema di performance.
    • Layout_resource_file  (creare un template)
      • E’ possibile definire un template per un layout che si ripete e importarlo nel nostro file xml.
      • Creare un layout_resource_file 
      • Assegnare un nome (es: “linear_orizontal” )
      • Inserirgli il contenuto che si vuole rendere templace
      • Dopodiché é sufficiente fare l’include come mostrato sotto:
      • <include layout="@layoute/linear_horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

 

  • RelativeLayout

 

    • Gli elementi si posizionato relativamente agli altri.
    • La taglia di un elemento é limitata delle regole di posizionamento definite.
  • Creare una finestra modale
    • Definire una nuova classe che eredita da DialogFragment

    • Chiamare la nostra classe dialog

  • Menù =>
    • Creare un nuovo menù
      • Creare una nuova ‘Android Resource Directory’ di tipo menù
      • Aggiungere a tale cartella un file di tipo ‘Menù resource file

 

    • Aggiungere un menu nela propria classe

  • Toolbar
    • Si é chiamata ActionBar, AppBar e ora Toolbar
    • Build.gradle
      • //nel file Build.gradle deve esserci questa dependency
        dependencies.compile 'com.android.support:appcompat-v7:25.3.1'
        //oppure
        dependences.compile 'androix.appcompat:appcompat:1.6.1
    • Verificare di non avere una actionbar di default (res->values->styles.xml->parent=’Theme.AppCompat.NoActionBar)
    • Definisco la toolbar customizzata nel file activity_main.xml

    • Nell’activity_main aggiungola toolbar customizzata

    • File manifest.xml
      • In questo file é possibile definire una gerarchie tra ‘activity’
      • Tale gerarchia sarà rispettata nella visualizzzione della nostra toolbar
  • RecyclerView
    • Permette di visualizzare lunghe liste di dati senza perdere in fluidità
    • Funziona trattando separatamente la visualizzazione e i dati visualizzati secondo lo schema seguente:

    • CardView

 

Android Studio

  • Gestione degli ambienti di build (es: dev o staging)
    • BuildType
    • Flavor
    • BuildVariant
      • Aprire la voce di menu  Build -> BuildVariant
      • Per poter scegliere quale BuildType tra quelli disponibili utilizzare (es: lanciare la varsione dev o staging)
  • Emulatore
    • Play Store (Enable/Disabled)
      • Quando si sceglie un emulatore se esiste una piccola icona nella colonnna ‘Play Store’ significa che tale emulatore avrà a disposizione il google play store per poter installare dele applicazioni.
      • E’ possibile modificare la configurazione per poter abilitare il google play store in un emulatore che originariamente non l’ha
    • Installare applicazione su un emulatore
      • E’ possibile installare un’applicazione su un emulatore semplicemente facendo il drag-and-drop del suo APK direttamente nella finestra dell’emulatore in esecuzione.
      • SKD Tools – Android Debug Bridge (adb)
        • E’ possibile usare  adb.exe per potersi connettere via comando shell all’emulatore e installare un nuovo APK.
      • Emulatore – Disinstallare un APK 
        • //C:\Users\nicola.riccardi\AppData\Local\Android\Sdk\platform-tools
          //adb.exe
          
          //visualizzare i packages presenti nell'emulatore
          adb shell pm list packages
          oppure
          adb shell cmd package list packages
          
          //disinstallare il package desiderato
          adb uninstall fr.cdchabitat.adoma.rmt.dev.debug
          
          //Increasing Buffer Sizes
          adb logcat -g
          adb logcat -b main -G 16M
          
           //to get process and thread IDs in the logging statements.
          adb logcat -v threadtime
          
          -------------------------------------------------------------------------------------------
          
          //C:\Users\nicola.riccardi\AppData\Local\Android\Sdk\emulator
          //emulator.exe
          //C:\Windows\System32\cmd.exe
          emulator -avd <device-name>
          emulator -list-avds
          
          -no-snapshot-load
          -gpu swiftshader_indirect
  • Device File Manager
    • Una volta lanciato l’emulatore, é possibile visualizzare il file SQLite a partire da Android Studio aprendo la finestra <Device File Manager>
    • Navigare fino alla file in questone /data/data/<my-project-package-folder>/<my-SQLite>
    • Il file é presente fisicamente nel file system del computer seguento il path
    • C:\User\<my-user>\AppData\Local\Google\AndroidStudio2022.1\device-explorer\<my-emulateur>\data/data/<my-project-package-folder>/<my-SQLite>