Skip to content

Sumarios

fmcarvalho edited this page Oct 23, 2019 · 34 revisions

Aulas:


09-09-2019

  • Apresentação.
  • Âmbito da disciplina.
  • Avaliação teórica e prática (3 entregas).

  • Caracterização geral da linguagem Kotlin:
    • Tipificação estática com inferência de tipos
    • Object-Oriented com suporte para os estilos imperativo e funcional
  • Funções: fun [<parametros de tipo>] <nome> ([parametros formais]) : [tipo retorno] {...}
  • Tipo Função -- notação especial correspondente à assinatura, i.e. (Tipo de Parametros) -> Tipo Retorno
  • Tipo Função e.g. (Int) -> String, () -> Unit, entre outros.
  • Typealias e.g. Predicate<T> = (T) -> Boolean
  • lambdas: { param1, param2, ... -> block } or { block }
  • it -- implicit lambda parameter
  • Function references - :: like Java
  • SAM (Single Abstract Method) compatível com lambda
  • read-only (e.g. listOf(), setOf) <vs> mutable collections (e.g. mutableListOf, mutableSetOf)

  • ? for Nullable -- val variable: Type? = value
  • ?. -- safe call -- access member only if not null. Otherwise returns null.

  • Basic parts: Manifest, Main Activity e Gradle build;
  • Activity: UI Component (subclasse de Context)
  • Activity:
    • visual + comportamento
    • visual (src/main/res/layout/...xml) + comportamento (src/main/java)
    • Analogia ao front-end Web: visual (HTML e CSS) + comportamento (Javascript)
  • Activity -- ciclo de vida, i.e. Created, Started (visível), Resumed (primeiro plano), Paused, Stopped, etc;
  • Activity -- métodos "gancho", i.e. onCreated(), onStarted(), etc
  • Actvities sao iniciadas por instâncias de Intent
  • Intent:
    • mensagem assíncrona;
    • ligação entre componentes (e.g. Activities)
  • Main Activity <-- intent.action.MAIN
  • UI = Layouts + Widgets:
    • Layouts = ViewGroup objects = widget containers
    • Widgets = View objects = UI components e.g. botões, caixas de texto, etc
  • ConstraintLayout
  • Android Studio Layout Editor ---> activity_...xml
  • R - classe gerada dinamicamente com constantes dos identificadores (e.g. R.id.buttonSend)
  • Eventos e Listeners -- view.setOnClickListener(View -> Unit)
  • findViewById(@IdRes int id)
  • Intent - representa uma mensagem assíncrona; ligação entre componentes (e.g. Activities)
    • e.g. Intent(this, DisplayMessageActivity::class.java):
    • Exlicit: identifica o tipo da actividade a ser instanciada (DisplayMessageActivity::class.java)
    • putExtra(key, value) e getStringExtra(key)
  • startActivity(intent)
  • Android Manifest: android:parentActivityName --> navegação
  • Activity: ciclo de vida
  • demo: logging lifecycle state transitions e.g. override fun onStart(){...}
  • Intercalação entre estados de activities da mesma App.
  • Lifecycle-Aware Components :
    • LifecycleOwner ----> LifecycleObserver
    • myLifecycleOwner.getLifecycle().addObserver(MyObserver())
    • e.g. @OnLifecycleEvent(Lifecycle.Event.ON_START)
  • Custom Views:
    • constructor(context: Context, attrs: AttributeSet)
    • custom drawing: onDraw(canvas: Canvas) e Paint
    • interaction: override fun onTouchEvent(event: MotionEvent)
  • Concepção da app Sketcher:
    • SketcherView --->* Line --->* XyPair
  • Implementação de SketcherView:
val lines : MutableList<Line> = mutableListOf()
var curr : Line? = null

override fun onDraw(canvas: Canvas) = lines.forEach { it.draw(canvas) }
override fun onTouchEvent(event: MotionEvent): Boolean { ... }

  • TPC: Identificar a instrução em falta para que a UI seja actualizada em resposta da interacção com utilizador.
  • Activity -- onSaveInstanceState(Bundle) e onRestoreInstanceState(Bundle)
  • Bundle:
    • Pares chave--valor
    • put<Primitive> ou put<Primitive>Array
    • Instâncias de tipos complexos => Serializable !!! Atenção aos custos !!!
      • Alternativa Parcelable
  • Implementar Serializable em Line e XyPair
  • View -- onSaveInstanceState(): Parcelable e onRestoreInstanceState(state: Parcelable)
  • Implementar Parcelable em Line e XyPair:
    • writeToParcel(dest: Parcel) : T
    • Parcelable.Creator<T> :: createFromParcel(source: Parcel) : T
    • Parcelable.Creator<T> :: newArray(int size) : Array<T>

  • TPC: Completar a implementação de Parcelable em Line. Substituir Serializable por Parcelable em on<Save|Restores>InstanceState
  • Implementação de Parcelable
  • Evitar a criação de um array intermédio.
  • Teste unitário para a implementação de Parcelable
  • !!! Problema: obter uma instância real de Parcel? (depende da infra-estrutura Android)
  • Robolectric framework -- ambiente Android para os testes unitários.
  • androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0
  • Adicionar ViewModel a sketcher app:
    • class SketcherModel : ViewModel()
    • Mover lines para SketcherViewModel
  • Transformação do desenho da aplicação Sketcher para ViewModel:
    • MainActivity --->1 SketcherView ---->* Line ---->* XyPair
    • MainActivity --->1 SketcherView --->1 SketcherViewModel ---->* Line ---->* XyPair
  • SketcherView --->1 SketcherViewModel através de:
    • ViewModelProviders.of(ctx)[SketcherModel::class.java]
    • Instância de ViewModel é gerida pela infra-estrutura.
  • RecyclerView -- 1. scrolling list, 2. large data sets, 3. data that frequently changes
  • Dependência gradle: 'androidx.recyclerview:recyclerview:1.0.0'
  • RecyclerView:
    • view holder object:
      • Um objecto por cada elemento visualizado
      • Instância de RecyclerView.ViewHolder
      • São instanciados apenas o número de view holders necessários à UI
    • view holder objects -- geridos por adapters -- instâncias de RecyclerView.Adapter.
    • adapter -- liga (binds) view holders aos seus dados ---> onBindViewHolder()
  • Imlementação de RecyclerView.Adapter:
    • class <Name> : RecyclerView.Adapter<ViewHolder_Name>()
    • override fun getItemCount() -- número de elementos na fonte de dados
    • override fun onBindViewHolder(holder ...) -- atribui dados ao holder
    • override fun onCreateViewHolder(parent ... ):
      1. Obtém a View correspondente a um layout
      2. Inflate parent com a View do ponto 1.
      3. Instancia e retorna um novo ViewHolder

  • Implementação da App GeniuZ para apresentação de informações da Last.fm Web API.
  • Utilização de RecyclerView com implementação de ArtistAdapter para dados só em memória (i.e. Array<ArtistDto>)
  • LayoutManager e LinearLayoutManager

  • Android HTTP framework envolve várias acções:
    1. Construção de um pedido HTTP
    2. Execução
    3. Obtenção da resposta
    4. Parsing headers e body e.g. JSON => Objecto
    5. Actualizar a UI.
  • Problema: operações de IO, parsing ou qq trabalho de background não pode ocupar a UI thread
  • App Resources
  • Tipos de recursos por pasta, e.g. layout, values, etc.
  • Recursos alternativos res/<resource_name>-<qualifier> e.g. res/values-pt/strings.xml

  • App GeniuZ simulação de obtenção dos dados sobre LastfmWebApiMock
  • RecyclerView.Adapter::notifyDataSetChanged()
  • Introduzir ViewModel para manutenção de estado em reconfiguração

  • Problema: operações de IO, parsing ou qq trabalho de background não pode ocupar a UI thread
  • Observar o resultado de executar IO na main thread:
  • Distinção entre idioma Sync versus Async:
    • Sync: Resultado = Retorno do método => Conclusão da execução do método
    • Async: Resultado != Retorno do método

  • 'com.android.volley:volley:1.1.1'
  • Volley - biblioteca HTPT para Android:
    • RequestQueue ---->* Request
    • Gestão de worker threads
    • Entrega a resposta de volta à main thread ( => actualização safe da UI)
  • Volley.newRequestQueue(context)
  • queue.add(request)
  • StringRequest(Request.Method,<url>,Response.Listener<String>,Response.ErrorListener)
  • AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" />
  • Implementação de LastfmWebApi via Volley com API baseada em callbacks
  • !!!! Problema: Reconfiguração gera novo pedido HTTP na AlbumsActivity
  • Refactoring: mover a propriedade LastfmWebApi da Activity para o ViewModel
  • Activity 1 -----> 1 ViewModel
  • Activity --> ViewModel --> LastfmWebApi
  • => ArtistsViewModel passa a ser instanciado por um ViewModelProvider.Factory
    • e.g. LasftfmViewModelProviderFactory
  • Application -- Classe base para manter o estado global da aplicação.
    • e.g GeniuzApp -- para manter uma instância de LastfmWebApi
    • Manifesto: <application android:name=".GeniuzApp" ... />`
  • ViewModelProviders.of(this, LasftfmViewModelProviderFactory(application as GeniuzApp))

  • !!!!! Problema: Processamento demorado do pedido HTTP na UI Thread impede a sua actualização (e.g. reconfiguração)
  • Asynchronous Task =
    • Computation that runs on a background thread
    • +
    • Result published on the UI thread.
  • AsyncTask<Params, Progress, Result>:
    • doInBackground(args: vararg Params) : Result
    • onProgressUpdate(progress: Progress)
    • onPostExecute(result: Result)
  • E.g. MyAsyncTask().execute(arg1, arg2)
  • Pedido HTTP com parsing JSON em background numa AsyncTask
  • E.g. AsyncTask<String, Int, SearchDto>():
    • doInBackground(vararg resp: String): SearchDto
    • onPostExecute(result: SearchDto) = onSuccess(result)
Clone this wiki locally