Web Service

Web Service pode ser definida como um recurso no qual permite as comunicações entre os programas (que podem ser de plataformas diferentes) geralmente acontecem através do protocolo HTTP.

"Um serviço da Web é um sistema de software projetado para oferecer suporte à interação máquina a máquina interoperável em uma rede. Possui uma interface descrita em um formato processável por máquina (especificamente WSDL). Outros sistemas interagem com o serviço da Web de uma maneira prescrita por sua descrição usando mensagens SOAP, normalmente transmitidas usando HTTP com uma serialização XML em conjunto com outros padrões relacionados à Web (WORLD WIDE WEB)."

Esquematização

A figura 1 mostra uma esquematização das interações entre os componentes. Observe que as aplicações clientes se comunicam com a parte servidora através das APIs (camadas de interfaces). Dessa forma, estas partes se comunicam sem saber os detalhes de implementação de cada uma.

Figura 1

api

Mais detalhes sobre WebService: POLO, Gabriel. O que é um web service? Disponível em: https://gabrielpolo.medium.com/o-que-%C3%A9-um-webservice-c5104d847a85. Acesso em: 21 de ago. 2025.

Diferenças entre Aplicação Web e Web Services: uma aplicação web é um programa acessado por meio de um navegador usando o protocolo HTTP/HTTPS. É criado para interação direta com o usuário. Geralmente oferece uma interface gráfica (UI) renderizada em HTML, CSS e JavaScript. Exemplo: o site do IFTO. Já Web Services é uma tecnologia que permite a comunicação entre sistemas (máquina - máquina). Exemplo quando o aplicativo no seu celular acessa a API da GoogleMaps.

Diferenças Fundamentais

Aspecto Aplicação Web Web Service

Destinatários

Usuários humanos

Outros sistemas ou aplicações

Interface

Interface gráfica (HTML, CSS, JS)

Interface de programação (API, XML, JSON)

Propósito

Oferecer uma experiência interativa

Fornecer dados ou serviços para integração

Exemplo de Uso

Site de reservas de hotel

API para consultar disponibilidade de quartos

Protocolos/Modelos

HTTP/HTTPS

HTTP/HTTPS, SOAP, REST, etc.

Formato de Resposta

Páginas web (HTML)

Dados estruturados (JSON, XML)

HTTP → Protocolo → Transportar as mensagens JSON → Formato→ Representar os dados REST → Arquitetura→ Organizar as regras de comunicação usando HTTP

Exemplo de Web Service usando o modelo de design REST

Endpoint (URL) do serviço para obter a lista de alunos: https://api.exemplo.com/alunos

A resposta pode ser um arquivo JSON representando os dados dos alunos

[
    {
        "id": 1,
        "aluno": "Ana Paula"
    },
    {
        "id": 2,
        "aluno": "Rodrigo André
    }
]

Consumo / Envio de Dados: Arquivos JSON

Através do WebService é possível a troca de mensagens entre aplicações, o formato JSON permite uma comunicação mais leve do que a formatação XML. O JSON usa apenas textos podendo representar um objeto ou uma coleção de objetos.

Exemplo de objeto no JSON

{
	nome: "Paulo,
	curso: "Sistema para Internet",
	idade: 33
}

Exemplo de vetores no JSON

[
{
	nome: "Paulo,
	curso: "Sistema para Internet",
	idade: 33
},
{
	nome: "Paula,
	curso: "Informática",
	idade: 35
},
{
	nome: "Ana,
	curso: "Agronomia",
	idade: 25
}
]

Mais detalhes sobre JSON: JSON org. Introdução ao JSON. Disponível em: https://www.json.org/json-pt.html. Acesso em: 21 de ago. 2025.

Exemplos práticos

Consumo/envio JSON sem biblioteca (exemplo um)

  • activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context=".MainActivity">
        <EditText
            android:id="@+id/editTextNome"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Digite seu Nome" />
        <EditText
            android:id="@+id/editTextDisciplina"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Digite o nome da Disciplina" />
        <EditText
            android:id="@+id/editTextNota"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Digite a Nota"
            android:inputType="number" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/buttonAdicionar"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:onClick="criarLista"
                android:layout_weight="1"
                android:text="A" />
            <Button
                android:id="@+id/buttonGerar"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:onClick="gerarJson"
                android:layout_weight="1"
                android:text="G" />
            <Button
                android:id="@+id/buttonConsumir"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:onClick="abrirTela"
                android:layout_weight="1"
                android:text="C" />
        </LinearLayout>
        <TextView
            android:id="@+id/textViewResultado"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Resultado" />
    </LinearLayout>
  • activity_segunda.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:orientation="vertical"
        android:padding="10dp">
        <ListView
            android:id="@+id/listViewDados"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
  • Estudante.java

    public class Estudante {
        private  String nome,disciplina;
        private  int nota;
        public Estudante(String nome, String disciplina, int nota) {
            this.nome = nome;
            this.disciplina = disciplina;
            this.nota = nota;
        }
        public Estudante() {
        }
        public String getNome() {
            return nome;
        }
        public void setNome(String nome) {
            this.nome = nome;
        }
        public String getDisciplina() {
            return disciplina;
        }
        public void setDisciplina(String disciplina) {
            this.disciplina = disciplina;
        }
        public int getNota() {
            return nota;
        }
        public void setNota(int nota) {
            this.nota = nota;
        }
        @Override
        public String toString() {
            return "Estudante{" +
                    "nome='" + nome + '\'' +
                    '}';
        }
    }
  • MainActivity.java

    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    import androidx.appcompat.app.AppCompatActivity;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity extends AppCompatActivity {
        private EditText editTextNome, editTextDisciplina, editTextNota;
        private List<Estudante> lista;
        private TextView textViewResultado;
        private String retorno;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            editTextNome = findViewById(R.id.editTextNome);
            editTextDisciplina = findViewById(R.id.editTextDisciplina);
            editTextNota = findViewById(R.id.editTextNota);
            textViewResultado = findViewById(R.id.textViewResultado);
            lista = new ArrayList<>();
        }
        public void criarLista(View v) {
            try {
                int nota = Integer.parseInt(editTextNota.getText().toString());
                lista.add(new Estudante(
                        editTextNome.getText().toString(),
                        editTextDisciplina.getText().toString(),
                        nota
                ));
                Toast.makeText(getApplicationContext(), "Item inserido", Toast.LENGTH_SHORT).show();
            } catch (NumberFormatException e) {
                Toast.makeText(getApplicationContext(), "Digite uma nota válida", Toast.LENGTH_SHORT).show();
            }
        }
        public String criarJson() {
            JSONArray jsonArray = new JSONArray();
            for (Estudante est : lista) {
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("nomeEstudante", est.getNome());
                    jsonObject.put("disciplinaEstudante", est.getDisciplina());
                    jsonObject.put("notaEstudante", est.getNota());
                    jsonArray.put(jsonObject);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return "{\"estudantes\":" + jsonArray.toString() + "}";
        }
        public void gerarJson(View v) {
            retorno = criarJson();
            textViewResultado.setText(retorno);
        }
        public void abrirTela(View v) {
            if (retorno == null || retorno.isEmpty()) {
                Toast.makeText(this, "Nenhum dado gerado", Toast.LENGTH_SHORT).show();
                return;
            }
            Intent intent = new Intent(getApplicationContext(), SegundaActivity.class);
            intent.putExtra("dados", retorno);
            startActivity(intent);
        }
    }
  • SegundaActivity.java

    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import androidx.appcompat.app.AlertDialog;
    import androidx.appcompat.app.AppCompatActivity;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    import java.util.ArrayList;
    import java.util.List;
    public class SegundaActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
        private String dadosJSON;
        private ListView listView;
        private List<Estudante> lista;
        private ArrayAdapter<Estudante> adapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_segunda);
            dadosJSON = getIntent().getStringExtra("dados");
            listView = findViewById(R.id.listViewDados);
            lista = consumirJSON();
            adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, lista);
            listView.setAdapter(adapter);
            listView.setOnItemClickListener(this);
        }
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setTitle("Dados Estudante")
                    .setMessage("Nome: " + lista.get(position).getNome()
                            + "\nDisciplina: " + lista.get(position).getDisciplina()
                            + "\nNota: " + lista.get(position).getNota())
                    .setPositiveButton("OK", null)
                    .create();
            alertDialog.show();
        }
        private List<Estudante> consumirJSON() {
            List<Estudante> listaEstudantes = new ArrayList<>();
            try {
                JSONObject jsonObject = new JSONObject(dadosJSON);
                JSONArray jsonArray = jsonObject.getJSONArray("estudantes");
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject object = jsonArray.getJSONObject(i);
                    Estudante estudante = new Estudante();
                    estudante.setNome(object.getString("nomeEstudante"));
                    estudante.setDisciplina(object.getString("disciplinaEstudante"));
                    estudante.setNota(object.getInt("notaEstudante"));
                    listaEstudantes.add(estudante);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return listaEstudantes;
        }
    }

No exemplo anterior foi usado o JSON de forma nativa. Existe uma opção mais fácil para criar e consumir o arquivo usando outras bibliotecas. Veja o exemplo do mesmo projeto, porém usando a biblioteca Gson.

Consumo/envio JSON com biblioteca (exemplo dois)

Inicialmente deve-se adicionar a biblioteca GSON no projeto, portanto, no arquivo Gradle na área de dependências, adicione a linha: implementation("com.google.code.gson:gson:2.11.0")

  • Estudante.java

    public class Estudante {
        private String nome;
        private String disciplina;
        private int nota;
        public Estudante(String nome, String disciplina, int nota) {
            this.nome = nome;
            this.disciplina = disciplina;
            this.nota = nota;
        }
        public Estudante() {}
        public String getNome() {
            return nome;
        }
        public void setNome(String nome) {
            this.nome = nome;
        }
        public String getDisciplina() {
            return disciplina;
        }
        public void setDisciplina(String disciplina) {
            this.disciplina = disciplina;
        }
        public int getNota() {
            return nota;
        }
        public void setNota(int nota) {
            this.nota = nota;
        }
        @Override
        public String toString() {
            return nome + " - " + disciplina + " (" + nota + ")";
        }
    }
  • activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp">
        <EditText
            android:id="@+id/editTextNome"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Digite seu Nome" />
        <EditText
            android:id="@+id/editTextDisciplina"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Digite a Disciplina" />
        <EditText
            android:id="@+id/editTextNota"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Digite a Nota"
            android:inputType="number" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="12dp">
            <Button
                android:id="@+id/buttonAdd"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="criarLista"
                android:text="Adicionar" />
            <Button
                android:id="@+id/buttonGerar"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="gerarJSON"
                android:text="Gerar JSON" />
            <Button
                android:id="@+id/buttonConsumir"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="abrirTela"
                android:text="Consumir" />
        </LinearLayout>
        <TextView
            android:id="@+id/textViewResultado"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Resultado aparecerá aqui"
            android:layout_marginTop="12dp" />
    </LinearLayout>
  • activity_segunda.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp">
        <ListView
            android:id="@+id/listViewDados"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
  • MainActivity.java

    import android.os.Bundle;
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    import androidx.appcompat.app.AppCompatActivity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    import com.google.gson.Gson;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity extends AppCompatActivity {
        private EditText editTextNome, editTextDisciplina, editTextNota;
        private TextView textViewResultado;
        private List<Estudante> lista;
        private String retorno;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            editTextNome = findViewById(R.id.editTextNome);
            editTextDisciplina = findViewById(R.id.editTextDisciplina);
            editTextNota = findViewById(R.id.editTextNota);
            textViewResultado = findViewById(R.id.textViewResultado);
            lista = new ArrayList<>();
        }
        public void criarLista(View v) {
            try {
                int nota = Integer.parseInt(editTextNota.getText().toString());
                lista.add(new Estudante(
                        editTextNome.getText().toString(),
                        editTextDisciplina.getText().toString(),
                        nota
                ));
                Toast.makeText(getApplicationContext(), "Item inserido", Toast.LENGTH_SHORT).show();
            } catch (NumberFormatException e) {
                Toast.makeText(getApplicationContext(), "Digite uma nota válida", Toast.LENGTH_SHORT).show();
            }
        }
        public String criarJSON(List<Estudante> dados) {
            Gson gson = new Gson();
            return gson.toJson(dados);
        }
        public void gerarJSON(View v) {
            retorno = criarJSON(lista);
            textViewResultado.setText(retorno);
        }
        public void abrirTela(View v) {
            if (retorno == null || retorno.isEmpty()) {
                Toast.makeText(this, "Nenhum dado gerado", Toast.LENGTH_SHORT).show();
                return;
            }
            Intent it = new Intent(getApplicationContext(), SegundaActivity.class);
            it.putExtra("dados", retorno);
            startActivity(it);
        }
    }
  • SegundaActivity.java

    import android.os.Bundle;
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    import java.lang.reflect.Type;
    import java.util.List;
    public class SegundaActivity extends AppCompatActivity {
        private String dadosJSON;
        private ListView listView;
        private List<Estudante> lista;
        private ArrayAdapter<Estudante> adapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_segunda);
            dadosJSON = getIntent().getStringExtra("dados");
            listView = findViewById(R.id.listViewDados);
            lista = consumirJSON();
            if (lista != null) {
                adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, lista);
                listView.setAdapter(adapter);
            }
        }
        private List<Estudante> consumirJSON() {
            if (dadosJSON != null) {
                Gson gson = new Gson();
                Type type = new TypeToken<List<Estudante>>() {}.getType();
                List<Estudante> listaEstudantes = gson.fromJson(dadosJSON, type);
                Toast.makeText(getApplicationContext(), "Carregado: " + listaEstudantes.size() + " itens", Toast.LENGTH_SHORT).show();
                return listaEstudantes;
            }
            return null;
        }
    }

Classe TypenToken: classe genérica presente na lib GSON que possibilita obter um tipo de dado em tempo de execução e recuperá-lo. Para mais detalhes da classe acesse a documentação do Java, disponível em: https://www.javadoc.io/doc/com.google.code.gson/gson/2.6.2/com/google/gson/reflect/TypeToken.html.

Exemplos práticos (Consumo/envio JSON com biblioteca remotamente)

Inicialmente cria-se um novo projeto no Android Studio. No arquivo build.gradle (Module:app) deve ser adicionado a linha implementation ‘com.google.code.gson:gson:2.11.0'. No arquivo AndroidManifest.xml deve ser adicionado a linha <uses-permission android:name="android.permission.INTERNET"/>.

Neste exemplo, será consumido o JSON retornado da seguinte URL: https://jsonplaceholder.typicode.com/posts/. Antes de implementar a classe MainActivity, primeiro será criado a classe POJO derivada do arquivo JSON. Neste material será usado a biblioteca criada por joelittlejohn, disponível em: http://www.jsonschema2pojo.org/. Esse site permite fazer a conversão de JSON para classe POJO para ser usada com a biblioteca GSON. A figura 1 mostra o site.

json pojo

Após a criação da class POJO, pode-se dar continuidade no projeto. Os códigos estão disponibilizados a seguir:

No arquivo AndroidManifest.xml adicione <uses-permission android:name="android.permission.INTERNET" />

  • Conversao.java

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    public class Conversao {
        public String converter(InputStream inputStream) {
            if (inputStream == null) return null;
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            StringBuilder stringBuilder = new StringBuilder();
            String conteudo;
            try {
                while ((conteudo = bufferedReader.readLine()) != null) {
                    stringBuilder.append(conteudo).append("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return stringBuilder.toString();
        }
    }
  • Conexao.java

    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    public class Conexao {
        public InputStream obterRespostaHTTP(String end) {
            try {
                URL url = new URL(end);
                HttpURLConnection conexao = (HttpURLConnection) url.openConnection();
                conexao.setRequestMethod("GET");
                conexao.connect();
                return new BufferedInputStream(conexao.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
  • Item.java

    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    public class Item {
        @SerializedName("userId")
        @Expose
        private Integer userId;
        @SerializedName("id")
        @Expose
        private Integer id;
        @SerializedName("title")
        @Expose
        private String title;
        @SerializedName("body")
        @Expose
        private String body;
        public Integer getUserId() { return userId; }
        public void setUserId(Integer userId) { this.userId = userId; }
        public Integer getId() { return id; }
        public void setId(Integer id) { this.id = id; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getBody() { return body; }
        public void setBody(String body) { this.body = body; }
        @Override
        public String toString() {
            return "Item{" +
                    "userId=" + userId +
                    ", id=" + id +
                    ", title='" + title + '\'' +
                    ", body='" + body + '\'' +
                    '}';
        }
    }
  • activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context=".MainActivity">
        <ListView
            android:id="@+id/listViewDados"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@android:color/darker_gray"
            android:dividerHeight="1dp" />
    </LinearLayout>
  • MainActivity.java

    import android.os.Bundle;
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    import java.io.InputStream;
    import java.lang.reflect.Type;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity extends AppCompatActivity {
        private ListView listView;
        private ArrayAdapter<String> adapter;
        private List<String> listaStrings;
        private final String URL = "https://jsonplaceholder.typicode.com/posts";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listView = findViewById(R.id.listViewDados);
            listaStrings = new ArrayList<>();
            adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listaStrings);
            listView.setAdapter(adapter);
            new obterDados().execute();
        }
        private class obterDados extends AsyncTask<Void, Void, List<Item>> {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                Toast.makeText(getApplicationContext(), "Download começando...", Toast.LENGTH_SHORT).show();
            }
            @Override
            protected List<Item> doInBackground(Void... voids) {
                Conexao conexao = new Conexao();
                InputStream inputStream = conexao.obterRespostaHTTP(URL);
                Conversao Conversao = new Conversao();
                String textoJSON = Conversao.converter(inputStream);
                Log.i("JSON", "doInBackground: " + textoJSON);
                if (textoJSON != null) {
                    Gson gson = new Gson();
                    Type type = new TypeToken<List<Item>>() {}.getType();
                    return gson.fromJson(textoJSON, type);
                }
                return null;
            }
            @Override
            protected void onPostExecute(List<Item> dadosBaixados) {
                super.onPostExecute(dadosBaixados);
                if (dadosBaixados != null) {
                    listaStrings.clear();
                    for (Item item : dadosBaixados) {
                        listaStrings.add("UserID: " + item.getUserId()
                                + "\nID: " + item.getId()
                                + "\nTítulo: " + item.getTitle()
                                + "\nBody: " + item.getBody());
                    }
                    adapter.notifyDataSetChanged();
                } else {
                    Toast.makeText(getApplicationContext(), "Não foi possível obter JSON", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

A classe AsyncTask foi descontinuada, segue a versão abaixo usando a classe Executor:

  • AndroidManisfest.xml: <uses-permission android:name="android.permission.INTERNET"/>

  • Arquivo Gradle: implementation("com.google.code.gson:gson:2.11.0")

  • Versão sem VIEWMODEL

  • Item.java

    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    public class Item {
        @SerializedName("userId")
        @Expose
        private Integer userId;
        @SerializedName("id")
        @Expose
        private Integer id;
        @SerializedName("title")
        @Expose
        private String title;
        @SerializedName("body")
        @Expose
        private String body;
        public Integer getUserId() { return userId; }
        public void setUserId(Integer userId) { this.userId = userId; }
        public Integer getId() { return id; }
        public void setId(Integer id) { this.id = id; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getBody() { return body; }
        public void setBody(String body) { this.body = body; }
        @Override
        public String toString() {
            return "Item{" +
                    "userId=" + userId +
                    ", id=" + id +
                    ", title='" + title + '\'' +
                    ", body='" + body + '\'' +
                    '}';
        }
    }
  • Conexao.java

    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    public class Conexao {
        public InputStream obterRespostaHTTP(String end) {
            HttpURLConnection conexao = null;
            try {
                URL url = new URL(end);
                conexao = (HttpURLConnection) url.openConnection();
                conexao.setConnectTimeout(10000);
                conexao.setReadTimeout(20000);
                conexao.setRequestMethod("GET");
                conexao.connect();
                return new BufferedInputStream(conexao.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (conexao != null) {
                    conexao.disconnect();
                }
            }
            return null;
        }
    }
  • Conversao.java

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    public class Conversao {
        public String converter(InputStream inputStream) {
            if (inputStream == null) return null;
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            StringBuilder stringBuilder = new StringBuilder();
            String conteudo;
            try {
                while ((conteudo = bufferedReader.readLine()) != null) {
                    stringBuilder.append(conteudo).append("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return stringBuilder.toString();
        }
    }
  • Repositorio.java

    import android.os.Handler;
    import android.os.Looper;
    import android.util.Log;
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    import java.io.InputStream;
    import java.lang.reflect.Type;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class Repositorio {
        private static final String URL = "https://jsonplaceholder.typicode.com/posts";
        private ExecutorService executor;
        private Handler mainHandler;
        public Repositorio() {
            this.executor = Executors.newSingleThreadExecutor();
            this.mainHandler = new Handler(Looper.getMainLooper());
        }
        public interface Callback{
            void sucesso(List<String> items);
            void erro(String mensagem);
        }//
        private void sucesso(Callback c, List<String> itens){
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    c.sucesso(itens);
                }
            });
        }//
        private void erro(Callback c, String mensagem){
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    c.erro(mensagem);
                }
            });
        }//
        public void obterDados(Callback c){
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Conexao conexao = new Conexao();
                        InputStream inputStream = conexao.obterRespostaHTTP(URL);
                        Conversao conversao = new Conversao();
                        String jsonString = conversao.converter(inputStream);
                        if (jsonString == null || jsonString.isEmpty()) {
                            erro(c, "Resposta vazia");
                            return;
                        }
                        Log.i("JSON", "Recebido: " + jsonString);
                        Gson gson = new Gson();
                        Type type = new TypeToken<List<Item>>() {}.getType();
                        List<Item> dados = gson.fromJson(jsonString, type);
                        List<String> itens = new ArrayList<>();
                        for (Item i:dados) {
                            itens.add(i.toString());
                        }
                        sucesso(c, itens);
                    } catch (Exception e) {
                        e.printStackTrace();
                        erro(c,"erro ao baixar: "+e.getMessage());
                    }
                }
            });
        }//
    }//class
  • activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context=".MainActivity">
        <ListView
            android:id="@+id/listViewDados"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@android:color/darker_gray"
            android:dividerHeight="1dp" />
    </LinearLayout>
  • MainActivity.java

    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity extends AppCompatActivity{
            private ListView listView;
            private ArrayAdapter<String> adapter;
            private List<String> lista;
            private Repositorio repositorio;
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                listView = findViewById(R.id.listViewDados);
                lista = new ArrayList<>();
                adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, lista);
                listView.setAdapter(adapter);
                repositorio = new Repositorio();
                carregarDados();
            }
            private void carregarDados() {
                Toast.makeText(this, "Download começando...", Toast.LENGTH_SHORT).show();
                repositorio.obterDados(new Repositorio.Callback() {
                    @Override
                    public void sucesso(List<String> itens) {
                        lista.clear();
                        lista.addAll(itens);
                        adapter.notifyDataSetChanged();
                        Toast.makeText(MainActivity.this, "Dados carregados (" + itens.size() + ")", Toast.LENGTH_SHORT).show();
                    }
                    @Override
                    public void erro(String message) {
                        Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
                    }
                });
            }
    }
  • Versão com VIEWMODEL

  • Conexao.java

    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    public class Conexao {
        public InputStream obterRespostaHTTP(String end) {
            HttpURLConnection conexao = null;
            try {
                URL url = new URL(end);
                conexao = (HttpURLConnection) url.openConnection();
                conexao.setConnectTimeout(50000);
                conexao.setReadTimeout(50000);
                conexao.setRequestMethod("GET");
                conexao.connect();
                return new BufferedInputStream(conexao.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
  • Conversao.java

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    public class Conversao {
        public String converter(InputStream inputStream) {
            if (inputStream == null) return null;
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            StringBuilder stringBuilder = new StringBuilder();
            String conteudo;
            try {
                while ((conteudo = bufferedReader.readLine()) != null) {
                    stringBuilder.append(conteudo).append("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return stringBuilder.toString();
        }
    }
  • Item.java

    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    public class Item {
        @SerializedName("userId")
        @Expose
        private Integer userId;
        @SerializedName("id")
        @Expose
        private Integer id;
        @SerializedName("title")
        @Expose
        private String title;
        @SerializedName("body")
        @Expose
        private String body;
        public Integer getUserId() { return userId; }
        public void setUserId(Integer userId) { this.userId = userId; }
        public Integer getId() { return id; }
        public void setId(Integer id) { this.id = id; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getBody() { return body; }
        public void setBody(String body) { this.body = body; }
        @Override
        public String toString() {
            return "Item{" +
                    "userId=" + userId +
                    ", id=" + id +
                    ", title='" + title + '\'' +
                    ", body='" + body + '\'' +
                    '}';
        }
    }
  • Repositorio.java

    import android.util.Log;
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    import java.io.InputStream;
    import java.lang.reflect.Type;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class Repositorio {
        private static final String URL = "https://jsonplaceholder.typicode.com/posts";
        private ExecutorService executor;
        public Repositorio() {
            executor = Executors.newSingleThreadExecutor();
        }
        public interface Callback {
            void sucesso(List<String> items);
            void erro(String mensagem);
        }
        public void obterDados(Callback c) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Conexao conexao = new Conexao();
                        InputStream inputStream = conexao.obterRespostaHTTP(URL);
                        Conversao conversao = new Conversao();
                        String jsonString = conversao.converter(inputStream);
                        if (jsonString == null || jsonString.isEmpty()) {
                            c.erro("Resposta vazia");
                            return;
                        }
                        Log.i("JSON", "Recebido " + jsonString);
                        Gson gson = new Gson();
                        Type type = new TypeToken<List<Item>>(){}.getType();
                        List<Item> dados = gson.fromJson(jsonString, type);
                        List<String> itens = new ArrayList<>();
                        if (dados != null) {
                            for (Item i : dados) {
                                itens.add(i.toString());
                            }
                        }
                        c.sucesso(itens);
                    } catch (Exception e) {
                        e.printStackTrace();
                        c.erro("Erro ao baixar dados: " + e.getMessage());
                    }
                }
            });
        }
        public void shutdown() {
            executor.shutdown();
        }
    }
  • MainViewModel.java

    import androidx.lifecycle.LiveData;
    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    import java.util.List;
    public class MainViewModel extends ViewModel {
        private Repositorio repositorio;
        private MutableLiveData<List<String>> lista;
        private MutableLiveData<String> mensagem;
        public MainViewModel() {
            this.repositorio = new Repositorio();
            lista = new MutableLiveData<>();
            mensagem = new MutableLiveData<>();
        }
        public LiveData<List<String>> getLista() {
            return lista;
        }
        public LiveData<String> getMensagem() {
            return mensagem;
        }
        public void carregarDados() {
            repositorio.obterDados(new Repositorio.Callback() {
                @Override
                public void sucesso(List<String> itens) {
                    lista.postValue(itens);
                }
                @Override
                public void erro(String msg) {
                    mensagem.postValue(msg);
                }
            });
        }
        @Override
        protected void onCleared() {
            super.onCleared();
            repositorio.shutdown();
        }
    }//
  • activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp"
        tools:context=".MainActivity">
        <ListView
            android:id="@+id/listViewDados"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@android:color/darker_gray"
            android:dividerHeight="1dp" />
    </LinearLayout>
  • MainActivity.java

    import android.os.Bundle;
    import android.view.View;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProvider;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity extends AppCompatActivity {
        private ListView listView;
        private ArrayAdapter<String> adapter;
        private List<String> dados = new ArrayList<>();
        private MainViewModel viewModel;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listView = findViewById(R.id.listViewDados);
            adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dados);
            listView.setAdapter(adapter);
            viewModel = new ViewModelProvider(this).get(MainViewModel.class);
            viewModel.getLista().observe(this, new Observer<List<String>>() {
                @Override
                public void onChanged(List<String> lista) {
                    if (lista != null) {
                        dados.clear();
                        dados.addAll(lista);
                        adapter.notifyDataSetChanged();
                        Toast.makeText(MainActivity.this,
                                        "Carregados: " + dados.size(),
                                        Toast.LENGTH_SHORT)
                                .show();
                    }
                }
            });
            viewModel.getMensagem().observe(this, new Observer<String>() {
                @Override
                public void onChanged(String error) {
                    if (error != null) {
                        Toast.makeText(MainActivity.this,
                                        error,
                                        Toast.LENGTH_LONG)
                                .show();
                    }
                }
            });
            viewModel.carregarDados();
        }
    }
  • Referências: As classes Conexao e Conversao foram adaptadas do site Stack Overflow (https://stackoverflow.com/questions/58889465/json-parsing-error-value-jsonstr-of-type-java-lang-string-cannot-be-converted-t) realizada pelo usuário Saad ( https://stackoverflow.com/users/7741722/saad) e respondida por Mike M. (https://stackoverflow.com/users/2850651/mike-m). Acesso em: 21 de ago. 2025.

  • Exemplos práticos (API JSON SERVER)

Neste exemplo, será usado uma biblioteca que permite criar uma API REST falsa destinada à testes. Para maiores detalhes sobre o biblioteca, acesse o endereço: https://github.com/typicode/json-server. Acesso em: 30 de jan. 2023. No Android, por questões de segurança, atualmente aceita apenas comunicação via HTTPS. A equipe que desenvolveu a biblioteca também disponibiliza um servidor com HTTPS chamado My JSON Server cujo o endereço para acesso é: https://my-json-server.typicode.com/. Na página Web supracitada tem-se os passos necessários para usar o servidor. São etapas simples, como pode ser vista a seguir:

  • Crie uma conta no GitHub;

  • Crie um repositório;

  • Crie um arquivo chamado db.json (coloque o conteúdo já disponibilizado neste exemplo).

  • Acesse o endereço https://my-json-server.typicode.com/<coloque seu nome de usuário><coloque o nome do repositório criado>

E pronto, o seu arquivo json já estará disponível no servidor on-line. A figura 3 mostra o resultado.

Figura 3

resultado json server

Observe na figura 3 que há 3 links clicáveis:

  • na opção agenda, serão mostrados os dados contidos dentro do array agenda;

  • na opção adicionais, serão mostrados os dados contidos dentro do array adicionais;

  • e na opção db, serão mostrados tanto o array agenda e o adicionais com os conteúdos.

Agora, basta criar um app cliente no Android para consumir os dados disponíveis em: https://my-json-server.typicode.com/<seu nome de usuário no GitHub><seu repositório>/db.

Outra opção é usar diretamente a API do GitHub, basta criar um repositório público, adicionar o arquivo db.json, clicar no botão RAW e copiar a URL gerada.

Para os projetos das aulas vamos usar as seguintes camadas: VIEW → VIEWMODEL → USECASE (opcional) → REPOSITORY. Para mais detalhes sobre arquitetura de app, segue o material: GOOGLE DEVELOPERS, Guia para a arquitetura do app, disponível em: https://developer.android.com/topic/architecture?hl=pt-br. Acessado em: 26 de fev. 2026.