Comunicação via Sockets



Documentos relacionados
Comunicação entre A0vidades

Provedores de Conteúdo

Programação para Dispositivos Móveis

Programação para a Plataforma Android Aula 7. Mul$mídia

Programa de Dispositivos Móveis

Java : Comunicação Cliente-Servidor.

Programação para Android. Aula 06: Activity, menus e action bar

Programação para a Plataforma Android Aula 11. Banco de Dados

Desenvolvimento para Android Prá9ca 2. Prof. Markus Endler

Programação de Dispositivos Móveis

Programação de Computadores - I. Profª Beatriz Profº Israel

Num sistema de objectos distribuídos, dois conceitos são fundamentais.

Introdução ao Android. SECAP 2014 Prof. Rone Ilídio - UFSJ

Olho por olho, e o mundo acabará cego. Mohandas Gandhi

Programa de Dispositivos Móveis

Sistemas Paralelos e Distribuídos /2004 Curso: Matemática /Informática Sistemas Distribuídos /2004 Curso: Ensino da Informática

Programação de Dispositivos Móveis

JDBC. Siga as instruções para instalar o banco de dados H2 e criar a tabela Alunos.

( TIAGO DOS SANTOS MENDES ) PROGRAMAÇÃO DISPOSITIVOS MOVEIS ANDROID STUDIO

Armazenamento Persistente de Dados

Programação para Android. Aula 08: Persistência de dados SQL

Android Banco de Dados. Ivan Nicoli

Apresentação de um Processo Cria4vo de Desenvolvimento de uma App Android. Realização de Dinâmica Hands- On para Construção de uma App Android

Módulo 2 - Novas Activities Android. Programação Orientada a Objetos Prof. Rone Ilídio - UFSJ

Programação em Java para a Plataforma Android AULA 1. Primeiros Passos

Tutorial RMI (Remote Method Invocation) por Alabê Duarte

Prof. Jhonatan Fernando

Programação para Android. Aula 05: Estilos e temas; galeria de imagens

Aula 30 - Sockets em Java

Desenvolvimento para Android Prá3ca 3. Prof. Markus Endler

Um pouco do Java. Prof. Eduardo

Coleções. Conceitos e Utilização Básica. c Professores de ALPRO I 05/2012. Faculdade de Informática PUCRS

Introdução ao Android. Programação Orientada a Objetos Prof. Rone Ilídio - UFSJ

Descrição. Implementação. Departamento de Informática e Estatística Universidade Federal de Santa Catarina LAB 4 Transferência de Arquivos

ANDROID APPLICATION PROJECT

Uma Introdução à Arquitetura CORBA. O Object Request Broker (ORB)

