UNIVERSIDADE DO ESTADO DO AMAZONAS - UEA
ESCOLA SUPERIOR DE TECNOLOGIA
ENGENHARIA DE COMPUTACAO
VICTOR MATHEUS DE SOUZA PEREIRA
DESENVOLVIMENTO DE UM JOGO
MULTIUSUARIO UTILIZANDO ANDROID
Manaus
2012
VICTOR MATHEUS DE SOUZA PEREIRA
DESENVOLVIMENTO DE UM JOGO MULTIUSUARIO UTILIZANDO
ANDROID
Trabalho de Conclusao de Curso apresentado
a banca avaliadora do Curso de Engenharia
de Computacao, da Escola Superior de
Tecnologia, da Universidade do Estado do
Amazonas, como pre-requisito para obtencao
do tıtulo de Engenheiro de Computacao.
Orientador: Prof. M. Sc. Jucimar Maia da Silva Junior
Manaus
2012
ii
Universidade do Estado do Amazonas - UEA
Escola Superior de Tecnologia - EST
Reitor:
Jose Aldemir de Oliveira
Vice-Reitor:
Marly Guimaraes Fernandes Costa
Diretor da Escola Superior de Tecnologia:
Mario Augusto Bessa de Figueiredo
Coordenador do Curso de Engenharia de Computacao:
Daniele Gordiano Valente
Coordenador da Disciplina Projeto Final:
Raimundo Correa de Oliveira
Banca Avaliadora composta por: Data da Defesa: 23 / 06 / 2012.
Prof. M.Sc. Jucimar Maia da Silva Junior (Orientador)
Prof. M.Sc. Raimundo Correa de Oliveira
Prof. M.Sc. Rodrigo Choji de Freitas
CIP - Catalogacao na Publicacao
P436d Pereira, Victor
Desenvolvimento de um Jogo Multiusuario utilizando Android/ Victor
Pereira; [orientado por] Prof. MSc. Jucimar Maia da Silva Junior - Man-
aus: UEA, 2012.
92 p.: il.; 30cm
Inclui Bibliografia
Trabalho de Conclusao de Curso (Graduacao em Engenharia de Com-
putacao). Universidade do Estado do Amazonas, 2012.
CDU: 004
iii
VICTOR MATHEUS DE SOUZA PEREIRA
DESENVOLVIMENTO DE UM JOGO MULTIUSUARIO UTILIZANDO
ANDROID
Trabalho de Conclusao de Curso apresentado
a banca avaliadora do Curso de Engenharia
de Computacao, da Escola Superior de
Tecnologia, da Universidade do Estado do
Amazonas, como pre-requisito para obtencao
do tıtulo de Engenheiro de Computacao.
Aprovado em: 23 / 06 / 2012BANCA EXAMINADORA
Prof. Jucimar Maia da Silva Junior, Mestre
UNIVERSIDADE DO ESTADO DO AMAZONAS
Raimundo Correa de Oliveira, Mestre
UNIVERSIDADE DO ESTADO DO AMAZONAS
Rodrigo Choji de Freitas, Mestre
UNIVERSIDADE DO ESTADO DO AMAZONAS
iv
Agradecimentos
E com muita emocao, apos um ano de dedi-
cacao, os agradecimentos que ofereco as pes-
soas que se encontravam ao meu redor e fiz-
eram com que eu permanecesse e enfrentasse
qualquer obstaculo:
A Deus, por ter me proporcionado essa opor-
tunidade.
A minha mae Silene Martins e ao meu irmao
Jamil Junior, que sempre confiaram no meu
potencial apesar de toda dificuldade por qual
passamos.
Ao meu grande amigo e parceiro Ronny Mar-
tins, por ter me acompanhado durante essa
jornada.
Ao meu orientador, Prof. Msc. Jucimar
Junior, e a todos os meus professores, que me
ensinaram e contribuıram para o meu cresci-
mento profissional.
E a todos os meus amigos, aos quais me
ausentei por diversas vezes, mas sempre me
compreenderam e me deram toda forca.
v
Resumo
Este trabalho apresenta o desenvolvimento de um jogo da velha multiusuario usando a
plataforma Android. O jogo, nomeado de OX Game, permite que dois usuarios joguem,
um contra o outro, partidas utilizando as regras do jogo da velha tradicional. A plataforma
Android e uma plataforma aberta voltada para dispositivos moveis e que possui um kit de
desenvolvimento proprio, utilizando a linguagem de programacao Java. O jogo OX Game
implementa a arquitetura cliente-servidor e a comunicacao existente entre os jogadores e
realizada a partir de fluxos de entrada e saıda de dados conhecidos como sockets.
Palavras-Chave: jogo, jogo da velha, Android, arquitetura cliente-servidor, sockets,
comunicacao em rede, java.
vi
Abstract
This work presents the development of a multiplayer tic-tac-toe game using the Android
platform. This game, named by Ox Game, lets two users play the tic-tac-toe against each
other using the traditional rules. The Android platform is an open source platform for
mobile devices and it has a development kit itself, using the programming language Java.
The game OX Game implements the client-server architecture and the communication
between players is made by input and output data stream known as sockets.
Keywords: game, tic-tac-toe, Android, client-server architecture, sockets, network com-
munication, java.
vii
Sumario
Lista de Figuras ix
1 Introducao 1
1.1 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Especıficos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Justificativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Estrutura do Trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Plataforma Android 5
2.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Open Handset Alliance (OHA) . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Licenca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4 Arquitetura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5 Seguranca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Caracterısticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7 O Kit de Desenvolvimento de Software - SDK . . . . . . . . . . . . . . . . 12
3 Programacao Distribuıda usando Android 15
3.1 Componentes das Aplicacoes em Android . . . . . . . . . . . . . . . . . . . 15
3.1.1 Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.2 Broadcast e Intent Receivers . . . . . . . . . . . . . . . . . . . . . . 20
3.1.3 Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.1.4 Content Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2 Programacao Distribuıda usando Android . . . . . . . . . . . . . . . . . . 22
3.2.1 Arquitetura Cliente-Servidor . . . . . . . . . . . . . . . . . . . . . . 23
3.2.2 Arquitetura Ponto-a-Ponto . . . . . . . . . . . . . . . . . . . . . . . 24
3.3 Servicos de Comunicacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
viii
3.3.1 Implementando um servidor utilizando Sockets de fluxo . . . . . . . 26
3.3.2 Implementando um cliente utilizando Sockets de fluxo . . . . . . . . 28
3.3.3 Estabelecendo uma comunicacao utilizando a arquitetura cliente-
servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4 Desenvolvimento 34
4.1 Etapas de Desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.2 O Projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.3 Jogo da Velha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.3.1 Regras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.4 Arquitetura do Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.5 Modelagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.6 Codificando o Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.6.1 Codificando o cliente . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.6.2 Codificando o Servidor . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.7 Imagens do Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5 Conclusao 75
5.1 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Referencias Bibliograficas 77
ix
Lista de Figuras
2.1 Membros da Open Handset Alliance - OHA . . . . . . . . . . . . . . . . . 8
2.2 Arquitetura da Plataforma Android . . . . . . . . . . . . . . . . . . . . . . 10
3.1 Exemplo de um projeto Android . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2 Ciclo de vida de uma Activity . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3 Diagrama representando a arquitetura cliente-servidor . . . . . . . . . . . . 24
3.4 Diagrama representando a arquitetura ponto-a-ponto . . . . . . . . . . . . 25
3.5 Servidor aguardando uma requisicao de conexao . . . . . . . . . . . . . . . 31
3.6 Confirmacao de conexao do cliente com o servidor . . . . . . . . . . . . . . 32
3.7 Confirmacao de fluxo de dados no servidor . . . . . . . . . . . . . . . . . . 32
3.8 Exemplo de um projeto Android . . . . . . . . . . . . . . . . . . . . . . . . 33
4.1 Tabuleiro 3x3 e sımbolos padroes utilizados no Jogo da Velha . . . . . . . . 36
4.2 Possibilidade de Vitoria no Jogo da Velha . . . . . . . . . . . . . . . . . . 37
4.3 Arquitetura do Jogo OX Game . . . . . . . . . . . . . . . . . . . . . . . . 37
4.4 Diagrama de Casos de Uso do Jogo da Velha OX Game . . . . . . . . . . . 40
4.5 Diagrama de Atividades do Jogo da Velha OX Game . . . . . . . . . . . . 41
4.6 Diagrama de Classes do Jogo da Velha OX Game referente ao Cliente . . . 43
4.7 Diagrama de Classes do Jogo da Velha OX Game referente ao Servidor . . 44
4.8 Localizacao dos arquivos XML no projeto OX Game . . . . . . . . . . . . 47
4.9 Primeira parte da tela do Jogo OX Game . . . . . . . . . . . . . . . . . . . 49
4.10 Primeira e segunda parte da tela do Jogo OX Game . . . . . . . . . . . . . 51
4.11 Primeira, segunda e terceira parte da tela do Jogo OX Game . . . . . . . . 52
4.12 Tela do Jogo OX Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.13 Menu principal do jogo OX Game . . . . . . . . . . . . . . . . . . . . . . . 54
4.14 Diagrama de sequencia do fluxo de dados do jogo OX Game . . . . . . . . 67
4.15 Fluxo de telas do jogo OX Game . . . . . . . . . . . . . . . . . . . . . . . 69
4.16 Tela de Aplicativos do Android . . . . . . . . . . . . . . . . . . . . . . . . 70
x
4.17 Tela de Apresentacao do Jogo . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.18 Menu principal do jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.19 Tela de selecao de nıvel e Tela de insercao do nome do jogador . . . . . . . 72
4.20 Tela do jogo da velha e Tela de opcoes durante uma partida . . . . . . . . 72
4.21 Tela com a lista de jogadores online . . . . . . . . . . . . . . . . . . . . . . 73
4.22 Aviso de desafio a um jogador . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.23 Tela referente ao resultado do jogo . . . . . . . . . . . . . . . . . . . . . . 74
xi
Lista de Codigos
3.3.1 Codigo de criacao de um objeto ServerSocket . . . . . . . . . . . . . . . . . 26
3.3.2 Codigo responsavel por gerenciar requisicoes de conexao . . . . . . . . . . . 27
3.3.3 Codigo de criacao dos objetos OutputStream e InputStream no Servidor . 27
3.3.4 Codigo exemplo de processamento de fluxo de dados . . . . . . . . . . . . . 28
3.3.5 Codigo de finalizacao dos fluxos de dados e Socket no Servidor . . . . . . . 28
3.3.6 Codigo de criacao do Socket no Cliente . . . . . . . . . . . . . . . . . . . . 29
3.3.7 Codigo de criacao dos objetos OutputStream e InputStream no Cliente . . 29
3.3.8 Codigo exemplo de processamento de fluxo de dados no Cliente . . . . . . 29
3.3.9 Codigo exemplo de processamento de fluxo de dados no Cliente . . . . . . 29
3.3.10Codigo fonte referente a implementacao do servidor . . . . . . . . . . . . . 30
3.3.11Codigo fonte referente a implementacao do cliente . . . . . . . . . . . . . . 31
4.6.1 Codigo fonte referente a implementacao do cliente . . . . . . . . . . . . . . 46
4.6.2 Declaracao das caracterısticas do arquivo telaJogo.xml . . . . . . . . . . . 48
4.6.3 Codificacao da primeira parte da tela do Jogo OX Game . . . . . . . . . . 48
4.6.4 Codificacao de um botao do tabuleiro 3x3 do Jogo OX Game . . . . . . . . 49
4.6.5 Codificacao do tabuleiro 3x3 do Jogo OX Game . . . . . . . . . . . . . . . 50
4.6.6 Codificacao do placar do Jogo OX Game . . . . . . . . . . . . . . . . . . . 51
4.6.7 Codificacao dos detalhes de design do Jogo OX Game . . . . . . . . . . . . 52
4.6.8 Requisicao de conexao ao Servidor . . . . . . . . . . . . . . . . . . . . . . . 54
4.6.9 Descricao dos metodos criarConexao(ip, porta) e conectar() . . . . . . . . . 55
4.6.10Classe responsavel por aguardar o desafio de um oponente . . . . . . . . . 56
4.6.11Loop responsavel pela analise das mensagens enviadas pelo servidor . . . . 57
xii
4.6.12Metodo responsavel por avisar o jogador de um desafio e iniciar uma nova
partida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.6.13Construtor da classe Partida localizada no servidor . . . . . . . . . . . . . 58
4.6.14Metodo responsavel pelo clique de uma jogada no tabuleiro . . . . . . . . . 58
4.6.15Classe concorrente Analisador . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.6.16Metodo avisarTerminou(boolean terminou) . . . . . . . . . . . . . . . . . . 60
4.6.17Loop de recebimento de jogadas na classe Mensageiro . . . . . . . . . . . . 60
4.6.18Metodo avisarReultado(String resultado) . . . . . . . . . . . . . . . . . . . 61
4.6.19Metodo desconectar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.6.20Metodo desconectar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.6.21Inicializacao do servidor em uma porta especificada . . . . . . . . . . . . . 62
4.6.22Metodo desconectar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.6.23Codigo que distingue qual o tipo de jogador . . . . . . . . . . . . . . . . . 64
4.6.24Construtor da classe Partida . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.6.25Metodo run() responsavel pela rotina do jogo . . . . . . . . . . . . . . . . 65
4.6.26Metodo lerJogada() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.6.27Metodo desativarJogadaOponente(int pos) . . . . . . . . . . . . . . . . . . 65
4.6.28Metodo trocarJogador(Jogador jogador) . . . . . . . . . . . . . . . . . . . 66
4.6.29Metodo desconectar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.6.30Metodo desconectar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Capıtulo 1
Introducao
O mercado de celulares esta crescendo cada vez mais. Estudo realizado no ano de 2011
pela empresa Teleco - Inteligencia em Telecomunicacoes, mostra que ja existiam mais
de 6 bilhoes de celulares, isso corresponde a mais ou menos um celular por pessoa no
mundo[Teleco2012]. O crescimento do numero de celulares e caracterizado pela busca dos
usuarios por diversos recursos como musicas, interface visual, jogos, GPS, acesso a internet
e e-mails, camera e ainda TV digital[Lecheta2010].
Segundo Lecheta, o mercado corporativo tambem esta crescendo muito, e diversas em-
presas estao buscando incorporar aplicacoes moveis ao dia-a-dia no intuito de agilizar nego-
cios. Dessa forma, empresas e desenvolvedores focam em desenvolver aplicativos que visam
negocios e lucros enquanto os usuarios buscam dispositivos moveis que abragem as neces-
sidades do cotidiano[Lecheta2010].
Os celulares smartphones, celulares com funcionalidades avancadas que podem ser es-
tendidas por meio de programas executados por seu sistema operacional, estao tendo um
diferencial quanto aos celulares das geracoes passadas. Todo esse diferencial pode ser no-
tado por meio das melhorias que vem acontecendo em hardware, como telas maiores e uma
resolucao melhor, e em software, com CPUs mais rapidas ajudando na melhoria de desem-
penho. Alem disso, vale ressaltar que esses celulares sao capazes de se conectar a Internet
pelos varios tipos de conexao (GSM, GPRS, 3G, WiFi) alem de prover de diversos meios
alternativos como tela touchscreen, GPS, camera, etc.
Dentre as areas de interesse dos usuarios, os jogos vem despertando a atencao dos mais
Objetivo 2
variados grupos de pessoas. Permitir que um usuario jogue jogos online com seus amigos
ou qualquer tipo de pessoa, e um entreternimento bastante complexo de ser oferecido, pois
o maior desafio e construir jogos multiusuarios. O indıce de procura de jogos multiusuarios
vem crescendo cada vez mais, pois pessoas jogam colaborando um com os outros ou com-
petindo um com o outro, utilizando o mesmo ambiente, conectados por algum tipo de
rede[Geek2012].
A area de jogos e, principalmente, as aplicacoes de jogos para dispositivos moveis sao
estimulantes pela complexidade dos desafios tecnologicos que apresentam e pelo potencial
de aplicabilidade que existe. O sistema operacional Android[Android2012], que surgiu
voltado para esse avanco tecnologico, permite a construcao de jogos desse tipo. Esse sistema
operacional vem conquistando o mercado[NotTec2012] e proporcionando experiencias aos
usuarios e desenvolvedores, pois e um sistema que engloba as necessidades do cotidiano e
eopen source, facilitando o desenvolvimento de aplicacoes.
1.1 Objetivo
O objetivo desse trabalho e desenvolver um jogo multiusuario utilizando a plataforma
Android. O jogo e baseado no jogo tradicional e popular Jogo da Velha, no qual permite
a comunicacao entre os jogadores a partir das jogadas realizadas.
1.1.1 Especıficos
• Aplicar as regras do jogo da velha na construcao de um jogo multiusuario.
• Aplicar os conceitos da plataforma Android no desenvolvimento do jogo da velha.
• Aplicar o conceito de sockets na comunicacao de dados do jogo.
• Desenvolver o prototipo de uma biblioteca de comunicacao multiusuario por meio de
sockets.
Justi�cativa 3
1.2 Justificativa
Os jogos multiusuarios sao considerados jogos divertidos por permitirem que pessoas
joguem entre si sem ser necessario estarem proximos um dos outros. Alem disso, a imple-
mentacao de um jogo multiusuario requer a analise e decisao de como o jogo sera implemen-
tado. Ao desenvolver um jogo desse tipo, ha a necessidade de se ater a varios problemas
inerentes ao dispositivo em que e utilizado, como limitacao de memoria, recursos e pro-
cessamento, tamanho da tela e mecanismo de entrada nao apropriada, acrescido, ainda,
das dificuldades inerentes no desenvolvimento de sistemas distribuıdos de tempo real como
tempo de resposta, sincronia de instrucoes, entre outros. Desenvolver um jogo multiusuario
e complexo por envolver muitas areas de conhecimento e, ao mesmo tempo, um desafio para
quem possui conhecimentos na area de computacao.
Esse trabalho se destaca por abordar problemas de infraestrutura de desenvolvimento
de componentes relacionados a jogos em dispositivos moveis e se enquadra em uma area
de pesquisa bem recente, denominada jogos computacionais, que vem despertando muito
interesse da comunidade cientıfica e de empresas, por revolucionar substancialmente as
aplicacoes de entretenimento digital. No Brasil, a area de desenvolvimento de jogos ainda
esta em processo de evolucao, mas e bastante promissora do ponto de vista de empresas,
universidades e em outras areas do conhecimento[Geek2012].
1.3 Metodologia
O projeto adota a seguinte metodologia de trabalho:
• Estudar e Implementar os conceitos da plataforma Android
• Projetar as telas que o jogo possui.
• Elaborar o fluxo das telas projetadas.
• Implementar uma interface grafica para o jogo da velha utilizando XML
• Modelar o jogo utilizando a engine do jogo da velha
• Implementar o nıvel basico para o jogo da velha
Estrutura do Trabalho 4
• Implementar o nıvel avancado para o jogo da velha
• Implementar o conceito de multiusuario no jogo da velha utilizando socket
• Executar e testar o jogo em dispositivos moveis.
1.4 Estrutura do Trabalho
Nesse trabalho, e apresentado o jogo multiusuario OX Game. No capıtulo 2, a
plataforma Android, plataforma utilizada pelo jogo, e descrita, informando o tipo de
plataforma, o kit de desenvolvimento disponıvel, a linguagem de programacao utilizada,
entre outros. No capıtulo 3, a comunicacao de dados entre dispositivos moveis e o foco. No
capıtulo 4, o desenvolvimento do jogo e tratado e, por fim, no capıtulo 5, uma conclusao e
apresentada assim como sugestoes de futuros desenvolvimentos utilizando o jogo OX Game
como base.
Capıtulo 2
Plataforma Android
O Android e uma plataforma completa para dispositivos moveis em geral, contendo
um sistema operacional baseado em Linux, middleware, aplicativos e interface de
usuario[Pereira2009].
2.1 Historia
A tecnologia voltada aos dispositivos moveis esta se desenvolvendo cada vez mais e
os seus usuarios buscam um dispositivo que melhor atenda as necessidades do cotidiano.
Com base nesse cenario, Andy Rubin (co-fundador da Danger), Rich Miner (co-fundador
da Wildfire Communications, Inc.), Nick Sears (vice-presidente da T-Mobile) e Chris White
(lıder de projeto e desenvolvimento de interface na WebTV ) fundaram em outubro de 2003,
na cidade de Palato Alto, California, Estados Unidos, a Android, Inc. Inicialmente, pouco
se sabia sobre a Android, Inc. em virtude de operarem secretamente e apenas informarem
que estavam trabalhando em software para celulares.
Em julho de 2005, o Google adquiriu a Android, Inc. e os co-fundadores Andy Rubin,
Rich Miner, Nick Sears e Chris White passaram a fazer parte desse novo time. Enquanto
suposicoes surgiam de que o Google estaria planejando competir no mercado de dispositivos
moveis, o time liderado por Rubin tentava desenvolver uma plataforma poderosa baseado
no kernel do Linux e com a premissa de prover flexibilidade, tornando-o um sistema aberto
História 6
e de facil atualizacao.
Segundo Nunes, especulacoes sobre a intencao do Google em entrar no mercado de
comunicacoes moveis continuaram a surgir ate dezembro de 2006. Houveram rumores de
que o Google estaria desenvolvendo um celular com a sua marca, definindo especificacoes
tecnicas e mostrando prototipos para os fabricantes de celular e operadores de telefonia
movel. Alem disso, em setembro de 2007, a InformationWeek cobriu um estudo da Evalue-
serve reportando que o Google apresentou varios pedidos de patentes na area de telefonia
movel[Nunes2011].
Por volta de dois meses apos o estudo levantado pela InformationWeek, no dia 05 de
novembro de 2007, um grupo formado por grandes empresas do mercado de telefonia movel,
sob nome Open Handset Alliance (OHA), e criado e liderado pelo Google. Dentre as varias
empresas, destacam-se a Texas Instruments, Broadcom Corporation, Google, HTC, Intel,
LG, Marvell Technology, Motorola, Nvidia, Qualcomm, Samsung Electronics, Sprint Nextel
e T-Mobile. Segundo Lecheta, no site da OHA existe uma otima descricao do que seria
essa alianca: ”Hoje, existem 1,5 bilhoes de aparelhos de televisao em uso em todo o mundo
e 1 bilhao de pessoas tem acesso a Internet. No entanto, quase 3 bilhoes de pessoas tem um
telefone celular, tornando o aparelho um dos produtos de consumo mais bem sucedidos do
mundo. Dessa forma, construir um aparelho celular superior melhoraria a vida de inumeras
pessoas em todo o mundo. A Open Handset Alliance e um grupo formado por empresas
lıderes em tecnologia movel que compartilham essa visao para mudar a experiencia movel
de todos os consumidores[...].”[Lecheta2010]. Assim, o objetivo do grupo era definir uma
plataforma unica e aberta para celulares de modo a deixar os consumidores mais satisfeitos
com o produto final alem de criar uma plataforma moderna, flexıvel para o desenvolvimento
de aplicacoes coorporativas.
Como resultado da OHA, seu primeiro produto consistiu na plataforma Android, uma
plataforma de desenvolvimento para aplicacoes moveis com sistema operacional baseado
no kernel 2.6 do Linux, interface visual, diversas aplicacoes instaladas e um ambiente
de desenvolvimento inovador, flexıvel e poderoso. Essa nova plataforma surgiu a partir
do projeto Android Open Source Project (AOSP) e tem sido acompanhada com diversas
manutencoes e atualizacoes[Lecheta2010][Nunes2011].
Open Handset Alliance (OHA) 7
2.2 Open Handset Alliance (OHA)
O Android surgiu da parceria do Google com a Open Handset Alliance (OHA), uma
alianca onde figuram as principais empresas do mercado movel mundial. Segundo Pereira,
essa alianca possui a seguinte estrutura[Pereira2009]:
• Operadoras de telefonia movel: responsavel pela conexao, fornecem o servico
para o usuario final;
• Fabricantes de aparelhos: responsaveis pela criacao do hardware;
• Empresas Semicondutores: fazem os chips dos aparelhos celulares;
• Empresas de software: desenvolvem os softwares que serao executados no An-
droid;
• Empresas de comercializacao: responsaveis pela divulgacao, marketing e comer-
cializacao dos produtos para o usuario.
No sıtio oficial da OHA, e possıvel verificar as 84 empresas que compoem a alianca,
conforme figura 2.1:
Open Handset Alliance (OHA) 8
Figura 2.1: Membros da Open Handset Alliance - OHA
Licença 9
2.3 Licenca
O codigo fonte do Android esta disponıvel sob licencas livres e de plataforma aberta.
O Google publica a maior parte dos codigos fontes sob a Licenca Apache versao 2.0 e o
restante, as mudancas do kernel do Linux, sob a Licenca GNU General Public License
versao 2.0. A OHA desenvolve modificacoes ao kernel do Linux a parte, com codigo fonte
disponıvel publicamente a qualquer momento, sob licenca GPL do Android. O resto do
Android e desenvolvido em particular, com codigo fonte liberado publicamente quando
uma nova versao principal e lancada. A unica versao cujo cogido fonte nao foi publicado
apos um lancamento de um nova versao foi a Honeycomb. Como justificativa, o Google
informou que a versao havia sido lancada de forma rapida e que era direcionada a tabletes,
evitando que os usuarios a utilizassem em celulares ate a mesclagem das funcionalidades
dessa versao com a versao destinada a celulares que viria posteriomente. Com o lancamento
da versao Ice Cream Sandwich, o codigo fonte foi liberado e assim eliminou as duvidas sobre
o compromisso com o codigo aberto do Android[Nunes2011].
2.4 Arquitetura
A arquitetura da plataforma Android esta estruturada conforme figura 2.2:
Arquitetura 10
Figura 2.2: Arquitetura da Plataforma Android
Segundo Schemberger, a arquitetura da plataforma Android e dividida em quatro ca-
madas: Kernel GNU Linux, bibliotecas, framework para aplicacoes e as proprias apli-
cacoes - alem da porcao runtime, necessaria para a execucao dos aplicativos no disposi-
tivo[Schemberger2012].
Todo o gerenciamento dos processos, threads, arquivos, pastas, redes e drivers dos
dispositivos sao gerenciados pelo kernel 2.6 do Linux, a camada mais baixa da arquite-
tura. O runtime do Android e construıdo em cima do kernel 2.6 do Linux e e respon-
savel por criar e executar aplicacoes Android. Cada aplicacao e executada em seu proprio
processo e com a propria maquina virtual chamada Dalvik. As aplicacoes Android sao
compactadas em um arquivo de formato .apk e armazenadas na pasta de aplicativos
chamada dados, no sistema operacional Android. Essa pasta e acessıvel apenas para o
usuario root por razoes de seguranca. As bibliotecas de sistema sao as responsaveis por
tarefas computacionalmente pesadas, como renderizacao grafica, reproducao de audio e
Segurança 11
acesso ao banco de dados, que nao seria adequado para a maquina virtual Dalvik, e a
camada de aplicacao, por sua vez, reune as bibliotecas de sistema e o runtime. Essa
camada gerencia as aplicacoes e fornece um framework elaborado no qual as aplicacoes
funcionam[Lecheta2010][Pereira2009][Schemberger2012].
2.5 Seguranca
Devido o sistema operacional do Android ser baseado no kernel 2.6 do Linux, a se-
guranca do Android e baseada na seguranca do Linux. Toda vez que um aplicativo e
instalado em um dispositivo Android, um novo usuario Linux e criado para aquele pro-
grama. Cada aplicativo no Android inicia um novo e unico processo no sistema opera-
cional, sendo que cada processo possui uma thread especıfica para sua execucao. Esses
processos sao nomeados de sandbox, um mecanismo de seguranca que separa os progra-
mas em execucao em um ambiente isolado, com acesso limitado aos recursos do sistema
e com diretorios que serao usados pelo aplicativo e somente pelo usuario Linux corre-
spondente. Como os aplicativos ficam completamente isolados uns dos outros, qualquer
tentativa de acessar informacoes de outro aplicativo e necessario ser explicitamente autor-
izado pelo usuario, podendo ser negado a instalacao do aplicativo ou autorizado a insta-
lacao[Pereira2009][Lecheta2010][Schemberger2012][Nunes2011].
2.6 Caracterısticas
Segundo Pereira, o Android e uma plataforma para a tecnologia movel completa, en-
volvendo um pacote com programas para celulares, ja com um sistema operacional, mid-
dleware, aplicativos e interface do usuario. Foi construıda para ser verdadeiramente aberta
e com intencao de permitir aos seus desenvolvedores criar aplicacoes moveis que possam
tirar proveito do que um aparelho portatil possa oferecer[Pereira2009].
Por possuir uma plataforma aberta, diversas atualizacoes sao realizadas de modo a in-
corporar novas tecnologias conforme as necessidades surgem. Cada atualizacao no Android
refere-se a solucao de algum bug ou a adicao de alguma funcionalidade nova. Cada versao
e nomeada alfabeticamente por nomes de sobremesa:
O Kit de Desenvolvimento de Software - SDK 12
• Versao 1.5 - Cupcake
• Versao 1.6 - Donut
• Versao 2.0 - Eclair
• Versao 2.2 - Froyo
• Versao 2.3 - Gingerbread
• Versao 3.0/ 3.1/ 3.2 - Honeycomb
• Versao 4.0 - Ice Cream Sandwich
A versao 1.5 (Cupcake) adicionou suporte a bibliotecas nativas as aplicacoes Android,
que antes eram restritas a serem escritas em Java puro. Codigo nativo pode ter muitos
benefıcios em situacoes onde o desempenho e o mais importante. A versao 1.6 (Donut)
introduziu suporte para diferentes resolucoes de tela. Na versao 2.0 (Eclair) foi adicionado
suporte a telas multi-toques, e na versao 2.2 (Froyo) adicionaram a compilacao just-in-
time (JIT) a maquina virtual Dalvik. O JIT acelera a execucao de aplicacoes Android,
dependendo do cenario, em ate 5 vezes. A versao 2.3 (Gingerbread) adicionou um garbage
collector concorrente ao da maquina virtual Dalvik e refinou a interface de usario, mel-
horando o teclado virtual e acrescentando a funcionalidade copiar-colar. As versoes 3.0/
3.1/ 3.2 (Honeycomb) sao orientadas para tabletes e com suporte para dispositivos de telas
grandes, com multiprocessadores e aceleradores de graficos, sistema de encriptacao com-
pleta, carregamento de mıdia a partir de cartoes de memoria e suporte para dispositivos de
entradas via USB. A versao 4.0 (Ice Cream Sandwich) e a mais recente, anunciada em 19 de
outubro de 2011, e trouxe as funcionalidades da versao 3.0 (honeycomb) para smartphones
alem de incluir desbloqueio por reconhecimento facial, controle e monitoramento de dados
via rede, unificacao de contatos por redes sociais e busca de e-mails offline.
2.7 O Kit de Desenvolvimento de Software - SDK
O kit de desenvolvimento de software(SDK) e a ferramenta principal para desenvolver
aplicacoes utilizando a plataforma Android. O SDK inclui um conjunto abrangente de ferra-
O Kit de Desenvolvimento de Software - SDK 13
mentas de desenvolvimento, incluindo um depurador, bibliotecas, um emulador de terminal
movel (baseada em QEMU - uma maquina virtual de codigo aberto para simular diferentes
plataformas de hardware), documentacao, codigo de exemplo e tutoriais. As plataformas
de desenvolvimento suportadas incluem computadores que executam o Linux (qualquer dis-
tribuicao Linux moderna), Mac OS X 10.4.9 ou superior e Windows XP ou posterior. O am-
biente de desenvolvimento integrado (IDE) suportado oficialmente e o Eclipse (versoes 3.4,
3.5 ou 3.6) usando o Android Development Tools (ADT) Plugin, embora os desenvolvedores
possam usar qualquer editor de texto para editar arquivos Java e XML e, em seguida, usar
ferramentas de linha de comando (Java Development Kit e Apache Ant sao necessarios)
para criar, construir e depurar aplicativos do Android[Lecheta2010][Schemberger2012].
Em 12 de novembro de 2007, ocorreu o pre-lancamento do SDK do Android. Em 15
de Julho de 2008, com o concurso de desenvolvimento de aplicacoes em Android, Android
Developer Challenge, a equipe organizadora acidentalmente enviou um e-mail a todos os
participantes do Android Developer Challenge anunciando que uma nova versao do SDK
estava disponıvel em uma area privada de download. O e-mail era destinado somente
para os vencedores da primeira rodada do concurso. A revelacao de que o Google estava
fornecendo novas versoes do SDK para alguns desenvolvedores e nao para outros, levou
muitos a frustracao, sendo divulgado dentro da comunidade de desenvolvimento para An-
droid.
Em 18 de Agosto de 2008, o Android SDK beta 0.9 foi liberado. Esta versao forneceu
uma API atualizada e ampliada, ferramentas de desenvolvimento melhoradas e um design
atualizado para a tela inicial. Instrucoes detalhadas para a atualizacao estavam disponıveis
para aqueles que ja trabalhavam com uma versao anterior. Em 23 de Setembro de 2008,
o Android SDK 1.0 foi lancado, e de acordo com as notas de lancamento, incluiu princi-
palmente correcoes de bugs alem de terem algumas funcionalidades adicionadas. Varias
versoes foram lancados desde entao.
Melhorias no SDK do Android estao fortemente ligadas com o desenvolvimento da
plataforma Android. O SDK tambem oferece suporte a versoes mais antigas da plataforma,
no caso de desenvolvedores desejarem atingir suas aplicacoes em dispositivos mais antigos.
As ferramentas de desenvolvimento sao componentes de download, sendo assim, depois
de se ter baixado a ultima versao e plataforma, plataformas mais antigas e ferramentas
O Kit de Desenvolvimento de Software - SDK 14
tambem pode ser baixadas para realizar testes de compatibilidade[Schemberger2012].
Segundo Nunes e Schemberger, as caracterısticas gerais do SDK sao:
• O depurador, capaz de depurar aplicacoes executando em um dispositivo ou emulador;
• O profile de memoria e desempenho, que ajudam a encontrar vazamentos de memoria
e identificar trechos de codigo lento;
• O emulador de dispositivos, baseado em QEMU (uma maquina virtual de codigo
aberto para simular diferentes plataformas de hardware), que, apesar de preciso,
pode ser um pouco lento algumas vezes;
• Utilitarios de linha de comando, que comunicam com os dispositivos;
• Scripts prontos e ferramentas para empacotamento e instalacao de apli-
cacoes[Nunes2011][Schemberger2012].
Capıtulo 3
Programacao Distribuıda usando
Android
Um sistema distribuıdo em Android e definido como um sistema no qual os componentes
de uma aplicacao, localizado nos dispositivos moveis, interligados em rede, se comunicam
e coordenam suas acoes apenas enviando e recebendo mensagens entre si.
3.1 Componentes das Aplicacoes em Android
As aplicacoes em Android podem ser divididas em quatro tipos de componentes basicos
que sao definidos pela propria arquitetura[Ableson2007], que sao:
• Activities
• Broadcast e Intent Receivers
• Services
• Content Providers
Nem toda aplicacao precisa possuir todos os tipos de componentes basicos, mas pode
ser construıda a partir de alguma combinacao entre eles. Uma vez decidido quais compo-
nentes sao necessarios para a construcao de um aplicativo, deve-se lista-los em um arquivo
Componentes das Aplicações em Android 16
chamado AndroidManifest.xml. Segundo Pereira, toda aplicacao deve ter um arquivo An-
droidManifest.xml no diretorio raiz. Este arquivo de configuracao descreve os elementos da
aplicacao, as classes de cada componente a ser utilizado, qual o tipo de dado ele pode tratar,
quando pode ser ativado, ou seja, serve para definir os dados de cada elemento[Pereira2009].
Na figura 3.1, a estrutura basica de um projeto Android e representado. O projeto
ClienteAndroid possui a biblioteca de pacotes referente a versao 2.2 do Android, uma pasta
chamada sourcing (src) - contem todas as classes e activities especificadas pelo usuario
(ClienteAndroid, GerenciadorConexoes, Mensageiro e Mensagem), uma pasta chamada
generated Java files (gen)- contem arquivos que consistem em referencias estaticas para
todos os recursos que possam ser referenciadas de forma facil e dinamica a partir do codigo
Java, uma pasta chamada resources (res) - contem todos os recursos do projeto: ıcones,
imagens, cadeias de caracteres e layouts, e o arquivo AndroidManifest.xml.
Figura 3.1: Exemplo de um projeto Android
Componentes das Aplicações em Android 17
3.1.1 Activities
Activity, ou atividade, e uma tela da aplicacao. A maioria das aplicacoes consiste de
varias telas. Por exemplo, uma aplicacao de mensagens de texto, deve possuir uma tela
para exibir a lista de contatos, possıveis destinatarios da mensagem, uma segunda tela
para escrever a mensagem para o contato selecionado, e outras telas para ver as mensagens
antigas e alterar configuracoes. Cada uma dessas telas deve ser implementada como uma
activity. Cada activity e implementada como uma unica classe que estende a classe de
base Activity. Essa classe exibe a interface com o usuario, responde a eventos e segue um
ciclo de vida especıfico. O ciclo de vida de uma activity esta representada conforme figura
3.2[Pereira2009]:
Componentes das Aplicações em Android 18
Figura 3.2: Ciclo de vida de uma Activity
Componentes das Aplicações em Android 19
• OnCreate(): metodo chamado quando a activity e inicialmente criada. E um metodo
obrigatorio, chamado apenas uma vez.
• OnStart(): chamado quando a activity torna-se visıvel para o usuario.
• OnResume(): e o topo da pilha de activity, chamado quando vai iniciar a interacao
com o usuario.
• OnPause(): chamado quando o sistema esta perto de comecar uma proxima activity.
E utilizado para gravar as informacoes que ainda nao foram salvas.
• OnStop(): e chamado quando a activity nao estiver mais sendo utilizada pelo usuario
e perdeu o foco para outra activity.
• OnDestroy(): pode ser chamado quando a activity terminou, ou quando o sistema
precisa finalizar activities para liberacao de recursos.
• OnRestart(): chamado quando a activity esta interrompida e prestes a ser acionada
pelo usuario novamente.
Segundo Lecheta, uma activity tem um ciclo de vida bem definido. Quando uma
activity e iniciada, ela e inserida no topo de uma pilha, chamada de activity stack ou
pilha de atividades, e a activity anterior que estava em execucao permanece abaixo dessa
nova[Lecheta2010].
As activities podem se encontrar em quatro estados[Pereira2009]:
• Executando: a activity esta ativa no visor do dispositivo.
• Parada: uma activity que perdeu o foco para outra, mantendo todas as informacoes
de estado, porem nao esta interagindo com o usuario. Pode, ainda, ser finalizada em
situacoes de baixo nıvel de memoria disponıvel.
• Interrompida: caso uma activity nao esteja sendo utilizada pelo usuario, ela man-
tem as suas informacoes de estado, porem sao muitas vezes finalizadas quando uma
recuperacao de memoria seja necessaria, perdendo informacoes.
Componentes das Aplicações em Android 20
• Finalizada: o sistema pode remover uma activity da memoria, caso esteja interromp-
ida ou parada. O estado anterior so pode ser restaurado se os metodos tiverem sido
implementados pelo desenvolvedor.
Segundo a documentacao do Android, existem tres subnıveis do ciclo de vida principal,
que por sua vez ficam se repetindo durante a execucao da aplicacao. Esses tres ciclos sao
basicamente[AndroidDev2012][Lecheta2010]:
• Entire Lifetime: inicia-se no metodo OnCreate(), onde a activity realiza toda a con-
figuracao, passa de um estado para outro e termina no metodo OnDestroy(), quando
todos os recursos utilizados por esta activity sao liberados.
• Visible Lifetime: inicia-se no metodo OnStart() e termina no metodo OnStop. E
o ciclo onde a activity esta disponıvel e visıvel para o usuaro, mesmo que este nao
esteja interagindo com ela. Quando o usuario nao visualizar mais a activity, o metodo
OnStop() e chamado, ou entao, para colocar a activity visıvel, chama o metodo
OnStart().
• Foreground Lifetime: ocorre entre os metodos OnResume() e OnPause(). Este e o
estado em que a activity esta no topo da pilha de atividades e interagindo com o
usuario. Durante esse ciclo, a activity pode alternar frequentemente entre os estados
executando e pausado, sendo assim, recomendado que o codigo que executa os meto-
dos OnPause() e OnResume() seja leve e rapido, proporcionando a troca dos estados
sem a necessidade de uma requisicao robusta.
3.1.2 Broadcast e Intent Receivers
Brodacast e Intent Receivers sao componentes que ficam aguardando a ocorrencia de
um determinado evento. Um evento, nesse caso, pode ser a inicializacao do sistema op-
eracional, uma chamada de voz, a chegada de um SMS ou um evento disparado por uma
aplicacao[Meier2009].
Intents sao elementos chave no Android porque facilitam a criacao de novas aplicacoes a
partir de aplicacoes ja existentes. A classe Intent interage com outras aplicacoes e servicos
que proporcionam informacoes necessarias para uma aplicacao.
Componentes das Aplicações em Android 21
Segundo Lecheta, uma intent esta presente em todas as aplicacoes Android e representa
a necessidade da aplicacao realizar algum processo. Uma intent e enviada ao sistema op-
eracional como uma mensagem, chamada broadcast. Quando o sistema operacional recebe
essa mensagem, decisoes sao tomadas dependendo do processo a ser realizado. Uma intent
pode ser utilizada para:
• abrir uma nova tela de aplicacao.
• solicitar ao sistema operacional que ligue para determinado numero de celular.
• abrir o browser em um determinado endereco da internet.
• exibir algum endereco, localizacao ou rota no Google Maps.
• executar algum processamento pesado em segunda plano.
• abrir o mercado de aplicativos oficiais do Android (Play Store) para fazer a instalacao
de um determinado aplicativo.
• enviar uma mensagem para outra aplicacao para executar algum outro pro-
cesso[Lecheta2010].
3.1.3 Services
Segundo Pereira, um service, que significa servico, e um codigo sem interfaces de
usuario, que rodam em segundo plano, nao sendo interrompidos quando da troca de ac-
tivities pelo usuario. Ao contrario da activity que tem um ciclo de vida proprio e um
vida curta, os services mantem o servico ativo ate que seja recebida outra ordem. Uma vez
conectado com o servico, pode-se comunicar com este atraves de uma interface apresentada
para o usuario[Pereira2009].
Um bom exemplo e um media player reproduzindo musicas a partir de uma lista de
musicas. Em uma aplicacao deste tipo, ha uma ou mais activities que permitem ao usuario
escolher musicas e reproduzi-las. Entretanto, o playback da musica nao pode ser tratado
por uma atividade, pois o usuario espera que a musica continue tocando mesmo depois que
ele tenha mudado de tela. Neste caso, a atividade do media player pode iniciar um servico
Programação Distribuída usando Android 22
para rodar em segunda plano e manter a musica tocando. O sistema mantem o servico de
playback da musica executando ate que o servico seja terminado.
3.1.4 Content Providers
Segundo Lecheta, o Android permite armazenar diversas informacoes utilizando banco
de dados, arquivos e o sistema de preferencias. Contudo, geralmente essas informacoes
ficam salvas dentro do pacote da aplicacao, e somente a aplicacao que criou o banco de
dados ou o arquivo pode ter acesso as informacoes[Lecheta2010].
Content Provider, ou provedor de conteudos, pode ser interpretado como uma classe que
permite que determinadas informacoes sejam publicas para todas as outras aplicacoes in-
staladas no sistema operacional. Utilizando essa classe, outras aplicacoes podem consultar,
inserir, alterar e excluir informacoes.
3.2 Programacao Distribuıda usando Android
Os aplicativos para Android sao programados na linguagem Java, mas sao compilados
e executados na maquina virtual Dalvik - maquina virtual do sistema operacional Android.
A IDE oficial para desenvolvimento em Android e o Eclipse, que fornece um ambiente Java
rico, incluindo ajuda sensıvel ao contexto e sugestoes de codigos[IBM2012].
Segundo Albuquerque, a linguagem Java apresenta caracterısticas que facilitam a imple-
mentacao de aplicacoes distribuıdas. A linguagem e portatil e independente de plataforma,
isto e, o codigo pode ser desenvolvido em uma plataforma e executado em outra plataforma
diferente. Quando um programa Java e compilado, em vez de ser gerado um codigo desti-
nado a uma plataforma especıfica, e gerado um codigo para uma maquina virtual. Qualquer
maquina pode executar este codigo desde que saiba como interpretar as instrucoes geradas.
Esta e uma abordagem diferente de outras linguagens de programacao onde o codigo fonte
precisa ser compilado para a plataforma onde sera executado. Outra caracterıstica util
da linguagem Java no desenvolvimento de aplicacoes distribuıdas e o suporte a multiplas
threads de execucao. Isto facilita a implementacao, por exemplo, de programas servidores.
Em tais programas pode ser necessario atender simultaneamente a solicitacao de multiplos
Programação Distribuída usando Android 23
clientes[Albuquerque2012].
A programacao distribuıda em Android utiliza classes existentes da linguagem Java e
pacotes de comunicacao em rede disponibilizadas pelo SDK. Esses pacotes sao conhecidos
como interfaces de programacao de aplicativos - APIs (Application Programming Interface)
para comunicacao entre aplicacoes. Essas APIs abstraem muitos dos detalhes de config-
uracao e implementacao necessarios em outras linguagens alem de diminuir o volume de
codigo da aplicacao destinado a aspectos de comunicacao e recursos de rede. Uma API e um
recurso de rede multiuso que permite que os desenvolvedores Java possam criar aplicativos
com esses pacotes. Um exemplo de API de comunicacao, dentre outras, e o Socket.
Segundo Vieira, a arquitetura de um sistema distribuıdo e basicamente definido em
duas: a arquitetura cliente-servidor e a arquitetura ponto-a-ponto. Existem tambem vari-
acoes destas arquiteturas que visam aumentar o desempenho e contornar alguns prob-
lemas ou necessidades especıficas que estes sistemas possam apresentar para diferentes
aplicacoes[Vieira2011].
3.2.1 Arquitetura Cliente-Servidor
A arquitetura Cliente-Servidor e o modelo mais tradicional para aplicacoes online. Essa
arquitetura constitui a maneira mais versatil de distribuir mensagens para um grande
numero de usuarios e e caracterizada por ser centralizada, ou seja, existe um servidor que
possui uma visao completa e permanentemente atualizada de todos os clientes conectados
a ele. Na figura 3.3, pode-se observar um diagrama representando-a:
Programação Distribuída usando Android 24
Figura 3.3: Diagrama representando a arquitetura cliente-servidor
Segundo Andrews, o principal problema desta arquitetura e o excesso de carga deposi-
tada no servidor. Muitas vezes os servidores precisam atender centenas ou milhares de
conexoes, o que exige um significativo esforco computacional. Outro ponto importante e a
natureza centralizada da arquitetura, pois qualquer falha no hardware ou na conectividade
da estacao servidora, todas as conexoes existentes podem ser abortadas[Andrews2000].
3.2.2 Arquitetura Ponto-a-Ponto
A arquitetura ponto-a-ponto e definida por computadores que se encontram em rede e
que estao todos interligados em uma cadeia descentralizada, onde cada um possui funcoes
equivalentes, nao havendo uma hierarquia entre eles. Todos os usuarios sao clientes e
servidores, funcionando, assim, de forma totalmente independente e livre da existencia de
um servidor central. A figura 3.4 mostra a representacao dessa arquitetura:
Serviços de Comunicação 25
Figura 3.4: Diagrama representando a arquitetura ponto-a-ponto
Segundo Vieira, pelo fato dessa arquitetura ser caracterizada como descentralizada e
robusta em relacao aos problemas que afetam a arquitetura cliente-servidor, novos ques-
tionamentos surgem com esta descentralizacao. A largura de banda limitada de cada
”ponto”, a troca de dados entre os ”pontos”, a garantia de autenticidade e seguranca dos
dados sao alguns desses questionamentos. Todavia, uma arquitetura ponto-a-ponto es-
truturada, permite que tecnicas de roteamento e organizacao sejam utilizadas com certa
eficiencia, ao mesmo tempo em que a rede se torne escalavel para uma grande quantidade
de clientes[Vieira2011].
3.3 Servicos de Comunicacao
Aplicacoes distribuıdas usam os servicos de comunicacao providos pela rede atraves de
interfaces de programacao de aplicativos(APIs). Os recursos fundamentais de rede utiliza-
dos pelo Android sao declarados pelas classes e interfaces do pacote java.net, no qual possui
funcoes que permitem o estabelecimento de comunicacoes baseadas em fluxo. Por interme-
Serviços de Comunicação 26
dio dessas comunicacoes, os aplicativos visualizam a rede como um fluxo de dados, ou seja,
enviando e recebendo dados de forma contınua por essa rede[Albuquerque2012][IBM2012].
O Socket e exemplo de servico de comunicacao. Permite que um processo estabeleca
uma conexao com outro processo. Enquanto a conexao estiver no ar, os dados fluem entre
os processos em fluxos contınuos. Pode-se dizer que os Sockets sao baseados em fluxo e que
fornecem um servico orientado para conexao. Essa comunicacao e feita atraves das classes
ServerSocket e Socket. O servidor usa a classe ServerSocket para aguardar conexoes a partir
dos clientes e, quando ocorre a conexao, a comunicacao e efetivada atraves de um objeto
da classe Socket. Estas classes escondem a complexidade presente no estabelecimento de
uma conexao e no envio de dados atraves da rede.
3.3.1 Implementando um servidor utilizando Sockets de fluxo
Implementar um servidor utilizando Sockets de fluxo e que trata as conexoes e se co-
munica com os possıveis clientes requer cinco passos[Deitel2010]:
1. Criar um objeto ServerSocket.
2. Esperar um conexao.
3. Obter os fluxos de entrada e saıda do socket.
4. Realizar o processamento (comunicacao).
5. Fechar a conexao.
No passo 1, deve-se criar um objeto do tipo ServerSocket. A criacao desse objeto e
realizado pela chamada do construtor ServerSocket, demonstrado no codigo 3.3.1:
1 ServerSocket servidor = new ServerSocket( porta, limiteDeConexoes );
Codigo 3.3.1: Codigo de criacao de um objeto ServerSocket
No construtor ServerSocket existem dois parametros. O parametro porta registra o
numero da porta TCP disponıvel para a conexao e o parametro limiteDeConexoes especifica
um numero maximo de clientes que podem esperar para se conectar ao servidor, ou seja, o
Serviços de Comunicação 27
numero maximo de conexoes. O numero da porta e utilizado pelos clientes para localizar
o aplicativo servidor no computador servidor. Isso costuma ser chamado de ponto de
handshake.
No passo 2, o servidor deve gerenciar as requisicoes de conexao dos clientes, para tanto
deve ser criado um objeto do tipo Socket para cada requisicao aceita pelo objeto Server-
Socket. O servidor passa a ouvir indefinidamente uma tentativa de conexao por meio do
metodo ServerSocket accept. Esse metodo encontra-se descrito no codigo 3.3.2:
1 Socket conexao = server.accept();
Codigo 3.3.2: Codigo responsavel por gerenciar requisicoes de conexao
Esse metodo retorna um Socket quando uma conexao com um cliente e estabelecida.
O Socket, entao, permite ao servidor interagir com o cliente. As interacoes com o cliente
ocorrem em uma porta diferente de servidor a partir do ponto de handshake, permitindo,
assim, que a porta especificada no passo 1 seja utilizada novamente em um servidor de
multiplas threads de modo a aceitar outras conexoes.
No passo 3, apos a conexao entre o servidor e o cliente, faz-se necessario que a comu-
nicacao seja possıvel. Desse modo, os objetos do tipo OutputStream e InputStream devem
ser criados de modo a permitir que o servidor se comunique com o cliente enviando e
recebendo bytes. O servidor envia informacoes ao cliente via um objeto OutputStream e
recebe informacoes do cliente via um objeto InputStream. Alem disso, o servidor invoca o
metodo getOutputStream no Socket para obter a referencia ao OutputStream do Socket e
invoca o metodo getInputStream no Socket para obter uma referencia ao InputStream do
Socket. Esse passo encontra-se demonstrado no codigo 3.3.3:
1 ObjectInputStream entradaDeDados = new ObjectInputStream( conexao.getInputStream() );2 ObjectOutputStream saidaDeDados = new ObjectOutputStream( conexao.getOutputStream() );
Codigo 3.3.3: Codigo de criacao dos objetos OutputStream e InputStream no Servidor
No passo 4, a comunicacao e realizada entre o servidor e o cliente via os objetos Out-
putStream e InputStream. Como exemplo, o codigo 3.3.4 utiliza os metodos writeOb-
ject(objeto) e readObject() de modo a enviar uma mensagem de sucesso referente a conexao
Serviços de Comunicação 28
realizada.
1 String mensagem = "Conexao realizada com sucesso!";2 saidaDeDados.writeObject( mensagem );3 saidaDeDados.flush();4 String resposta = (String) entradaDeDados.readObject();
Codigo 3.3.4: Codigo exemplo de processamento de fluxo de dados
E importante lembrar que existem varios metodos que possibilitam a leitura e escrita a
partir de Streams. No exemplo mencionado, os metodos utilizados sao de escrita e leitura
de objetos, no caso, especificamente, sao enviadas e recebidas Strings. Entretanto e possıvel
enviar e receber varios outros objetos, tipos primitivos, entre outros.
No passo 5, apos a transmissao ter sido realizada, faz-se necessario finalizar os objetos
de comunicacao, assim como a conexao do Socket. O encerramento ocorre utilizando o
metodo close() nos objetos InputStream e OutputStream e no Socket, conforme codigo
3.3.5:
1 entradaDeDados.close();2 saidaDeDados.close();3 conexao.close();
Codigo 3.3.5: Codigo de finalizacao dos fluxos de dados e Socket no Servidor
3.3.2 Implementando um cliente utilizando Sockets de fluxo
A implementacao do cliente e bastante semelhante ao servidor. Para realizar essa
implementacao se faz necessario executar quatro passos:
1. Criar um Socket.
2. Obter os fluxos de entrada e saıda do socket.
3. Realizar o processamento (comunicacao).
4. Fechar a conexao.
No passo 1, deve-se criar um Socket de modo a conectar-se ao servidor. O construtor
do Socket, conforme codigo 3.3.6, estabelece a conexao.
Serviços de Comunicação 29
1 Socket conexaoCliente = new Socket( enderecoDoServidor, porta );
Codigo 3.3.6: Codigo de criacao do Socket no Cliente
O construtor do Socket possui duas variaveis: enderecoDoServidor e porta. A requisicao
de conexao ao servidor e realizada indicando o endereco e a porta no qual a aplicacao esta
hospedada. Se a tentativa de conexao for bem sucedida, essa instrucao retorna um Socket.
Caso contrario, uma falha de excecao de entrada e saıda e invocada.
No passo 2, o cliente tambem necessita criar objetos InputStream e OutputStream e
utilizar os metodos getInputStream e getOutputStream para obter as referencias ao Input-
Stream e OutputStream do Socket. Desse modo, caso o servidor envie valores com um objeto
ObjectOutputStream, o cliente devera ler esses valores com um objeto ObjectInputStream.
O codigo 3.3.7 relata essa implementacao no cliente:
1 ObjectInputStream entrada = new ObjectInputStream( conexaoCliente.getInputStream() );2 ObjectOutputStream saida = new ObjectOutputStream( conexaoCliente.getOutputStream() );
Codigo 3.3.7: Codigo de criacao dos objetos OutputStream e InputStream no Cliente
No passo 3, ocorre a comunicacao entre o cliente e servidor. As informacoes sao enviadas
e recebidas utilizando os objetos InputStream e OutputStream. Como exemplo, o codigo
3.3.8 demonstra a informacao recebida do servidor referente a confirmacao de conexao e,
em seguida, o cliente encaminha uma outra mensagem.
1 String confirmacaoDeConexao = (String) entrada.readObject();2 String ok = "OK!";3 saida.writeObject(ok);4 saida.flush();
Codigo 3.3.8: Codigo exemplo de processamento de fluxo de dados no Cliente
No passo 4, o cliente encerra os fluxos de dados e finaliza a conexao com o servidor.
Nesse caso, o metodo close e utilizado, conforme codigo 3.3.9:
1 entrada.close();2 saida.close();3 conexaoCliente.close();
Codigo 3.3.9: Codigo exemplo de processamento de fluxo de dados no Cliente
Serviços de Comunicação 30
3.3.3 Estabelecendo uma comunicacao utilizando a arquiteturacliente-servidor
A partir da utilizacao de Sockets de fluxo, uma comunicacao entre cliente e servidor
pode ser implementada. Executando os passos para a implementacao do servidor e do
cliente, demonstrado, respectivamente, nos subtopicos 3.3.1 e 3.3.2, pode-se obter uma
conexao e realizar a troca de informacoes. No codigo 3.3.10 e demonstrado a implementacao
completa de um servidor simples que tem como objetivo receber uma conexao e enviar uma
confirmacao ao cliente caso tenha sido bem sucedida.
1 import java.io.ObjectInputStream;2 import java.io.ObjectOutputStream;3 import java.net.InetAddress;4 import java.net.ServerSocket;5 import java.net.Socket;6
7 public class Servidor {8 public static void main(String[] args) {9 try {
10 //Passo 1: Criando um objeto ServerSocket11 ServerSocket server = new ServerSocket(9876, 10);12 System.out.println("Servidor -> Esperando Conexao.");13
14 //Passo 2: Esperando uma conexao15 Socket conexao = server.accept();16
17 //Passo 3: Obtendo os fluxos de entrada e saida18 ObjectInputStream entradaDeDados = new ObjectInputStream(conexao.getInputStream());19 ObjectOutputStream saidaDeDados = new ObjectOutputStream(conexao.getOutputStream());20
21 //Passo 4: Realizando o processamento/comunicacao22 String mensagem = "Conexao realizada com sucesso!";23 saidaDeDados.writeObject( mensagem );24 saidaDeDados.flush();25 String resposta = (String) entradaDeDados.readObject();26 System.out.println("Servidor -> " + resposta);27
28 //Passo 5: Finalizando os fluxos de dados e o socket29 saidaDeDados.close();30 entradaDeDados.close();31 conexao.close();32 } catch (Exception e) {33 e.printStackTrace();34 }35 }36 }
Codigo 3.3.10: Codigo fonte referente a implementacao do servidor
No codigo 3.3.11 e demonstrado a implementacao de um cliente de modo a requerer
uma conexao com o servidor. Caso a conexao seja realizada com sucesso, o cliente recebera
uma mensagem de sucesso e, em seguida, enviara uma outra mensagem de modo a informar
ao servidor que a comunicacao esta sendo efetuada corretamente.
Serviços de Comunicação 31
1 import java.io.IOException;2 import java.io.ObjectInputStream;3 import java.io.ObjectOutputStream;4 import java.net.Socket;5
6 public class Cliente {7 public static void main(String[] args) throws ClassNotFoundException{8 try {9 //Passo 1: Criando um Socket
10 Socket conexaoCliente = new Socket("192.168.0.10", 9876);11
12 //Passo 2: Obtendo os fluxos de entrada e saida do socket.13 ObjectOutputStream saida = new ObjectOutputStream(conexaoCliente.getOutputStream());14 ObjectInputStream entrada = new ObjectInputStream(conexaoCliente.getInputStream());15
16 //Passo 3: Realizando o processamento17 String confirmacaoDeConexao = (String) entrada.readObject();18 String ok = "OK!";19 saida.writeObject(ok);20 saida.flush();21 System.out.println(confirmacaoDeConexao);22
23 //Passo 4: Fechando os fluxos de entrada, de saida e o socket24 saida.close();25 entrada.close();26 conexaoCliente.close();27 }catch (IOException e) {28 System.out.println("Erro: "+ e);29 }30 }31 }
Codigo 3.3.11: Codigo fonte referente a implementacao do cliente
Ao executar o codigo 3.3.10 - codigo referente ao servidor, observa-se, na figura 3.5, que
o mesmo esta aguardando a requisicao de uma conexao:
Figura 3.5: Servidor aguardando uma requisicao de conexao
Serviços de Comunicação 32
Ao executar o codigo 3.3.11 - codigo referente ao cliente, o servidor aceita a conexao e
envia a mensagem de confirmacao. Apos o recebimento dessa mensagem, o cliente envia
uma mensagem de modo a mostrar que o fluxo de dados ocorre normalmente. Na figura
3.6 temos a mensagem de confirmacao no cliente, assim como na figura 3.7, a mensagem
no servidor de que o fluxo ocorre normalmente.
Figura 3.6: Confirmacao de conexao do cliente com o servidor
Figura 3.7: Confirmacao de fluxo de dados no servidor
Por fim, ambos fluxos e Sockets sao finalizados, terminando assim todo esse processo.
Na figura 3.8 e representado o diagrama de sequencia referente a essa comunicacao. Em
resumo, o cliente cria um objeto Socket (new Socket()) e realiza a conexao com o servidor
(representado no diagrama pelo metodo conectar()). Por sua vez, o servidor autentica essa
Serviços de Comunicação 33
conexao e o fluxo de dados se inicia logo apos os objetos (Streams) de entrada e saıda serem
criados. Terminando a comunicacao, esses objetos sao finalizados (fecharStreams()) assim
como as respectivas conexoes fecharConexao().
Figura 3.8: Exemplo de um projeto Android
Capıtulo 4
Desenvolvimento
Este capıtulo apresenta o desenvolvimento do jogo da velha multisuario online chamado
OX Game, onde sao descritas as etapas de desenvolvimento, a abstracao da arquitetura
utilizada e a codificacao do sistema.
4.1 Etapas de Desenvolvimento
O processo de desenvolvimento de um jogo requer decisoes que devem ser avaliadas de
modo a torna-lo mais funcional e atraente. Decisoes como a metodologia de desenvolvi-
mento a ser utilizada, o tipo de arquitetura e que linguagem de programacao escolher sao
cruciais para construir um jogo de qualidade. Segundo Bates, o desenvolvimento de jogos
nao requer somente a programacao, mas diversas etapas antes e depois da codificacao. As
etapas mencionadas por Bates sao descritas a seguir[Bates2004]:
• Reuniao Criativa
Tecnica adotada de modo a obter ideias de construcao do jogo, baseada em uma
reuniao chamada de brainstorming - ”tempestade de ideias”em portugues brasileiro.
• Rascunho
Definicao das principais caracterısticas do jogo (interfaces, modo do jogo, regras,
fluxos, entre outros).
• Detalhamento
Momento de descrever as principais caracterısticas definidas na etapa Rascunho, como
quais acoes serao desempenhadas pelo jogador, o sistema de pontuacao, o estilo do
jogo, etc.
O Projeto 35
• Game Design Document
Etapa em que o jogo precisa ser descrito em um documento fısico, um roteiro que
permite guiar a construcao do jogo durante o desenvolvimento e codificacao.
• Level Design
E a etapa que mapeia todos os desafios que o jogador deve confrontar durante uma
partida do jogo.
• Producao de Arte
Construcao do efeito sonoro e efeitos visuais do jogo.
• Integracao
Etapa que realiza a integracao entre a logica do jogo com a linguagem de programacao
definida e os mecanismos adotados pela plataforma a ser utilizada.
• Versao Beta
Versao que engloba as versoes Alpha (versoes parciais que sao definidades com o
acrescimo de cada funcionalidade) e e composta por todas as funcionalidades pro-
postas.
• Teste
Etapa que realiza testes de funcionalidade a fim de detectar qualquer erro ate obter
a versao final do jogo.
4.2 O Projeto
As decisoes do projeto de desenvolvimento do jogo OX Game estao descritas a seguir:
• Android versao 2.1 ou superior: compatıvel com celulares de alta tecnologia e que
possui conectividade 2G, 3G e Wifi.
• Controles na tela (Touchscreen): uso da tela para a manipulacao do jogo e que esta
disponıvel na maioria dos celulares que possui a plataforma Android.
• Jogo da Velha Tradicional: baseado em partidas entre dois jogadores e realizadas em
um tabuleiro 3x3 (9 posicoes).
Jogo da Velha 36
4.3 Jogo da Velha
E um jogo casual e que possui regras e caracterısticas acessıveis a um publico infantil,
juvenil e adulto. Esse jogo surgiu no Egito, mas o nome foi originado na Inglaterra quando
mulheres se reuniam a tarde para conversar e bordar. As mulheres idosas, por serem
impossibilitadas de bordar devido a problema oftamologicos, jogavam esse jogo simples,
que passou a ser conhecido como o da ”velha”.
4.3.1 Regras
O jogo da velha utiliza um tabuleiro 3x3, ou seja, uma matriz composta de tres linhas e
tres colunas. As partidas acontecem entre dois jogadores que fazem suas marcas em umas
das posicoes livres do tabuleiro. Geralmente os sımbolos utilizados sao um cırculo (O) e
um xis (X), como mostrado na figura 4.1.
Figura 4.1: Tabuleiro 3x3 e sımbolos padroes utilizados no Jogo da Velha
Cada jogador realiza uma jogada enquanto existir posicoes livres no tabuleiro. As
jogadas sao alternadas ate que um jogador venca a partida ou ao completar o tabuleiro,
ocasionando um empate. Um jogador e considerado vencedor quando consegue colocar tres
marcas em sequencia, podendo ser no sentido horizontal, no sentido vertical ou diagonal,
de acordo com a figura 4.2. Dessa forma, o jogo consiste que um jogador coloque tres
marcas em um dos sentidos que decide a vitoria enquanto tenta evitar que seu oponente
faco o mesmo antes.
Arquitetura do Jogo 37
Figura 4.2: Possibilidade de Vitoria no Jogo da Velha
4.4 Arquitetura do Jogo
Ao desenvolver um jogo, e necessario analisar qual arquitetura e a mais adequada para
atender as funcionalidades requeridas. O jogo da velha ”OX Game” utiliza a arquitetura
cliente-servidor (explicado no subtopico 3.2.1) e e formado por quatro componentes prin-
cipais, mostrados na figura 4.3:
Figura 4.3: Arquitetura do Jogo OX Game
A figura mostra quatro clientes, hospedados em dispositivos moveis diferentes, e um
servidor simples, em uma maquina (computador). Os quatros componentes possuem as
seguintes funcoes:
• Interface de Usuario
A interface de usuario, denominado pela letra ”I”, e uma unidade de interface no qual
e responsavel por exibir ao jogador toda e qualquer funcionalidade do jogo, como por
exemplo o menu de opcoes e a propria funcionalidade de jogar.
Modelagem 38
• Cliente
O cliente, denominado pela letra ”C”, gerencia as comunicacoes com a interface e
com o servidor. A comunicacao usuario-interface e realizada pela navegacao de telas
do aplicativo. A comunicacao com o servidor e obtida durante um jogo no qual um
determinado jogador mantem a partida com seus adversarios, possibilitando, assim,
o fluxo das jogadas.
• Servidor
O servidor, denominado pela letra ”S”, e o responsavel por processar e gerenciar o
jogo e as partidas que estao sendo jogadas pelos usuarios. Para cada dois clientes
conectados e desafiados entre si, o servidor e responsavel por conecta-los e iniciar a
partida.
• Partida
A partida, denominado pela letra ”P”, representa um jogo entre dois jogadores. O
gerenciamento e controle de quem e o vencedor, perdedor e se houve ou nao um
empate e realizado pela partida, cabendo apenas ao servidor informar aos jogadores
o resultado.
• Mensageiro
O mensageiro, denominado pela letra ”M”, e o responsavel por realizar a comuni-
cacao entre o cliente e o servidor. Essa comunicacao e realizada utilizando sockets
(explicado no topico 3.3). Esse componente esconde a interface baixo-nıvel de socket
entre os dispositivos moveis e o computador que hospeda o servidor.
4.5 Modelagem
Segundo Booch, a modelagem de um sistema se caracteriza por ser uma parte central de
todas as atividades que levam a implantacao de um bom software. Modelos sao construıdos
para comunicar a estrutura e o comportamento desejado do sistema, para visualizar e
controlar a arquitetura escolhida, para compreender melhor o sistema que deseja elaborar
e gerenciar possıveis riscos, muitas vezes proporcionando oportunidades de simplificacao
e reaproveitamento[Booch2005]. A modelagem consiste, entao, em elaborar diagramas
Modelagem 39
que permitem alcancar quatro objetivos essenciais na compreensao do sistema que se esta
desenvolvendo:
• Visualizar o sistema como ele e ou como e desejado.
• Permitir especificar a estrutura ou o comportamento de um sistema.
• Proporcionar um guia para a construcao do sistema.
• Documentar as decisoes tomadas.
O primeiro diagrama produzido foi o de Casos de Uso, que denota o comportamento
essencial do sistema. E identificado a interacao dos atores com o sistema sem ser necessario
especificar como essa interacao e realizada. No jogo OX Game existe apenas um jogador
humano que pode estar interagindo com a inteligencia artificial ou com outro humano,
caracterizando a acao de jogar uma partida. E permitido, ainda, que esse jogador interaja
com o sistema de modo a usufruir de suas funcionalidades. O diagrama esta descrito na
figura 4.4:
Modelagem 40
Figura 4.4: Diagrama de Casos de Uso do Jogo da Velha OX Game
O diagrama de atividades do jogo da velha OX Game esta descrito na figura 4.5. Nesse
diagrama e possıvel analisar o fluxo de controle de uma atividade para outra, ou seja, o
passo a passo do programa. Esse diagrama tambem mostra a concorrencia bem como as
devidas ramificacoes de controle.
Modelagem 41
Figura 4.5: Diagrama de Atividades do Jogo da Velha OX Game
Modelagem 42
A partir do comportamento essencial do sistema, dos atores, suas atividades e do fluxo
das atividades no decorrer da execucao do jogo, os diagramas de classes estao representados
nas figuras 4.6 e 4.7. Esses diagramas mostram o conjunto de classes e seus relacionamentos
no dispositivo movel (cliente) e no servidor, respectivamente.
O Diagrama de classes referente ao cliente possui 10 classes. As classes estao descritas
a seguir:
• TelaSplash: classe responsavel pela apresentacao do jogo quanto ao seu desenvolvedor
e a razao de seu desenvolvimento.
• MenuPrincipal: apresenta o menu do jogo(praticar, novo jogo, desafiar, sair).
• Jogo: classe responsavel pelo jogo entre um oponente humano e a inteligencia artifi-
cial.
• JogoEspera: e uma especificacao da classe Jogo. O jogador humano esta aguardando
por um oponente humano.
• JogoRede: classe responsavel pelo jogo entre dois jogadores humanos.
• ConexaoMensageiro: encapsula a solicitacao do fluxo de entrada e saıda de dados.
• Mensageiro: classe responsavel pelo fluxo de entrada e saıda de dados com o servidor.
• ListaJogadores: solicita a lista de jogadores disponıveis que serao desafiados em uma
partido do jogo.
• ConstrutorLista: gera a lista de jogadores.
• ItemJogador: cria uma instancia na lista para cada jogador conectado e esperando
por um desafio.
Modelagem 43
Figura 4.6: Diagrama de Classes do Jogo da Velha OX Game referente ao Cliente
O diagrama de classes referente ao servidor possui 4 classes. As classes estao descritas
a seguir:
• ServidorExecutavel: cria uma instancia do servidor e e iniciado de modo a receber
conexoes.
• Servidor: classe responsavel por gerenciar as conexoes dos clientes.
• Jogador: e a classe responsavel por realizar o fluxo de dados e armazenar os dados
do jogador.
• Partida: e a classe responsavel por analisar as jogadas e valida-las.
Modelagem 44
Figura 4.7: Diagrama de Classes do Jogo da Velha OX Game referente ao Servidor
Codi�cando o Jogo 45
4.6 Codificando o Jogo
Com a modelagem do sistema pronto, o proximo passo para implementacao do jogo
OX Game consiste na codificacao utilizando a plataforma Android. Por se tratar de um
jogo multiusuario online, cada componente do sistema possui um ou mais processos sendo
executados. Estes processos sao trechos de codigo que sao executados paralelamente e
possuem linhas de controle distintas. Dessa forma, cada processo e responsavel por uma
atividade de modo a permanecer ativa enquanto necessaria, caso contrario, o processo e
encerrado. Um processo se comunica por meio do fluxo de entrada e saıda de dados,
utilizando sockets (abordado no topico 3.3), e e por intermedio desse fluxo que cada processo
sabe o momento exato em que deve iniciar.
4.6.1 Codificando o cliente
Qualquer aplicacao em Android que necessita realizar processos envolvendo rede, e de
extrema importancia declarar a permissao de uso no arquivo AndroidManifest.xml. Como
mencionado anteriormente no topico 3.1, este arquivo descreve os elementos da aplicacao,
as classes de cada componente a ser utilizado, qual o tipo de dado ele pode tratar, quando
pode ser ativado, ou seja, serve para definir os dados de cada elemento[Pereira2009].
Com base nesse conceito, no trecho de codigo 4.6.1 se encontra o arquivo AndroidMani-
fest.xml do jogo OX Game. Na linha 8 desse codigo, e possıvel verificar a permissao do uso
da internet pela aplicacao. De modo que um cliente possa utilizar o acesso a rede WiFi,
outra permissao precisa ser imposta, como na linha 9.
Codi�cando o Jogo 46
1 <?xml version="1.0" encoding="utf-8"?>2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"3 package="com.teste"4 android:versionCode="1"5 android:versionName="1.0" >6
7 <uses-sdk android:minSdkVersion="8" />8 <uses-permission android:name="android.permission.INTERNET"></uses-permission>9 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
10
11 <application12 android:icon="@drawable/logo"13 android:label="@string/app_name" >14 <activity15 android:screenOrientation="nosensor"16 android:label="@string/app_name"17 android:name=".TelaSplash">18 <intent-filter >19 <action android:name="android.intent.action.MAIN" />20 <category android:name="android.intent.category.LAUNCHER" />21 </intent-filter>22 </activity>23 <activity24 android:screenOrientation="nosensor"25 android:label="@string/app_name"26 android:name=".MenuPrincipal" >27 </activity>28 <activity29 android:screenOrientation="nosensor"30 android:label="@string/app_name"31 android:name=".Jogo" >32 </activity>33 <activity34 android:screenOrientation="nosensor"35 android:label="@string/app_name"36 android:name=".JogoEspera" >37 </activity>38 <activity39 android:screenOrientation="nosensor"40 android:label="@string/app_name"41 android:name=".JogoEmRede" >42 </activity>43 <activity44 android:screenOrientation="nosensor"45 android:label="@string/app_name"46 android:name=".ListaJogadores" >47 </activity>48 </application>49
50 </manifest>
Codigo 4.6.1: Codigo fonte referente a implementacao do cliente
Nas linhas 11-48 do trecho de codigo 4.6.1, entre as tags <application> e </applica-
tion>e declarado cada componente Activity que existe no jogo. Dessa forma, e possıvel
notar que existe seis telas em toda a aplicacao. O nome de cada tela se refere a classe em
que a instancia, como por exemplo, na linha 7, a tela e denominada TelaSplash, dado por
android:name=”.TelaSplash”.
Por existir mais de um componente Activity, ao iniciar uma aplicacao um desses com-
Codi�cando o Jogo 47
ponentes precisa ser declarado como o componente principal. De modo a definir qual com-
ponente deve iniciar uma aplicacao, faz-se necessario a utilizacao das tags <intent-filter >
e </intent-filter> e a declaracao desse componente como a activity principal (linha 19), e
executavel (linha 20).
Interface do Jogo da Velha
A interface do aplicativo e baseado em XML. Toda a codificacao da interface e realizada
separadamente da codificacao logica do jogo. Os arquivos XML estao localizados na pasta
res/layout-port, conforme figura 4.8.
Figura 4.8: Localizacao dos arquivos XML no projeto OX Game
Cada arquivo XML e responsavel pela construcao da interface de uma determinada
Codi�cando o Jogo 48
Activity. No trecho de codigo 4.6.2, as caracterısticas como o identificador da tela, a
utilizacao do espaco da tela, a orientacao, o plano de fundo e o efeito do som sao declara-
dos. E importante ressaltar que os termos android : layoutwidth = ”matchparent” e
android : layoutheight = ”matchparent” definem a largura e a altura do layout na dimen-
sao disponıvel da tela.
1 <?xml version="1.0" encoding="utf-8"?>2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"3 android:id="@+id/layout_id"4 android:layout_width="match_parent"5 android:layout_height="match_parent"6 android:background="@drawable/fundo"7 android:orientation="vertical"8 android:soundEffectsEnabled="true" >9
10 </LinearLayout>
Codigo 4.6.2: Declaracao das caracterısticas do arquivo telaJogo.xml
Tendo em vista que codificar e gerenciar parte da tela permite controlar os eventos com
facilidade, no trecho de codigo 4.6.3 e definido a primeira parte da tela. Nesse trecho de
codigo e declarado uma imagem utilizando a tag <ImageView>. Nessa tag e informado
o identificador (android:id=”@+id/titulo2”) dessa imagem, para que possa ser chamado
durante a codificacao logica do jogo, as dimensoes e a orientacao.
1 <?xml version="1.0" encoding="utf-8"?>2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"3 android:id="@+id/layout_id"4 android:layout_width="match_parent"5 android:layout_height="match_parent"6 android:background="@drawable/fundo"7 android:orientation="vertical"8 android:soundEffectsEnabled="true" >9
10 <LinearLayout11 android:layout_width="match_parent"12 android:layout_height="78dp"13 android:orientation="vertical" >14
15 <ImageView16 android:id="@+id/titulo2"17 android:layout_width="wrap_content"18 android:layout_height="wrap_content"19 android:layout_marginRight="5dip"20 android:layout_marginTop="15dip"21 android:background="@drawable/titulo2" />22 </LinearLayout>23
24 </LinearLayout>
Codigo 4.6.3: Codificacao da primeira parte da tela do Jogo OX Game
Codi�cando o Jogo 49
Na figura 4.9, a visualizacao da parte codificada e apresentada:
Figura 4.9: Primeira parte da tela do Jogo OX Game
A segunda parte da tela e referente ao tabuleiro de 9 posicoes. Cada posicao e um botao
e utiliza a tag <ImageButton> para instancia-lo. Para cada botao existe um identificador
(android:id=”@+id/b3”)e as caracterısticas de orientacao. No trecho de codigo 4.6.4 e
apresentado a criacao de uma instancia desse botao:
1 <ImageButton2 android:id="@+id/b3"3 android:layout_width="60dp"4 android:layout_height="67dp"5 android:layout_gravity="center"6 android:layout_marginLeft="40dip"7 android:layout_weight="0.07"8 android:tag="3" />
Codigo 4.6.4: Codificacao de um botao do tabuleiro 3x3 do Jogo OX Game
De modo a organizar as noves posicoes do tabuleiro, essa segunda parte da tela e
dividida em tres subpartes de modo a ficarem igualmente distribuıdos. Cada subparte
engloba tres botoes. Sendo assim, cada subparte possui a implementacao apresentado no
trecho de codigo 4.6.5:
Codi�cando o Jogo 50
1 <LinearLayout2 android:layout_width="match_parent"3 android:layout_height="match_parent"4 android:layout_weight="1"5 android:orientation="horizontal" >6
7 <ImageButton8 android:id="@+id/b3"9 android:layout_width="60dp"
10 android:layout_height="67dp"11 android:layout_gravity="center"12 android:layout_marginLeft="40dip"13 android:layout_weight="0.07"14 android:tag="3" />15
16 <ImageButton17 android:id="@+id/b2"18 android:layout_width="60dp"19 android:layout_height="67dp"20 android:layout_gravity="center"21 android:layout_toLeftOf="@id/b3"22 android:layout_weight="0.07"23 android:tag="2" />24
25 <ImageButton26 android:id="@+id/b1"27 android:layout_width="60dp"28 android:layout_height="67dp"29 android:layout_gravity="center"30 android:layout_marginRight="40dip"31 android:layout_toLeftOf="@id/b2"32 android:layout_weight="0.07"33 android:tag="1" />34 </LinearLayout>
Codigo 4.6.5: Codificacao do tabuleiro 3x3 do Jogo OX Game
Na figura 4.10, a visualizacao da parte codificada e apresentada:
Codi�cando o Jogo 51
Figura 4.10: Primeira e segunda parte da tela do Jogo OX Game
A terceira parte da tela do jogo e destinado para a visualizacao do placar. O tre-
cho de codigo 4.6.6 define um texto na tela utilizando a tag <TextView>. A utilizacao
dessa tag permite que seja alterado constatemente por meio do identificador declarado (
android:id=”@+id/scoreboard”).
1 <LinearLayout2 android:layout_width="match_parent"3 android:layout_height="match_parent"4 android:layout_weight="3.5"5 android:orientation="vertical" >6
7 <TextView8 android:id="@+id/scoreboard"9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"11 android:layout_gravity="center_horizontal|center_vertical"12 android:textColor="#000000"13 android:textStyle="bold" />14 </LinearLayout>
Codigo 4.6.6: Codificacao do placar do Jogo OX Game
Como existe apenas a codificacao grafica na interface e o texto depende da informacao
vinda da logica do jogo, nenhuma valor e visualizado, mas o seu espaco na tela e reservado,
conforme figura 4.11:
Codi�cando o Jogo 52
Figura 4.11: Primeira, segunda e terceira parte da tela do Jogo OX Game
A ultima parte da tela e codificada de modo a incluir alguns detalhes de design. O
trecho de codigo 4.6.7 apresenta a inclusao de duas figuras. Ambas figuras possuem seus
identificadores assim como as configuracoes de orientacao e tamanho.
1 <LinearLayout2 android:layout_width="match_parent"3 android:layout_height="wrap_content"4 android:orientation="horizontal" >5
6
7 <ImageView8 android:id="@+id/detalhes"9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"11 android:layout_weight="0.51"12 android:background="@drawable/detalhes" />13
14
15 <ImageView16 android:id="@+id/android1"17 android:layout_width="wrap_content"18 android:layout_height="wrap_content"19 android:background="@drawable/androidgrande" />20
21 </LinearLayout>
Codigo 4.6.7: Codificacao dos detalhes de design do Jogo OX Game
Na figura 4.12, a visualizacao da parte codificada e apresentada:
Codi�cando o Jogo 53
Figura 4.12: Tela do Jogo OX Game
Dessa forma, a interface do jogo OX Game esta construıda. E importante ressaltar que
as tags <LinearLayout> e </LinearLayout> dividem a tela em tamanhos proporcionais
desejados. Como se pode observar, existem as tags LinearLayout principais e mais outras
tags de mesmo nome dividindo a tela em partes menores. No total existe um tela que esta
dividida em quatro partes, e por sua vez, a segunda parte e dividida em mais tres.
Criando uma conexao com o Servidor
O usuario do jogo OX Game solicita uma conexao com o servidor em duas circunstan-
cias: ao criar um novo jogo, aguardando por um oponente de modo a iniciar o jogo online,
ou ao solicitar a lista de jogadores disponıveis para desafiar e iniciar uma partida. Ambas
situacoes acontecem a partir do menu principal do jogo, conforme apresentado na figura
4.13:
Codi�cando o Jogo 54
Figura 4.13: Menu principal do jogo OX Game
A requisicao de uma conexao com o servidor e realizada por meio de sockets, con-
forme visto no topico 3.2.1. Essa conexao e criada utilizando as classes MenuPrincipal e
ConexaoMensageiro. No trecho de codigo 4.6.8 - Classe MenuPrincipal, e possıvel obser-
var que a requisicao dessa conexao e realizada pelos metodos criarConexao(ip, porta) e
conectar().
1 try {2 // Inicia uma conexao com o Servidor de Socket3 ConexaoMensageiro conexao = ConexaoMensageiro.criarConexao(ip, porta);4 conexao.conectar();5 } catch (Exception e) {6 // Mostra erro na tela7 Toast.makeText(MenuPrincipal.this, "Nao foi possivel conectar",8 Toast.LENGTH_LONG).show();9 }
Codigo 4.6.8: Requisicao de conexao ao Servidor
Ao criar um objeto ConexaoMensageiro, um objeto de mesma classe e atribuıdo. Esse
objeto e instanciado utilizando os parametros host e porta que foram informados no metodo
Codi�cando o Jogo 55
criarConexao(ip, porta). A partir desse objeto, uma requisicao de conexao e solicitada. O
metodo conectar(), por sua vez, e responsavel por realizar a conexao com o servidor e
preparar o fluxo de entrada e de saıda de dados. No trecho de codigo 4.6.9 e apresentado
essas funcionalidades:
1 private ConexaoMensageiro(String host, String porta) {2 this.host = host;3 this.porta = Integer.parseInt(porta);4 }5
6 public static ConexaoMensageiro criarConexao(String host, String porta) {7 connection = new ConexaoMensageiro(host, porta);8 return connection;9 }
10
11 public void conectar() throws Exception {12 this.socket = new Socket(host, porta);13 dataOut = new DataOutputStream(socket.getOutputStream());14 dataIn = new DataInputStream(socket.getInputStream());15 }
Codigo 4.6.9: Descricao dos metodos criarConexao(ip, porta) e conectar()
Aguardando um Oponente
Dentre as funcionalidades do aplicativo OX Game, o jogador pode optar por inicializar
um novo jogo e aguardar um oponente. Quando essa opcao e escolhida, a conexao com
o servidor, se realizada, permite ao usuario jogar contra a inteligencia artificial enquanto
um oponente nao o desafia. Durante essa partida, que pode ocorrer sucessivamente, um
processo concorrente e iniciado e fica aguardando esse jogador oponente.
O processo concorrente e executado em uma classe interna chamada MyThread. Essa
classe e criada dentro da classe JogoEspera de modo a facilitar o trabalho dessa classe sem
expor a complexidade existente. A classe MyThread e apresentada no trecho de codigo
4.6.10:
Codi�cando o Jogo 56
1 private class MyThread extends Thread {2 private boolean esperando;3
4 public MyThread() {5 esperando = true;6 }7
8 public void run() {9 aguardarOponente();
10 mHandler.post(new Runnable() {11 @Override12 public void run() {13 avisarDesafio();14 }15 });16 }17
18 private void aguardarOponente() {19 do {20 try {21 esperando = ConexaoMensageiro.retornarConexao().aguardarOponente();22 } catch (Exception e) {23 e.printStackTrace();24 }25 } while (esperando);26 }27 }
Codigo 4.6.10: Classe responsavel por aguardar o desafio de um oponente
Por se tratar de uma classe concorrente, o metodo obrigatorio run() realiza toda a
atividade necessaria. A chamada do metodo interno aguardarOponente() faz com que todo
o restante da atividade concorrente so se realize quando houver uma resposta do servidor.
Nessa caso, o servidor e responsavel por enviar a esse metodo uma mensagem de que
existe um oponente desafiando o jogador. O metodo aguardarOponente(), por sua vez,
esta relacionado com o socket do jogador e sendo trabalho na classe Mensageiro, classe
designada a se comunicar com o servidor.
Na classe Mensageiro, um loop e executado de modo a averiguar as mensagens enviadas
pelo servidor. No trecho de codigo 4.6.11, e possıvel verificar que toda vez que ocorre um
envio de mensagem, essa mensagem e analisada. Caso exista uma solicitacao de desafio, o
loop e encerrado e assim a atividade concorrente executa o metodo avisarDesafio().
Codi�cando o Jogo 57
1 try {2 while (esperar) {3 aguardarOponente = dataIn.readBoolean();4 if (aguardarOponente == false) {5 esperar = false;6 }7 }8 } catch (IOException e) {9 e.printStackTrace();
10 stop();11 }
Codigo 4.6.11: Loop responsavel pela analise das mensagens enviadas pelo servidor
O metodo avisarDesafio() inicia uma nova partida e conecta os dois jogadores. Esse
metodo esta descrito no trecho de codigo a seguir:
1 public void avisarDesafio() {2 AlertDialog.Builder builder = new AlertDialog.Builder(this);3 builder.setMessage("Um oponente esta lhe desafiando... Hora de jogar!!");4 builder.setCancelable(true);5 builder.setPositiveButton("OK",6 new DialogInterface.OnClickListener() {7 public void onClick(DialogInterface dialog1, int which) {8 Intent intent = new Intent(JogoEspera.this, JogoEmRede.class);9
10 Bundle parametros = new Bundle();11 parametros.putString("jogador2", jogador2);12 parametros.putString("statusSom", statusSom);13 parametros.putBoolean("conectado", true);14
15 intent.putExtras(parametros);16
17 startActivity(intent);18 finish();19 }20 });21 builder.show();22 }
Codigo 4.6.12: Metodo responsavel por avisar o jogador de um desafio e iniciar uma novapartida
Enviando e recebendo as jogadas
Apos o aviso de desafio de um oponente, os dois jogadores sao sincronizados de modo a
compartilharem a mesma tela de jogo, alternando entre si as jogadas. A partida e executada
utilizando as classes JogoEmRede e Mensageiro. A classe Mensageiro recebe do servidor
uma mensagem informando qual jogador inicializa a partida. Essa mensagem e enviada
atraves do construtor da classe Partida no qual o servidor monitora, conforme trecho de
codigo 4.6.13.
Codi�cando o Jogo 58
1 public Partida(Jogador jogadorX, Jogador jogadorO) throws IOException{2 this.PLAYER_X = jogadorX;3 this.PLAYER_0 = jogadorO;4 this.jogadorDaVez = PLAYER_X;5 jogadorDaVez.dataOut.writeBoolean(false);6 }
Codigo 4.6.13: Construtor da classe Partida localizada no servidor
Por sua vez, quando a classe Mensageiro recebe a mensagem de permissao de jogada,
e informa a classe JogoEmRede, a variavel isMinhaVez permite que os botoes bloqueados
sejam liberados e prontos para receber uma posicao do jogador. Ao ser escolhida a posicao
de jogada, o metodo enviarJogada() e executado. Caso essa jogada seja decisiva para o
fim do jogo, uma analise e realizada. Caso contrario, o socket realiza o envio da posicao ao
servidor, de modo que possa ser distribuıdo ao cliente oponente. O metodo enviar jogada
e apresentado no trecho de codigo 4.6.14:
1 OnClickListener button_listener = new View.OnClickListener() {2 public void onClick(View v) {3 controleSomAndroid = (AudioManager) getSystemService(Context.AUDIO_SERVICE);4 if (SOM_LIGADO5 && (controleSomAndroid.getRingerMode() == AudioManager.RINGER_MODE_NORMAL)) {6 media.start();7 }8
9 ImageButton ibutton = (ImageButton) v;10 String posicao = "";11 int pos = 0;12
13 if (isMinhaVez) {14 posicao = (String) ibutton.getTag(); // pega a posicao conforme a tag do button15 pos = (int) posicao.charAt(0) - 48;16
17 try {18 ConexaoMensageiro.retornarConexao().enviarJogada(pos);19 } catch (IOException e) {20 e.printStackTrace();21 }22 atualizarTabuleiro(pos);23 atualizaJogadas(pos);24 resultado = verificaResultado();25 if((resultado == true) || ((resultado == false) && isCompleto())){26 ConexaoMensageiro.retornarConexao().avisarTerminou(true);27 avisarResultado(resultado);28 }else{29 ativaThread();30 }31 }32 }33 };
Codigo 4.6.14: Metodo responsavel pelo clique de uma jogada no tabuleiro
Em paralelo, a classe JogoEmRede possui uma classe interna chamada Analisador que
Codi�cando o Jogo 59
tem como objetivo verificar quando e a vez de receber a jogada do oponente. Essa classe
concorrente executa o metodo existente run() que, em seguida, executa um metodo interno
chamado receberJogadaOponente(). No trecho de codigo a seguir e possıvel analisar a classe
Analisador :
1 private class Analisador extends Thread {2 int pos;3
4 public Analisador() {5 isMinhaVez = false;6 }7
8 public void run() {9 receberJogadaOponente();
10 mHandler.post(new Runnable() {11 @Override12 public void run() {13 if(pos != 0){14 atualizarTabuleiro(pos);15 atualizaJogadas(pos);16 resultado = verificaResultado();17 if((resultado == true) || ((resultado == false) && isCompleto())){18 ConexaoMensageiro.retornarConexao().avisarTerminou(true);19 avisarResultado(resultado);20 }else{21 isMinhaVez = true;22 }23 }24 }25 });26 }27
28 private void receberJogadaOponente() {29 pos = 0;30 do {31 try {32 pos = ConexaoMensageiro.retornarConexao().recebeJogadaOponente();33 } catch (Exception e) {34 }35 } while (pos == 0);36 }37
38 }
Codigo 4.6.15: Classe concorrente Analisador
O metodo receberJogadaOponente() verifica quando ha uma jogada do oponente a re-
ceber e, quando existente, efetua o recebimento e verifica se ganhou a partida ou se houve
um empate.
Verificando o vencedor
Quandos os jogadores efetuam suas jogadas, analises sao realizadas de modo a informar
ao servidor se houve ou nao a finalizacao do jogo. Ao verificar que o jogo obteve um fim,
Codi�cando o Jogo 60
uma mensagem e informada ao servidor de modo que possa distribuir a informacao ao
oponente. O metodo responsavel por esse processo e chamado de avisarTerminou(boolean
terminou) e e descrito como:
1 public void avisarTerminou(boolean terminou){2 mensageiro.setTerminou(terminou);3 }
Codigo 4.6.16: Metodo avisarTerminou(boolean terminou)
Esse metodo, por sua vez, finaliza o loop de recebimento de jogadas na classe Men-
sageiro. Esse loop esta apresentado a seguir:
1 public void run() {2 while (running) {// Enquanto estiver executando3 if (vezDeJogar) {4 try {5 while (esperar) {6 aguardarOponente = dataIn.readBoolean();7 if (aguardarOponente == false) {8 esperar = false;9 }
10 }11 } catch (IOException e) {12 e.printStackTrace();13 stop();14 }15 }else{16 try {17 if(terminou == false){18 jogadaOponente = dataIn.readInt();19 }20 } catch (IOException e) {21 e.printStackTrace();22 stop();23 }24 }25 }26 }27
28 public void setTerminou(boolean terminou) {29 this.terminou = terminou;30 }31
Codigo 4.6.17: Loop de recebimento de jogadas na classe Mensageiro
Por fim, uma mensagem e informada aos jogadores e, entao, todo o fluxo de entrada e
saıda de dados e encerrado. No trecho de codigo 4.6.18 e detalhado o metodo avisarReul-
tado(String resultado) e no trecho de codigo 4.6.19, o metodo desconectar():
Codi�cando o Jogo 61
1 public void avisarResultado(boolean resultado) {2 String textoResultado = "";3 if (resultado == true) {4 if (isMinhaVez) {5 // alterePlacar(1);6 textoResultado = "Voce ganhou!!";7 } else {8 // alterePlacar(2);9 textoResultado = "Seu Oponente ganhou!!";
10 }11 } else if ((resultado == false) && isCompleto()) {12 textoResultado = "Velhou!!";13 }14 mostraResultado(textoResultado);15 }16
17 public boolean mostraResultado(String mensagem) {18 AlertDialog.Builder builder = new AlertDialog.Builder(this);19 builder.setMessage(mensagem).setPositiveButton("Continuar",20 new DialogInterface.OnClickListener() {21 public void onClick(DialogInterface dialog, int id) {22 try {23 ConexaoMensageiro.retornarConexao().desconectar();24 } catch (Exception e) {25 Toast.makeText(JogoEmRede.this, "Nao fechou!!!",26 Toast.LENGTH_SHORT).show();27 }28 finish();29 }30 });31 AlertDialog alert = builder.create();32 alert.show();33 return true;34 }
Codigo 4.6.18: Metodo avisarReultado(String resultado)
1 public void desconectar() throws Exception {2 dataIn.close();3 dataOut.close();4 mensageiro.desconectar();5 socket.close();6 }
Codigo 4.6.19: Metodo desconectar()
4.6.2 Codificando o Servidor
O servidor tem como objetivo gerenciar todas as conexoes que sao solicitadas pelos
jogadores. O fluxo de entrada e saıda de dados do servidor tambem e baseada em sockets.
A codificacao do servidor e bastante semelhante ao que foi implementado no subtopico
3.3.1. No trecho de codigo a seguir, os objetos de fluxo de dados assim como outras
variaveis que sao utilizadas pelo servidor sao instanciados.
Codi�cando o Jogo 62
1 public class Servidor {2 private final int numeroConexoes = 14;3 private boolean executando = true;4 private Jogador[] jogadores = new Jogador[numeroConexoes];5 private final int PORTA = 7771;6 private ArrayList<Jogador> jogadoresEsperando = new ArrayList<Jogador>();7 private boolean aguardandoOponente = false;8 private DataInputStream in;9 private DataOutputStream out;
10 private String oponenteEscolhido;11 }
Codigo 4.6.20: Metodo desconectar()
A variavel PORTA especifica em qual porta o servidor esta hospedado e a variavel
numConexoes define qual o numero maximo de conexoes que o servidor ira gerenciar. Para
cada conexao realizada, o servidor deve registrar quem sao os jogadores conectados assim
como distinguir quais jogadores criaram um novo jogo. De modo a solucionar essas especifi-
cacoes, um vetor chamado jogadores e uma lista de jogadores chamada jogadoresEsperando,
resolvem esses requisitos, respectivamente. Os objetos responsaveis pela comunicacao de
dados tambem sao designados: in referente a entrada de dados e out referente a saıda de
dados. Por fim, as demais variaveis servem de controle durante o processo de execucao do
servidor.
Inicializando o Servidor e Estabelecendo Jogos entre 2 jogadores
O servidor possui apenas um unico metodo chamado inicializar(). Esse metodo e
responsavel por iniciar o servidor, permitir que haja conexoes com os clientes, distinguir
os tipos de jogadores assim como permitir que dois jogadores joguem entre si.
De modo a permitir que jogadores se conectem, uma instancia da classe nativa Server-
Socket e criada, utilizando a porta informada. O trecho de codigo 4.6.21 mostra a
declaracao e inicializacao desse servidor:
1 ServerSocket server = new ServerSocket(PORTA, numeroConexoes);
Codigo 4.6.21: Inicializacao do servidor em uma porta especificada
Cada conexao existente no servidor se refere a um jogador. Dessa forma, para cada
conexao deve ser criado um objeto do tipo Jogador de modo a ter controle sobre o fluxo de
dados que ele realiza. A partir disso, essa conexao informa que tipo de jogador sera. Todo
Codi�cando o Jogo 63
esse processo e repetido ate alcancar o numero maximo de conexoes. O codigo a seguir
demonstra como implementar esse processo:
1 for (int i = 0; i < numeroConexoes; i++) {2 //Recebendo conexao de um novo jogador3 jogadores[i] = new Jogador(server.accept());4
5 //criando os fluxos de entrada e saida do jogador6 in = new DataInputStream(jogadores[i].getSocket().getInputStream());7 out = new DataOutputStream(jogadores[i].getSocket().getOutputStream());8
9 //detectando se o jogador cria um novo jogo ou desafia um jogador10 aguardandoOponente = in.readBoolean();11 }
Codigo 4.6.22: Metodo desconectar()
A variavel aguardandoOponente e responsavel por distinguir qual o tipo de jogador.
Caso o jogador inicie uma nova partida, esse jogador e adicionado na lista jogadore-
sEsperando. Caso o jogador seja um oponente, o servidor envia uma lista de jogadores
disponıveis e, assim, escolhe qual o jogador quer desafiar. Nesse caso, uma busca e real-
izada na lista jogadoresEsperando e, entao, ambos jogadores sao sincronizados, iniciando
uma partida. E importante ressaltar que por meio das instrucoes realizadas nas linhas 17,
18 e 19 do trecho de codigo 4.6.23, varios jogos podem ser iniciados, respeitando o limite
de conexoes (jogadores) que o servidor suporta. Essa funcionalidade se encontra disponıvel
em virtude dessas instrucoes serem executadas toda vez que ha uma nova conexao do tipo
jogador desafiante (representado pelo loop demonstrado no codigo 4.6.22). O codigo 4.6.23,
localizado no loop for definido no codigo 2.6.22, representa essa implementacao:
Codi�cando o Jogo 64
1 if(aguardandoOponente){2 //jogador iniciou um novo jogo e aguarda por um oponente3 jogadoresEsperando.add(jogadores[i]);4 System.out.println("Jogador Esperando!!");5 }else{6 //Servidor envia a lista de jogadores disponiveis7 out.writeInt(jogadoresEsperando.size());8 for (int j = 0; j < jogadoresEsperando.size(); j++) {9 out.writeUTF(jogadoresEsperando.get(j).getNome());
10 System.out.println(jogadoresEsperando.get(j).getNome());11 }12 //Jogador escolhe seu oponente13 oponenteEscolhido = in.readUTF();14 for (int j = 0; j < jogadoresEsperando.size(); j++) {15 if(oponenteEscolhido.equals(jogadoresEsperando.get(j).getNome())){16 //Uma partida eh iniciada com os dois jogadores17 Partida jogo = new Partida(jogadoresEsperando.get(j), jogadores[i]);18 jogadoresEsperando.remove(j);19 jogo.start();20 System.out.println("Jogo Comecou!!");21 }22
23 }24 }
Codigo 4.6.23: Codigo que distingue qual o tipo de jogador
Envio e recebimento das jogadas
Ao iniciar um novo jogo, o construtor da classe Partida e executado. Com isso, o
jogador que criou esse jogo e o oponente sao declarados, respectivamente, o jogador X e
o jogador O. Apos essa declaracao, o jogador X e designado como o jogador que inicia a
partida, recebendo uma mensagem do servidor sinalizando essa atividade. Esse processo e
implementado conforme o codigo 4.6.24.
1 public Partida(Jogador jogadorX, Jogador jogadorO) throws IOException{2 this.PLAYER_X = jogadorX;3 this.PLAYER_0 = jogadorO;4 this.jogadorDaVez = PLAYER_X;5 jogadorDaVez.dataOut.writeBoolean(false);6 }
Codigo 4.6.24: Construtor da classe Partida
Devido o envio da mensagem de permissao de jogada, um metodo e codificado de modo
a cumprir a rotina do jogo. Esse metodo e chamado run() e esta descrito no codigo 4.6.25.
Codi�cando o Jogo 65
1 public void run() {2 try {3 while (executando) {4 //recebe a jogada5 posicao = jogadorDaVez.lerJogada();6 //atualiza a posicao7 atualizaJogadas(posicao);8 //imprime o estado do tabuleiro9 imprimir();
10 //envia ao oponente uma mensagem de modo a desativar o botao referente a jogada11 desativarJogadaOponente(posicao);12 //alterna entre os jogadores13 trocarJogador(jogadorDaVez);14 }15 } catch (IOException e) {16 e.printStackTrace();17 }18 }
Codigo 4.6.25: Metodo run() responsavel pela rotina do jogo
A jogada e recebida pela leitura do fluxo de dados, via socket, de cada jogador. Essa
leitura e implementada pelo metodo jogadorDaVez.lerJogada() que se encontra na classe
Jogador, conforme codigo 4.6.26.
1 public int lerJogada() throws IOException {2 int posicao = dataIn.readInt();3 return posicao;4 }
Codigo 4.6.26: Metodo lerJogada()
Apos essa verificacao, o metodo interno desativarJogadaOponente(posicao) e respon-
savel por enviar a jogada ao oponente evitando assim que se repita uma jogada ja realizada.
Caso o jogador que realize a jogada seja o jogador X, essa jogada e enviada ao jogador O,
e vice-versa. Esse metodo e apresentado no trecho de codigo 4.6.27.
1 public void desativarJogadaOponente(int pos) {2 try{3 if (jogadorDaVez.equals(PLAYER_X)) {4 PLAYER_0.dataOut.writeInt(pos);5 PLAYER_0.dataOut.flush();6 } else if (jogadorDaVez.equals(PLAYER_0)) {7 PLAYER_X.dataOut.writeInt(pos);8 PLAYER_X.dataOut.flush();9 }
10 }catch (IOException e) {11 e.printStackTrace();12 }13 }
Codigo 4.6.27: Metodo desativarJogadaOponente(int pos)
Codi�cando o Jogo 66
Por fim, os jogadores sao alternados utilizando o metodo interno trocarJo-
gador(jogadorDaVez) e essa rotina de jogo ocorre ate que haja um vencedor ou ocorra
um empate. Um ponto relevante e que antes de efetuar a troca dos jogadores, uma
analise e feita para que o servidor detecte o final da partida e encerre. O metodo tro-
carJogador(jogadorDaVez) esta codificado a seguir:
1 private void trocarJogador(Jogador jogador) throws IOException {2 acabouJogo();3 if(jogador.equals(PLAYER_X)){4 jogadorDaVez = PLAYER_0;5 }else if (jogador.equals(PLAYER_0)){6 jogadorDaVez = PLAYER_X;7 }8 }
Codigo 4.6.28: Metodo trocarJogador(Jogador jogador)
Finalizando a Partida
Quando um vencedor e definido ou a partida e finalizada por empate, o metodo acabou-
Jogo() alem de realizar essa verificacao, encerra essa partida e fecha os fluxos de dados
existentes. O codigo 4.6.29 representa essa verificacao:
1 private void acabouJogo() throws IOException{2 if((resultado == true) || ((resultado == false) && isCompleto())){3 System.out.println("Jogo Acabou!\n");4 executando = false;5 PLAYER_0.desconectar();6 PLAYER_X.desconectar();7 }8 }
Codigo 4.6.29: Metodo desconectar()
Como cada jogador e uma conexao, e cada conexao possui um fluxo de dados, o metodo
desconectar(), presente no metodo acabouJogo() e instanciado na classe Jogador, realiza o
fechamento do fluxo de entrada e saida de dados alem de encerrar o socket do jogador. O
codigo 4.6.30 apresenta o metodo desconectar().
Codi�cando o Jogo 67
1 public void desconectar() throws IOException {2 dataIn.close();3 dataOut.close();4 this.socket.close();5
6 }
Codigo 4.6.30: Metodo desconectar()
De modo a visualizar os sistema de fluxo de dados entre os jogadores e o servidor, o
diagrama de sequencia a seguir representa esse relacionamento:
Figura 4.14: Diagrama de sequencia do fluxo de dados do jogo OX Game
Imagens do Jogo 68
4.7 Imagens do Jogo
O jogo OX Game possui 9 telas principais:
• Tela 01: apresenta as credenciais do jogo OX Game
• Tela 02: apresenta o menu do jogo OX Game
• Tela 03: solicita o nıvel do jogo
• Tela 04: solicita o nome do jogador
• Tela 05: apresenta a lista de jogadores esperando por um desafio
• Tela 06: informa um desafio a um jogador
• Tela 07: tela do jogo da velha
• Tela 08: informa o resultado do jogo
• Tela 09: informa as opcoes disponıveis durante um jogo
O fluxo dessas telas se encontra representado a seguir:
Imagens do Jogo 69
Figura 4.15: Fluxo de telas do jogo OX Game
A partir do menu de aplicacoes de um celular Android, e possıvel iniciar o Jogo OX
Game, conforme figura a seguir:
Imagens do Jogo 70
Figura 4.16: Tela de Aplicativos do Android
Ao iniciar o jogo, a tela 01 do fluxo de dados e apresentada:
Figura 4.17: Tela de Apresentacao do Jogo
Imagens do Jogo 71
Logo em seguida, o menu do jogo (tela 02) e visualizado e permanece disponıvel para a
decisao do usuario:
Figura 4.18: Menu principal do jogo
Caso o usuario selecione o menu Praticar, o aplicativo solicitara o nıvel do jogo e,
posteriormente, o nome do usuario. Essas duas solicitacoes ocorrem por meio das telas 03
e 04:
Imagens do Jogo 72
Figura 4.19: Tela de selecao de nıvel e Tela de insercao do nome do jogador
Dada as informacoes solicitadas, uma partida e iniciada contra a inteligencia artificial
(tela 07). Durante a partida, opcoes se encontram disponıveis caso o usuario deseje realiza-
las(tela 09).
Figura 4.20: Tela do jogo da velha e Tela de opcoes durante uma partida
Imagens do Jogo 73
No entanto, duas outras opcoes de jogo ainda podem ser selecionadas. No caso do
menu Novo Jogo, o aplicativo solicitara o nome do jogador, utilizando a tela 03, e iniciara
um jogo contra a inteligencia artificial (tela 07) enquanto aguarda um oponente humano.
No caso do menu Desafiar, o jogador devera informar o nome e, em seguida, o jogador
oponente que desafiara. A solicitacao do nome tambem e realizada por meio da tela 03 e,
a lista de jogadores, pela tela 05:
Figura 4.21: Tela com a lista de jogadores online
Apos de um desafio realizado, o jogador que se encontra jogando contra a inteligencia
aritificial, recebe uma notificacao (tela 06) e, entao, ambos os jogadores estarao iniciando
uma partida um contra o outro (tela 07).
Imagens do Jogo 74
Figura 4.22: Aviso de desafio a um jogador
Ao finalizar uma partida, uma notificacao e informada por meio da tela 08, retornando
ao menu principal posteriormente.
Figura 4.23: Tela referente ao resultado do jogo
Capıtulo 5
Conclusao
Neste trabalho foi desenvolvido um jogo multiusuario utilizando a plataforma Android.
Dessa forma, foi possıvel concluir que essa plataforma por ser open source e ser uma das
plataformas mais atuais, tem bastante potencial de evoluir ainda mais. Caracterısticas
como ambiente multiplataforma, codificacao nativa disponıvel, utilizacao da linguagem de
programacao Java e um ambiente de desenvolvimento integrado (Eclipse), contribuem para
um bom desenvolvimento de um jogo, visto que desenvolver um jogo e desafiador e bastante
interessante para o publico de dispositivos moveis.
Em paralelo, foi possıvel observar que um jogo multiusuario envolve estudos e recursos
ligados com percepcao, hardware, software, interface do usuario, fatores humanos e suas
possıveis aplicacoes. Para a elaboracao de um jogo desse tipo, entao, e necessario realizar
estudos sobre a plataforma requerida, interacao, projeto de interfaces e sistemas simples e
distribuıdos.
Para o desenvolvimento do Jogo OX Game, apresentado nesse trabalho, foi essencial
a analise dos requisitos do jogo e a modelagem desses requisitos, permitindo, assim, a
codificacao de uma maneira simples das regras do jogo da velha. Enquanto isso, permitiu
um entendimento mais preciso de como o fluxo de dados funciona. E importante, ainda,
mencionar que independente de como o jogo e desenvolvido, problemas de comunicacao
podem ocorrer por diversos fatores,como por exemplo a perda de dados na rede durante a
comunicacao.
5.1 Trabalhos Futuros
Com base no jogo desenvolvido, e possıvel realizar trabalhos futuros, como por exemplo:
Trabalhos Futuros 76
• Implementar esse mesmo jogo utilizando a arquitetura ponto a ponto (mencionada
no topico 3.2.2).
• Aplicar o conceito de sockets apresentado no topico 3.3 e durante o desenvolvimento
do jogo (capıtulo 4) no desenvolvimento de outros jogos multiusuarios.
• Realizar a comunicacao do cliente a um servidor Web ao inves de um servidor de
sockets.
Referencias Bibliograficas
[Lecheta2010] Lecheta, R. (2010). Google Android - Aprenda a Criar Aplicacoes para
Dispositivos Moveis com o Android SDK. Novatec.
[Pereira2009] Pereira, L. C. O. (2009). Android para Desenvolvedores. Brasport. Sao Paulo.
[Schemberger2012] Shemberguer, E. Freitas, I. Vani, R. (2012) Plataforma Android. Uni-
versidade Estadual do Oeste do Parana.
[Nunes2011] Nunes, G. da R. M. (2011) Desenvolvimento de um Jogo de Domino para
Android. Departamento de Engenharia de Computacao. Universidade do Estado do
Amazonas.
[Albuquerque2012] Albuquerque, F. (2012) Programacao Distribuıda usando Java. Depar-
tamento de Ciencia da Computacao. Universidade de Brasılia.
[Vieira2011] Vieira, L I. da S. (2011) Desenvolvimento de um Jogo Multiusuario Online
usando Programacao Concorrente. Departamento de Engenharia de Computacao. Uni-
versidade do Estado do Amazonas.
[Deitel2010] Deitel, P. Deitel, H. (2010) Java: Como Programar - Traducao Edson Fur-
mankiewicz. Pearson Prentice Hall. Sao Paulo.
[Android2012] Site oficial do sistema operacional Android. Android. Disponıvel em:
<http://http://www.android.com/> Acesso em: 10/06/2012.
[AndroidDev2012] Android Developers. Guia Android para Desenvolvedores. Disponıvel
em: <http://developer.android.com/guide/index.html> Acesso em: 25/04/2012.
REFERÊNCIAS BIBLIOGRÁFICAS 78
[IBM2012] IBM Developer Works. Introducao ao Desenvolvimento do Android. Disponıvel
em: <http://www.ibm.com/developerworks/br/library/os-android-devel> Acesso em:
28/04/2012.
[Geek2012] Geek Information. Investimento em Jogos. Disponıvel em:
<http://www.geek.com.br/posts/17764-brasileiros-deverao-gastar-us-2-bi-em-jogos-
este-ano> Acesso em: 02/06/2012.
[Teleco2012] Teleco Celulares no Mundo. Disponıvel em:
<http://www.teleco.com.br/pais/celular.asp> Acesso em: 28/05/2012.
[NotTec2012] Notıcias Tecnologia Android Supera Apple no Maior Mercado de Telefonia do
Mundo. Disponıvel em: <http://www.noticiastecnologia.com.br/android-supera-apple-
no-maior-mercado-de-telefonia-do-mundo> Acesso em: 02/06/2012.
[Booch2005] Booch, G. Rumbaugh, J. Jacobson, I. (2005) UML: Guia do Usuario -
Traducao Fabio da Silva e Cristina de A. Machado. Elsevier. Rio de Janeiro.
[Alencar2012] Alencar, S. M. (2012) Receituario para Preparacao de Textos Tecnicos.
Universidade Federal de Campina Grande (UFCG).
[Andrews2000] Andrews, G. (2000) Foundations of Multithreaded, Parallel and Distributed
Programming. Addison-Wesley.
[Bates2004] Bates, B. (2004) Game Design. Premier Press.
[Ableson2007] Ableson, F. W. (2007) Unlocking Android - A Developers Guide. Manning.
[Meier2009] Meier, R. (2009) Professional Android Application Development. Indianapolis.
Wiley Publishing.
Apendice
Os codigos-fonte desta monografia encontram-se no CD que acompanha a mesma.