Problems making call using Retrofit on Android

Asked

Viewed 427 times

1

I’m a student and I’m having a hard time understanding where I’m going wrong in a job that the teacher went through. Briefly describing, the teacher provided an API on Github, which after the installation we can add products, suppliers and customers (using the Postman app). Follow the API link - https://github.com/newba/api-d73-a2017. She uses the address http://localhost:3033. Anyway, the job is to make a CRUD using at our choice the VOLLEY library or the RETROFIT library. In Volley I could not do anything. In Retrofit I can access the API find method, but I can’t show the list in my Activity.

Code of class Productolista

    public class ProdutosLista extends AppCompatActivity {

ProgressDialog dialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.produtos_lista);


}

@Override
protected void onStart(){
    super.onStart();
    final ListView lista = (ListView)findViewById(R.id.lvProdutos);

    ApiInterface apiInterface = ApiInterface.retrofit.create(ApiInterface.class);
    /*
    ==============================================================================
    Charging... para evitar açoes indesejadas na aplicação
    ==============================================================================
     */

    dialog = new ProgressDialog(ProdutosLista.this);
    dialog.setMessage("Carregando...");
    dialog.setCancelable(false);
    dialog.show();

    final Call<List<Produto>> call = apiInterface.getProdutos();

    call.enqueue(new Callback<List<Produto>>() {

        @Override
        public void onResponse(Call<List<Produto>> call, Response<List<Produto>> response) {

            if (dialog.isShowing())
                dialog.dismiss();

            final List<Produto> listaProdutos = response.body();
            if (listaProdutos != null){
                ProdutosAdapter adapter = new ProdutosAdapter(getBaseContext(), listaProdutos);

                lista.setAdapter(adapter);


            }

        }

        @Override
        public void onFailure(Call<List<Produto>> call, Throwable t) {

            if (dialog.isShowing())
                dialog.dismiss();

            Toast.makeText(getBaseContext(), "Problema de acesso", Toast.LENGTH_LONG).show();

        }
    });

}

}

This is the Interface code:

    public interface ApiInterface {

@GET ("/products")
Call<List<Produto>>getProdutos();

public static final Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://10.0.2.2:3033")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

}

This is the model class of Product

    public class Produto {

String code;
String name;
int price;
String description;
int inventoryActual;
String supplier;

public int getPrice() {
    return price;
}

public void setPrice(int price) {
    this.price = price;
}

public int getInventoryActual() {
    return inventoryActual;
}

public void setInventoryActual(int inventoryActual) {
    this.inventoryActual = inventoryActual;
}

public String getCode() {
    return code;
}

public void setCode(String code) {
    this.code = code;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getSupplier() {
    return supplier;
}

public void setSupplier(String supplier) {
    this.supplier = supplier;
}

}

This is the Adapter class

    public class ProdutosAdapter extends ArrayAdapter<Produto>{

private final Context context;
private final List<Produto> elementos;

public ProdutosAdapter(Context context, List<Produto> elementos) {
    super(context, R.layout.linha, elementos);
    this.context = context;
    this.elementos = elementos;
}

    @Override
    public View getView(int position, View convertView, ViewGroup parent){

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rowView = inflater.inflate(R.layout.linha, parent, false);

        TextView name = (TextView)rowView.findViewById(R.id.name);
        TextView code = (TextView)rowView.findViewById(R.id.code);
        TextView price = (TextView)rowView.findViewById(R.id.price);
        TextView description = (TextView)rowView.findViewById(R.id.description);
        TextView inventoryActual = (TextView)rowView.findViewById(R.id.inventoryActual);
        TextView supplier = (TextView)rowView.findViewById(R.id.supplier);

        /*
        ==================================================================================
        Set values
        ==================================================================================
         */

        name.setText(elementos.get(position).getName());
        code.setText(elementos.get(position).getCode());
        price.setText(Integer.toString(elementos.get(position).getPrice()));
        description.setText(elementos.get(position).getDescription());
        inventoryActual.setText(Integer.toString(elementos.get(position).getInventoryActual()));
        supplier.setText(elementos.get(position).getSupplier());

        return  rowView;

    }

}

And finally this is XML from the custom list layout

    <?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:orientation="vertical">

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:paddingRight="16dp"
        android:textSize="16sp"
        android:textStyle="bold" />


    <TextView
        android:id="@+id/code"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingRight="16dp" />

    <TextView
        android:id="@+id/description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="3"
        android:paddingRight="16dp"
        />
    <TextView
        android:id="@+id/supplier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="3"
        android:paddingRight="16dp"
        />
    <TextView
        android:id="@+id/inventoryActual"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="3"
        android:paddingRight="16dp"
        />

</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="35dp"
    android:orientation="horizontal">


    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:text="$" />

</LinearLayout>

Aqui a imagem do erro e o log da linha de comando mostrando que ele acessou o método da API

This is the Json:

    {
"total": 2,
"limit": 10,
"skip": 0,
"data": [
    {
        "code": "002",
        "name": "Rims",
        "price": 45,
        "description": "R15 Corolla",
        "inventoryActual": 12,
        "supplier": "NCdaojXnykwxBV2n",
        "removed": null,
        "onlineStatus": null,
        "notes": null,
        "categId": null,
        "_id": "3qsvzvtpDc2JmAEM"
    },
    {
        "code": "001",
        "name": "Pneu",
        "price": 30,
        "description": "R15 Corolla",
        "inventoryActual": 10,
        "supplier": "qvql3wCvEInl5RDZ",
        "removed": null,
        "onlineStatus": null,
        "notes": null,
        "categId": null,
        "_id": "D9ete272UCGgjKDQ"
    }
]

}

  • Looks like the requisition’s going down on the block onFailure, which usually indicates a network error or error when creating the request or response. What is the stack of the Throwable t?

  • @Leonardo Lima, according to the documentation: Throwable initCause(Throwable cause). Initializes the cause of this Throwable to the specified value. A Throwable contains a snapshot of the Execution stack of its thread at the time it was created.

  • He asked what the message is giving on Throwable t

  • Sorry, rsrs. Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

  • So the problem is that your flame awaits a Lista but JSON is responding with Objeto. If you post the JSON you’re receiving I can help you better.

  • @Lmaker posted

Show 1 more comment

1 answer

2


Gson is failing to convert the answer to the informed type. According to your JSON, you must create a class that involves the list of products:

public class RespostaProduto {

  private int total;
  private int limit;
  private int skip;
  private List<Produto> data;

  // Getters e setters
}

And change your interface:

@GET ("/products")
Call<RespostaProduto>getProdutos();
  • They’re making other mistakes right now. I’m trying to understand them right now. The answer was important to understand what’s going on

  • Error:(58, 53) error: cannot find Symbol variable List Error:(58, 58) error: cannot find Symbol variable Product (In the Product class).. I made all the changes that were requested after I made the suggested modification. I did a cast tbem but it gives a crash in the application when I try this gambiarra

  • Remember to import the respective classes? List and Produto?

  • Yes. In the log it says it is returning an empty list. List = null

Browser other questions tagged

You are not signed in. Login or sign up in order to post.