Mecanismos de Comunicação. Sockets em java (

Android Core. Felipe Silveira felipesilveira.com.br. Aula 6

Persistência de Classes em Tabelas de Banco de Dados

INF1013 MODELAGEM DE SOFTWARE

Memória Flash. PdP. Autor: Tiago Lone Nível: Básico Criação: 11/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos

Sistemas Distribuídos

Programação para Dispositivos Móveis

insfcanceof new public switch transient while byte continue extends for int null

Linguagem de Programação JAVA. Técnico em Informática Professora Michelle Nery

Sistemas Distribuídos

Invocação de Métodos Remotos RMI (Remote Method Invocation)

Multithreading. Programação Orientada por Objectos com Java. Ademar Aguiar. MRSC - Programação em Comunicações

Programação para Dispositivos Móveis

Prototype, um Design Patterns de Criação

Exercício 1 : As classes abaixo serão utilizadas neste exercício: public class Ponto { int x; int y; public Ponto(int x, int y){ this.

2 Orientação a objetos na prática

Aula 2. Objetivos. Encapsulamento na linguagem Java; Utilizando a referência this.

Técnicas de Programação II

INTRODUÇÃO À TECNOLOGIA SERVLETS

Java para Desenvolvimento Web

Computação II - Java Prof. Adriano Joaquim de Oliveira Cruz Aula Prática - Herança, Polimorfismo e Construtores

public Agenda() { compromissos = null; } public int getnumerodecompromissos() { if (compromissos==null) return 0; else return compromissos.

Analisar os sistemas operacionais apresentados na figura e responder as questões abaixo: Identificar

Introdução ao Android

Desenvolvimento com Android Studio. Aula 02 Widgets, Manipulação de Dados e Programação de Eventos

Computação II Orientação a Objetos

Módulo 4 - Interface Gráfica Gerenciadores de Layout. Programação Orientada a Objetos Prof. Rone Ilídio - UFSJ

Android Layout Manager. Ivan Nicoli

Orientação a Objetos

Cliente-servidor com Sockets TCP

AULA 2. Minicurso PET-EE UFRN

Curso Adonai QUESTÕES Disciplina Linguagem JAVA

5 Caso de estudo O cartão fidelidade

A ) O cliente terá que implementar uma interface remota. . Definir a interface remota com os métodos que poderão ser acedidos remotamente

Acessando um Banco de Dados

Programação para Android. Aula 10: Acesso a câmera, sms e recursos do aparelho

Sintaxe Geral Tipos de Dados. Prof. Angelo Augusto Frozza, M.Sc.

Introdução ao Desenvolvimento para Sistema Operacional Android

Acesso a banco de dados

Como foi exposto anteriormente, os processos podem ter mais de um fluxo de execução. Cada fluxo de execução é chamado de thread.

POO Programação Orientada a Objetos. Classes em Java

JAVA COM BANCO DE DADOS PROFESSORA DANIELA PIRES

ECD1200 Equipamento de Consulta de Dados KIT DE DESENVOLVIMENTO

Manipulação de Banco de Dados com Java. Ms. Bruno Crestani Calegaro Maio/ 2015

FTP FILE F TRANSFER PROTOCOL. Tópicos

Para desenvolver a atividade a atividade desta aula utilizaremos o ambiente de desenvolvimento integrado NetBeans.

Aula 09 Introdução à Java. Disciplina: Fundamentos de Lógica e Algoritmos Prof. Bruno Gomes

Curso de Java. Orientação a objetos e a Linguagem JAVA. TodososdireitosreservadosKlais

Is Event Dispatcher Threade (Animation)

Implementação de Classe e Auto-Relacionamento em Java

Display de Cristal Líquido

Laboratório de Computação VI JAVA IDL. Fabricio Aparecido Breve

SISTEMAS DISTRIBUÍDOS

Invocação Remota MC704

Sockets. Introdução. Introdução. Programando para redes em Java. mecanismo de alto nível para acessar recursos na Internet.

Threads e Sockets em Java. Threads em Java. Programas e Processos

Display de 7. PdP. Autor: Tiago Lone Nível: Básico Criação: 16/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos

UNIVERSIDADE FEDERAL DO PARANÁ. CURSO: Ciência da Computação DATA: / / 2013 PERÍODO: 4 o.

Android Binding. Implementando o padrão de projeto MVVM com MVVM_. Saiba como criar um projeto utilizando o padrão de projeto MVVM no Android

Transcrição:

Programação para a Plataforma Android Aula 9 Comunicação via Sockets O que são sockets? O que são data access objects? Como criar servidores de serviços distribuídos? Aplicações mulb threading simples O padrão de projetos command O que é o princípio da inversão de dependências?

Sockets Sockets são uma abstração de endereços de comunicação: Um nome de host, mais um número de porta. Esse Bpo de dados é a abstração de comunicação básica em várias linguagens de programação. Java não é exceção.

Banco de Dados Distribuído Serviço de notas de estudantes: Implemente um banco de dados distribuído que informe a nota de um estudante. Estudantes são encontrados por um id um inteiro do tipo longo que os identifica unicamente. O banco de dados deve ser acessado via um DAO (Data Access Object) As operação aceitas são add, get, delete e update. O servidor de dados deve receber conexões na porta 4444. O servidor deve criar uma thread para tratar cada conexão recebida. O banco de dados deve receber conexões de clientes android.

Data Access Object Um DAO é um objeto que faz a intermediação entre a lógica de serviço, e o sistema de banco de dados. É o intermediário. Operações Bpicamente fornecidas por um DAO são adicionar, atualizar, remover e pesquisar. Em termos de padrões de projeto um DAO é um adaptador. Como descrever o DAO em Java?

Data Access Object server/dao.java package server; public interface DAO<K, V> { V get(k key); void add(k key, V value); O que são esses K s e V s? O nosso banco de dados irá armazenar estudantes. void delete(k key); void update(k key, V value); O que é um estudante?

Estudantes public class Student { public Student(long key, String name, double grade) { this.name = name; this.grade = grade; this.key = key; public final String name; public final double grade; public final long key; public String tostring() { Instâncias dessa classe deverão ser passadas via rede. return name + "" + "(" + key + "): " + grade; server/student.java Qual propriedade objetos passáveis via rede devem ter?

import java.io.serializable; public class Student implements Serializable { public Student(long key, String name, double grade) { this.name = name; this.grade = grade; this.key = key; public final String name; public final double grade; public final long key; public String tostring() { Estudantes Como será nosso servidor de banco de dados? return name + "" + "(" + key + "): " + grade; server/student.java

server/server1/gradeserver.java O Servidor public stabc void main(string[] args) { Map<Long, Student> students = new HashMap<Long, Student>(); loaddb(students); ServerSocket serversocket = null; boolean listening = true; try { serversocket = new ServerSocket(4444); System.out.println("WaiBng for connecbon"); while (listening) { new StudentHandlerThread(serverSocket.accept(), students).start(); serversocket.close(); catch (IOExcepBon e) { e.printstacktrace(); System.exit( 1); O que é um stub? Precisamos implementar um stub para testar nosso programa. E como será a implementação de nosso stub?

Um Stub muito Simples private stabc void loaddb(map<long, Student> students) { students.put(200934878l, new Student(200934878L, "Alberico", 90.5)); students.put(200755120l, new Student(200755120L, "Bernadino", 71.0)); students.put(200723139l, new Student(200723139L, "Romao", 84.0));

server/server1/gradeserver.java O Servidor public stabc void main(string[] args) { Map<Long, Student> students = new HashMap<Long, Student>(); loaddb(students); ServerSocket serversocket = null; boolean listening = true; try { serversocket = new ServerSocket(4444); System.out.println("WaiBng for connecbon"); while (listening) { new StudentHandlerThread(serverSocket.accept(), students).start(); serversocket.close(); catch (IOExcepBon e) { e.printstacktrace(); System.exit( 1); O que é uma thread? Agora precisamos implementar essa thread E como implementar threads em Java?

server/server1/studenthandlerthread.java public class StudentHandlerThread extends Thread { private Socket socket = null; Map<Long, Student> students; A Thread Novamente: o que é uma thread? public StudentHandlerThread(Socket socket, Map<Long, Student> students) { System.out.println("Got conecbon!"); this.socket = socket; this.students = students; public void run() {... Como inicia-se a execução de uma thread? Qual a vantagem de se programar com threads? Que suporte java dá para programação multi-thread? Como implementar o método run?

server/server1/studenthandlerthread.java public void run() { try { ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); Long key = (Long) in.readobject(); while (key.longvalue()!= 0L) { System.out.println("Received " + key); if (students.containskey(key)) { out.writeobject(students.get(key)); else { out.writeobject(new Student( 1, "", 0.0)); key = (Long) in.readobject(); out.close(); in.close(); socket.close(); catch (ExcepBon e) { e.printstacktrace(); Quantas vezes essa thread provê esse serviço? Que tipo de serviço essa thread provê? O que acontece quando um id não está presente no banco de dados? Precisamos implementar o lado cliente da aplicação

O Lado Cliente public class Dao1 implements DAO<Long, Student> { public Student get(long key) {... public void add(long key, Student value) {... Por enquanto, vamos prover somente o get. public void update(long key, Student value) {... public void delete(long key) {... server/server1/dao1.java E como seria a implementação do get?

Implementação do DAO public Student get(long key) { Student s = null; Socket socket; ObjectOutputStream out; ObjectInputStream in; try { socket = new Socket("10.0.2.2", 4444); out = new ObjectOutputStream(socket.getOutputStream()); in = new ObjectInputStream(socket.getInputStream()); out.writeobject(new Long(key)); s = (Student) in.readobject(); out.writeobject(new Long(0L)); socket.close(); out.close(); in.close(); catch (ExcepBon e) { e.printstacktrace(); return s; server/server1/dao1.java Comecemos então pelo layout! Que endereço é esse? Olhando para cliente e servidor, qual é o protocolo de comunicação? Ok, mas agora é preciso usar esse cliente em um telefone

Aviso importante: Setup Para que nosso cliente funcione, ele precisa enxergar o servidor. Botão direito no projeto > build path > configure build path Lembre se de exportar o pacote server com a aplicação, ou ela será compilada, mas não executará corretamente.

Layout do Cliente Como criar esse layout em XML?

<LinearLayout xmlns:android="h7p://schemas.android.com/apk/res/ android" android:id="@+id/root" android:orientabon="ver>cal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/txtid" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lblresults"/> <LinearLayout android:orientabon="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/txtname" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.3"/> <EditText android:id="@+id/txtgrade" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> </LinearLayout> <Bu on android:id="@+id/read" android:text="@string/read" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> </LinearLayout> Vamos precisar de algumas constants strings. main.xml Layout do Cliente

Layout do Cliente <LinearLayout xmlns:android="h7p://schemas.android.com/apk/res/ android" android:id="@+id/root" android:orientabon="ver>cal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/txtid" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lblresults"/> <LinearLayout android:orientabon="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/txtname" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.3"/> <EditText android:id="@+id/txtgrade" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> </LinearLayout> <Bu on android:id="@+id/read" android:text="@string/read" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> </LinearLayout> main.xml <?xml version="1.0" encoding="u} 8"?> <resources> <string name="app_name">aula9</string> <string name="client_name">daoclient</string> <string name="read">r</string> <string name="write">w</string> <string name="lblresults">nome e Nota:</string> <string name="get">g</string> <string name="add">a</string> <string name="upd">u</string> <string name="del">d</string> <string name="cln">c</string> <string name="siz">s</string> </resources> E como implementar a atividate? strings.xml

@Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); final EditText txtid = (EditText) findviewbyid(r.id.txtid); final EditText txtname = (EditText) findviewbyid(r.id.txtname); final EditText txtgrade = (EditText) findviewbyid(r.id.txtgrade); ((Bu on) findviewbyid(r.id.read)).setonclicklistener(new Bu on.onclicklistener() { public void onclick(view arg0) { String strid = txtid.gettext().tostring(); long id = Long.parseLong(strId); Dao1 d = new Dao1(); Student s = d.get(id); txtname.settext(s.name); txtgrade.settext(string.valueof(s.grade)); }); AulaAcBvity9.java Essa atividade precisa de permissões especiais. Quais? E como indicamos que essas permissões são necessárias?

manifest.xml Manifesto! Agora temos de testar nossa atividade! Como? <?xml version="1.0" encoding="u} 8"?> <manifest xmlns:android="h p://schemas.android.com/apk/res/android" package="com.aula9" android:versioncode="1" android:versionname="1.0" > <applicabon android:icon="@drawable/icon" android:label="@string/app_name"> <acbvity android:name=".aulaacibvity9" android:label="@string/app_name"> <intent filter> <acbon android:name="android.intent.acbon.main" /> <category android:name="android.intent.category.launcher" /> </intent filter> </acbvity> </applicabon> <uses sdk android:minsdkversion="2" /> <uses permission android:name="android.permission.internet" /> </manifest>

Objetos Remotos A mágica de programar para as interfaces. Note que nosso DAO funciona como um objeto remoto. Ele é usado como se seus dados esbvessem disponíveis localmente, ainda que esses dados estejam distribuídos! Simplesmente olhando para esse código, não é possível saber que o objeto é remoto. public void onclick(view arg0) { String strid = txtid.gettext().tostring(); long id = Long.parseLong(strId); Dao1 d = new Dao1(); Student s = d.get(id); txtname.settext(s.name); txtgrade.settext(string.valueof(s.grade));

Ligando o Servidor Podemos abrir uma nova instância de Eclipse, ou simplesmente iniciar o servidor a parbr da linha de comando: ~/workspace/server$ cd bin/ ~/workspace/server/bin$ java server.server1.gradeserver Waiting for connection Agora já podemos usar o cliente!

Testando a Aplicação Precisamos implementar os outros métodos: add, update, delete. Mas o nosso programa possui várias falhas de projeto! Quais? Existem falhas no servidor Mas também existem falhas no cliente!

Analisando a Camada de Comunicação public Student get(long key) { Student s = null; Socket socket; ObjectOutputStream out; ObjectInputStream in; try { socket = new Socket("10.0.2.2", 4444); out = new ObjectOutputStream(socket.getOutputStream()); in = new ObjectInputStream(socket.getInputStream()); out.writeobject(new Long(key)); s = (Student) in.readobject(); out.writeobject(new Long(0L)); socket.close(); out.close(); in.close(); catch (ExcepBon e) { e.printstacktrace(); return s; server/server1/dao1.java Há um grande desperdício de recursos aqui. Que desperdício é esse?

Analisando a Camada de Comunicação public Student get(long key) { Student s = null; Socket socket; ObjectOutputStream out; ObjectInputStream in; try { socket = new Socket("10.0.2.2", 4444); out = new ObjectOutputStream(socket.getOutputStream()); in = new ObjectInputStream(socket.getInputStream()); out.writeobject(new Long(key)); s = (Student) in.readobject(); out.writeobject(new Long(0L)); socket.close(); out.close(); in.close(); catch (ExcepBon e) { e.printstacktrace(); return s; server/server1/dao1.java Há um grande desperdício de recursos aqui. Que desperdício é esse? E como reusar os canais de comunicação? Como garantir que o canal aberto seja eventualmente fechado?

O padrão Command server/server2/command.java public interface Command { void execute(dao6 d); Temos um miniarcabouço. Vocês lembram o que é um arcabouço? Esse padrão é uma forma de inversão de dependências. O que é isso? public class Invoker { public void invoke(dao6 d, Command c) { openconnecbon(); d.setchannels(out, in); c.execute(d); closeconnecbon(); server/server2/invoker.java

O padrão Command server/server2/command.java public interface Command { void execute(dao6 d); Como estão sendo divididas as responsabilidades? public class Invoker { public void invoke(dao6 d, Command c) { openconnecbon(); d.setchannels(out, in); c.execute(d); closeconnecbon(); server/server2/invoker.java

Command Como transcrever esses elementos para nossa aplicação?

server/server2/invoker.java O Invocador public class Invoker { public void invoke(dao6 d, Command c) {... private void openconnecbon() {... private void closeconnecbon() {... public Invoker(String host, int port) { this.host = host; this.port = port; public class Invoker { public void invoke(dao6 d, Command c) { openconnecbon(); d.setchannels(out, in); c.execute(d); closeconnecbon();

O Invocador private void openconnecbon() { try { socket = new Socket(host, port); out = new ObjectOutputStream(socket.getOutputStream()); in = new ObjectInputStream(socket.getInputStream()); catch (ExcepBon e) { e.printstacktrace(); server/server2/invoker.java private void closeconnecbon() { try { out.writeobject(new Integer(EOF)); out.flush(); socket.close(); out.close(); in.close(); catch (ExcepBon e) { e.printstacktrace(); Quais os campos de objetos invokers? Como seria o construtor da classe Invoker? public void invoke(dao6 d, Command c) { openconnecbon(); d.setchannels(out, in); c.execute(d); closeconnecbon();

Ainda o Invocador public class Invoker { private stabc final int EOF = 1; private String host; private int port; private Socket socket = null; private ObjectOutputStream out = null; private ObjectInputStream in = null; public Invoker(String host, int port) { this.host = host; this.port = port; private void closeconnecbon() { private void openconnecbon() { public void invoke() { Quais são as responsabilidades do DAO?

Inversão de Dependência Antes o DAO Bnha a responsabilidade de abrir a conexão de rede. O DAO dependia da conexão de rede para funcionar. Agora o DAO recebe uma conexão já aberta. A dependência não mais existe. A enbdade responsável por abrir essas conexões, o Invoker, agora depende do DAO. A criação e liberação de recursos já não é mais responsabilidades dos usuários do DAO.

server/server2/dao6.java public class Dao6 implements DAO<Long, Student> { private ObjectOutputStream out; private ObjectInputStream in; public void setchannels (ObjectOutputStream out, ObjectInputStream in) { this.out = out; this.in = in; public Student get(long key) { Student s = null; try { out.writeobject(new Integer(DAO.GET)); out.writeobject(new Long(key)); s = (Student) in.readobject(); out.flush(); catch (ExcepBon e) { e.printstacktrace(); return s; O Novo DAO Qual é o protocolo de comunicação? Que constante é essa aqui? Para que ela serve?

Constantes para a Comunicação public interface DAO<K, V> { final int GET = 1; final int ADD = 2; final int DELETE = 3; final int UPDATE = 4; final int SIZE = 5; final int PORT = 4444; final String HOST = "10.0.2.2"; V get(k key); void add(k key, V value); void delete(k key); void update(k key, V value); int size(); server/dao.java Nós já vimos a implementação desse método. Como ficam os outros?

server/server2/dao6.java public void add(long key, Student value) { try { out.writeobject(new Integer(DAO.ADD)); out.writeobject(new Long(key)); out.writeobject(value); out.flush(); catch (ExcepBon e) { e.printstacktrace(); O Novo DAO public void delete(long key) { try { out.writeobject(new Integer(DAO.DELETE)); out.writeobject(new Long(key)); out.flush(); catch (ExcepBon e) { e.printstacktrace(); public void update(long key, Student value) { try { out.writeobject(new Integer(DAO.UPDATE)); out.writeobject(new Long(key)); out.writeobject(value); out.flush(); catch (ExcepBon e) { e.printstacktrace(); Como é a implementação do protocolo no lado servidor?

public void run() { try { Integer request = (Integer) in.readobject(); boolean isworking = true; while (isworking) { switch (request.intvalue()) { case DAO.GET: out.writeobject(get((long) in.readobject())); break; case DAO.DELETE: delete((long) in.readobject()); break; case DAO.UPDATE: update((long) in.readobject(), (Student)in.readObject()); break; case DAO.ADD: add((long) in.readobject(), (Student)in.readObject()); break; default: isworking = false; return; request = (Integer) in.readobject(); out.close(); in.close(); socket.close(); catch (ExcepBon e) { e.printstacktrace(); Fecho, mas onde abro? server/server2/studenthandlerthread.java O Servidor public Student get(long key) { Student s = null; if (students.containskey(key)) { s = students.get(key); else { s = new Student( 1, "", 0.0); return s; private Socket socket = null; private Map<Long, Student> students; private ObjectOutputStream out; private ObjectInputStream in;

O Servidor public void run() { try { Integer request = (Integer) in.readobject(); boolean isworking = true; while (isworking) { switch (request.intvalue()) { case DAO.GET: out.writeobject(get((long) in.readobject())); break; case DAO.DELETE: delete((long) in.readobject()); break; case DAO.UPDATE: update((long) in.readobject(), (Student)in.readObject()); break; case DAO.ADD: add((long) in.readobject(), (Student)in.readObject()); break; default: isworking = false; return; request = (Integer) in.readobject(); out.close(); in.close(); socket.close(); catch (ExcepBon e) { e.printstacktrace(); server/server2/studenthandlerthread.java public StudentHandlerThread(Socket socket, Map<Long, Student> students) { System.out.println("Got conecbon!"); this.socket = socket; this.students = students; try { out = new ObjectOutputStream(socket.getOutputStream()); in = new ObjectInputStream(socket.getInputStream()); catch (ExcepBon e) { e.printstacktrace(); Temos, é claro, outros métodos para implementar

O Servidor public void add(long key, Student value) { this.students.put(key, value); public void update(long key, Student value) { add(key, value); public void delete(long key) { this.students.remove(key); Prcisamos, agora, escrever o novo cliente. Temos quatro eventos para tratar. Quais são eles? E como seria o layout do novo programa? server/server2/studenthandlerthread.java

Quatro Botões Como fazer um layout assim? Quantos layouts lineares temos aqui? E como seria a atividade cliente? Quantos eventos precisam ser tratados?

Layout <LinearLayout xmlns:android= "h p://schemas.android.com/apk/res/android" android:id="@+id/root" android:orientabon="verbcal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/txtid" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lblresults"/> <LinearLayout android:orientabon="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/txtname" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.3"/> <EditText android:id="@+id/txtgrade" android:focusable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> </LinearLayout> <LinearLayout android:orientabon="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Bu on android:id="@+id/get" android:text="@string/get" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <Bu on android:id="@+id/add" android:text="@string/add" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <Bu on android:id="@+id/del" android:text="@string/del" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <Bu on android:id="@+id/upd" android:text="@string/upd" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <Bu on android:id="@+id/cln" android:text="@string/cln" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> </LinearLayout> </LinearLayout> client.xml Escreva agora a classe que implementa essa atividade.

@Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.client); txtid = (EditText) findviewbyid(r.id.txtid); txtname = (EditText) findviewbyid(r.id.txtname); txtgrade = (EditText) findviewbyid(r.id.txtgrade); oncreate ((Bu on) findviewbyid(r.id.get)).setonclicklistener(new GetCmd()); ((Bu on) findviewbyid(r.id.add)).setonclicklistener(new AddCmd()); ((Bu on) findviewbyid(r.id.upd)).setonclicklistener(new UpdCmd()); ((Bu on) findviewbyid(r.id.del)).setonclicklistener(new DelCmd()); ((Bu on) findviewbyid(r.id.cln)).setonclicklistener(new Bu on.onclicklistener() { public void onclick(view arg0) { txtid.settext(""); txtname.settext(""); txtgrade.settext(""); }); Client2.java Precimos implementar todos esses eventos!

class UpdCmd implements Command, Bu on.onclicklistener { public void onclick(view arg0) { Invoker i = new Invoker(DAO.HOST, DAO.PORT); Dao6 d = new Dao6(); i.invoke(d, this); public void execute(dao6 d) { long id = Long.parseLong(txtId.getText().toString()); String name = txtname.gettext().tostring(); double grade = Double.parseDouble(txtGrade.getText().toString()); Student std = new Student(id, name, grade); d.update(id, std); Essa alternativa é muito redundante. Como fatorar onclick( )? Já podemos testar nossa aplicação! class GetCmd implements Command, Bu on.onclicklistener { public void onclick(view arg0) { Invoker i = new Invoker(DAO.HOST, DAO.PORT); Dao6 d = new Dao6(); i.invoke(d, this); public void execute(dao6 d) { String strid = txtid.gettext().tostring(); long id = Long.parseLong(strId); Student s = d.get(id); txtname.settext(s.name); txtgrade.settext(string.valueof(s.grade));

Client2.java Classes Abstratas abstract class AbstractCommand implements Command, Bu on.onclicklistener { public abstract void execute(dao6 d); public void onclick(view arg0) { Invoker i = new Invoker(DAO.HOST, DAO.PORT); Dao6 d = new Dao6(); i.invoke(d, this); Como seria o tratador do evento de adição de novo dado? Todos os tratadores de evento vão usar esse método onclick Eles terão somente de implementar o método execute.

Client2.java AddCmd class AddCmd extends AbstractCommand implements Command { public void execute(dao6 d) { long id = Long.parseLong(txtId.getText().toString()); String name = txtname.gettext().tostring(); double grade = Double.parseDouble(txtGrade.getText().toString()); Student std = new Student(id, name, grade); d.add(id, std); Agora está fácil: como ficaria o comando para pesquisar um ID?

getcmd Client2.java class GetCmd extends AbstractCommand implements Command { public void execute(dao6 d) { String strid = txtid.gettext().tostring(); long id = Long.parseLong(strId); Student s = d.get(id); txtname.settext(s.name); txtgrade.settext(string.valueof(s.grade)); E o comando para atualizar um item? Não se esqueçam do comando para apagar um item!

UpdCmd Client2.java class UpdCmd extends AbstractCommand implements Command { public void execute(dao6 d) { long id = Long.parseLong(txtId.getText().toString()); String name = txtname.gettext().tostring(); double grade = Double.parseDouble(txtGrade.getText().toString()); Student std = new Student(id, name, grade); d.update(id, std);

DelCmd Client2.java class DelCmd extends AbstractCommand implements Command { public void execute(dao6 d) { long id = Long.parseLong(txtId.getText().toString()); d.delete(id);

Exercício: Size Modifique a sua aplicação para que ela seja capaz de informar o número de elementos presentes no banco de dados. Será preciso modificar a interface DAO. Será também necessário modificar o layout do cliente. public interface DAO<K, V> { final int GET = 1; final int ADD = 2; final int DELETE = 3; final int UPDATE = 4; final int SIZE = 5; final int PORT = 4444; final String HOST = "10.0.2.2"; V get(k key); void add(k key, V value); void delete(k key); void update(k key, V value); int size();

Exercício: Size Adicione um botão size à interface do cliente. Quando esse botão receber um clique, o número de elementos armazenados no banco de dados deverá ser impresso na caixa de texto em que são impressas as notas: