Comunicação via Sockets

Propaganda
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.
Como
•  Em
termos
de
padrões
de
projeto
descrever o
a?
v
a
um
DAO
é
um
adaptador.
J
m
e
O
A
D
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;
Instâncias
this.grade
=
grade;
dessa classe
this.key
=
key;
deverão ser
a
}
passadas vi
Qual proprie
rede.
public
final
String
name;
dade
objetos
public
final
double
grade;
“passáveis” v
public
final
long
key;
ia
rede devem
ter?
public
String
toString()
{
return
name
+
""
+
"("
+
key
+
"):
"
+
grade;
}
}
server/Student.java
Estudantes
import
java.io.Serializable;
public
class
Student
implements
Serializable
{
public
Student(long
key,
String
name,
double
grade)
{
this.name
=
name;
this.grade
=
grade;
Como será n
this.key
=
key;
osso
servidor de
}
b
public
final
String
name;
anco de dados?
public
final
double
grade;
public
final
long
key;
public
String
toString()
{
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);
Precisamos
ServerSocket
serverSocket
=
null;
implementar
um
boolean
listening
=
true;
stub para te
star
try
{
nosso progra
ma.
serverSocket
=
new
ServerSocket(4444);
System.out.println("WaiBng
for
connecBon");
while
(listening)
{
new
StudentHandlerThread(serverSocket.accept(),
students).start();
}
serverSocket.close();
}
catch
(IOExcepBon
e)
{
E como será a
?
e.printStackTrace();
implementação
O que é um stub
System.exit(‐1);
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);
Agora
ServerSocket
serverSocket
=
null;
precisamos
boolean
listening
=
true;
implementar
try
{
essa thread
serverSocket
=
new
ServerSocket(4444);
System.out.println("WaiBng
for
connecBon");
while
(listening)
{
new
StudentHandlerThread(serverSocket.accept(),
students).start();
}
E como
serverSocket.close();
uma
é
e
u
q
implement
O
}
catch
(IOExcepBon
e)
{
ar
?
d
a
e
threads em
thr
e.printStackTrace();
Java?
System.exit(‐1);
}
}
server/server1/StudentHandlerThread.java
public
class
StudentHandlerThread
extends
Thread
{
private
Socket
socket
=
null;
Map<Long,
Student>
students;
A
Thread
:o
e
t
n
e
m
a
v
o
N
que é uma
thread?
public
StudentHandlerThread(Socket
socket,
Map<Long,
Student>
students)
{
System.out.println("Got
conecBon!");
this.socket
=
socket;
te java
r
o
p
u
s
e
u
Como
inicia-se
a
Q
this.students
=
students;
execução de uma dá para
}
thread?
programação
ad?
e
r
h
t
i
t
l
u
m
public
void
run()
{
...
Como
agem
t
n
a
v
a
l
a
u
Q
}
ar
implementar o
de se program
}
método run?
com threads?
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)
{
Que tipo de
System.out.println("Received
"
+
key);
serviço essa
if
(students.containsKey(key))
{
thread provê?
out.writeObject(students.get(key));
}
else
{
O que aconte
ce
out.writeObject(new
Student(‐1,
"",
0.0));
quando um i
d não
}
está present
key
=
(Long)
in.readObject();
e no
b
anco de dado
}
s?
out.close();
Quantas vezes
in.close();
sa thread
s
e
socket.close();
Precisamos
sse
e
ê
v
o
r
p
}
catch
(ExcepBon
e)
{
implementar o
?
o
iç
v
ser
e.printStackTrace();
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 enquan
to,
vamos prov
er
somente o g
et.
public
void
update(Long
key,
Student
value)
{...}
public
void
delete(Long
key)
{...}
}
server/server1/Dao1.java
a
E como seria
ão
implementaç
do get?
Implementação
do
DAO
public
Student
get(Long
key)
{
server/server1/Dao1.java
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();
Comecemos
}
catch
(ExcepBon
e)
{
então pelo
e.printStackTrace();
layout!
}
return
s;
}
Que endere
ço é
esse?
Olhando para
cliente e
servidor, qual é o
protocolo de
comunicação?
ora é
g
a
s
a
m
,
k
O
esse
r
a
s
u
o
s
i
c
pre
um
cliente em
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 X
ML?
<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>
r
a
s
i
c
e
r
p
Vamos
as
m
u
g
l
a
de
ts
constan
.
strings…
main.xml
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>
strings.xml
Layout
do
Cliente
<?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>
main.xml
E como
implementa
ra
atividate?
@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);
Essa ativid
ade
((Bu|on)
findViewById(R.id.read))
precisa de
.setOnClickListener(new
Bu|on.OnClickListener()
{
p
ermissões
public
void
onClick(View
arg0)
{
especiais. Q
uais?
String
strId
=
txtId.getText().toString();
long
id
=
Long.parseLong(strId);
Dao1
d
=
new
Dao1();
E como
Student
s
=
d.get(id);
icamos que
d
n
i
txtName.setText(s.name);
s permissões
a
s
s
e
txtGrade.setText(String.valueOf(s.grade));
s?
a
i
r
á
s
s
e
c
e
n
o
sã
}
});
}
AulaAcBvity9.java
manifest.xml
Manifesto!
Agora temo
s de
testar noss
a
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
•  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!
A mágica de programar
para as interfaces.
nte
Simplesme
sse
e
a
r
a
p
o
d
n
olha
ível
s
s
o
p
é
o
ã
n
código,
eto é
j
b
o
o
e
u
q
r
sabe
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 us
ar o
cliente!
Testando
a
Aplicação
Precisamos
implementa
r os
outros méto
dos:
add, update
,
delete.
Mas o nosso
programa possui
várias falhas de
projeto! Quais?
Existem
Mas também
falhas no
existem falhas
servidor… 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.
ício
d
r
e
p
s
e
d
Que
é esse?
Analisando
a
Camada
de
Comunicação
public
Student
get(Long
key)
{
Há um grande
Student
s
=
null;
Socket
socket;
desperdício de
ObjectOutputStream
out;
recursos aqui.
ObjectInputStream
in;
try
{
socket
=
new
Socket("10.0.2.2",
4444);
ício
d
r
e
p
s
e
d
Que
out
=
new
ObjectOutputStream(socket.getOutputStream());
é esse?
in
=
new
ObjectInputStream(socket.getInputStream());
out.writeObject(new
Long(key));
E como reusa
s
=
(Student)
in.readObject();
r os
out.writeObject(new
Long(0L));
canais de
socket.close();
comunicação
?
out.close();
in.close();
Como garantir que
}
catch
(ExcepBon
e)
{
o canal aberto seja
e.printStackTrace();
}
eventualmente
return
s;
fechado?
}
server/server1/Dao1.java
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();
private
void
closeConnecBon()
{
}
try
{
}
out.writeObject(new
Integer(EOF));
out.flush();
socket.close();
out.close();
in.close();
}
catch
(ExcepBon
e)
{
e.printStackTrace();
}
}
server/server2/Invoker.java
s
Quais os campo
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;
Quais são as
private
ObjectOutputStream
out
=
null;
es
responsabilidad
private
ObjectInputStream
in
=
null;
do DAO?
public
Invoker(String
host,
int
port)
{
this.host
=
host;
this.port
=
port;
}
private
void
closeConnecBon()
{}
private
void
openConnecBon()
{}
public
void
invoke()
{}
}
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;
}
Qual é o protocolo
public
Student
get(Long
key)
{
de comunicação?
Student
s
=
null;
try
{
out.writeObject(new
Integer(DAO.GET));
out.writeObject(new
Long(key));
s
=
(Student)
in.readObject();
Que constante é
out.flush();
essa aqui? Para
}
catch
(ExcepBon
e)
{
que ela serve?
e.printStackTrace();
}
return
s;
}
}
O
Novo
DAO
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
O
Novo
DAO
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();
}
}
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();
}
}
public
void
delete(Long
key)
{
try
{
out.writeObject(new
Integer(DAO.DELETE));
out.writeObject(new
Long(key));
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()));
public
Student
get(Long
key)
{
break;
case
DAO.DELETE:
Student
s
=
null;
delete((Long)
in.readObject());
if
(students.containsKey(key))
{
break;
case
DAO.UPDATE:
s
=
students.get(key);
update((Long)
in.readObject(),
(Student)in.readObject());
break;
}
else
{
case
DAO.ADD:
s
=
new
Student(‐1,
"",
0.0);
add((Long)
in.readObject(),
(Student)in.readObject());
break;
}
default:
return
s;
isWorking
=
false;
return;
}
}
request
=
(Integer)
in.readObject();
}
out.close();
private
Socket
socket
=
null;
in.close();
Fecho,
mas
private
Map<Long,
Student>
students;
socket.close();
onde
abro?
}
catch
(ExcepBon
e)
{
private
ObjectOutputStream
out;
e.printStackTrace();
private
ObjectInputStream
in;
}
}
O
Servidor
server/server2/StudentHandlerThread.java
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;
Temos, é claro,
case
DAO.DELETE:
outros métodos
delete((Long)
in.readObject());
break;
para
case
DAO.UPDATE:
implementar…
update((Long)
in.readObject(),
(Student)in.readObject());
break;
case
DAO.ADD:
add((Long)
in.readObject(),
(Student)in.readObject());
break;
default:
public
StudentHandlerThread(Socket
socket,
Map<Long,
Student>
students)
{
isWorking
=
false;
System.out.println("Got
conecBon!");
return;
this.socket
=
socket;
}
this.students
=
students;
request
=
(Integer)
in.readObject();
try
{
}
out
=
new
ObjectOutputStream(socket.getOutputStream());
out.close();
in
=
new
ObjectInputStream(socket.getInputStream());
in.close();
}
catch
(ExcepBon
e)
{
socket.close();
e.printStackTrace();
}
catch
(ExcepBon
e)
{
}
e.printStackTrace();
}
}
}
O
Servidor
server/server2/StudentHandlerThread.java
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);
}
server/server2/StudentHandlerThread.java
gora,
Prcisamos, a
vo
escrever o no
cliente.
Temos quatro
eventos para tratar.
Quais são eles?
E como seria o
layout do novo
programa?
Quatro
Botões
m
Como fazer u
?
layout assim
Quantos layouts
lineares temos aqu
i?
E como seria a
e?
atividade client
s
Quantos evento
precisam ser
tratados?
Layout
Escreva agora a
classe que
a
implementa ess
atividade.
<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>
client.xml
<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>
@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);
Já podemos
Dao6
d
=
new
Dao6();
testar nossa
i.invoke(d,
this);
}
aplicação!
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);
class
GetCmd
implements
Command,
Bu|on.OnClickListener
{
}
public
void
onClick(View
arg0)
{
}
Invoker
i
=
new
Invoker(DAO.HOST,
DAO.PORT);
iva é
t
a
Dao6
d
=
new
Dao6();
n
r
e
t
l
a
a
s
s
E
nte. i.invoke(d,
this);
a
d
n
u
d
e
r
o
t
i
mu
}
public
void
execute(Dao6
d)
{
String
strId
=
txtId.getText().toString();
long
id
=
Long.parseLong(strId);
Como fatora
r
Student
s
=
d.get(id);
onClick(…)
?
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);
dores
a
t
a
r
t
s
o
s
o
d
To
o usar
ã
v
o
t
n
e
v
e
e
d
lick
C
n
o
o
d
o
t
é
m
esse
public
void
onClick(View
arg0)
{
Invoker
i
=
new
Invoker(DAO.HOST,
DAO.PORT);
Dao6
d
=
new
Dao6();
i.invoke(d,
this);
Eles terão somente
Como seria o
}
de implementar o
tratador do e
método execute.
}
vento
de adição de
novo
dado?
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);
}
}
il:
Agora está fác
como ficaria o
comando para
ID?
m
u
r
a
s
i
u
q
s
e
p
getCmd
Client2.java
class
GetCmd
extends
AbstractCommand
implements
Command
{
public
void
execute(Dao6
d)
{
String
strId
=
txtId.getText().toString();
ara
long
id
=
Long.parseLong(strId);
E o comando p
em?
t
i
m
u
r
a
z
i
l
a
u
Student
s
=
d.get(id);
at
txtName.setText(s.name);
txtGrade.setText(String.valueOf(s.grade));
}
}
Não se es
queçam d
o
comando
par
apagar um a
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:

Download