Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Aula 4 - Agenda parou

Fiz todos os testes, e não está aparecendo nenhum erro de código, porém ao clicar no botão para salvar o aluno, e aparecer o TOAST aparece a mensagem o app parou.

Segue abaixo meu código.

package br.com.alura.agenda;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import br.com.alura.agenda.modelo.Aluno;

public class FormularioActivity extends AppCompatActivity {

    private FormularioHelper helper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_formulario);
        helper = new FormularioHelper(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        final MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_formulario, menu);
        return super.onCreateOptionsMenu(menu);

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_formulario_ok:

                Aluno aluno = helper.pegaAluno();
                Toast.makeText(FormularioActivity.this, "Aluno" + aluno.getNome() + " Cadastrado com sucesso" ,Toast.LENGTH_SHORT).show();

                finish();
                break;

        }
        return super.onOptionsItemSelected(item);
    }
}
package br.com.alura.agenda;

import android.widget.EditText;
import android.widget.RatingBar;

import br.com.alura.agenda.modelo.Aluno;

public class FormularioHelper {

    private EditText campoNome;
    private EditText campoEndereco;
    private EditText campoTelefone;
    private EditText campoSite;
    private RatingBar campoNota;


    public FormularioHelper(FormularioActivity activity){
        EditText campoNome = (EditText) activity.findViewById(R.id.formulario_nome);
        EditText campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
        EditText campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
        EditText campoSite = (EditText) activity.findViewById(R.id.formulario_site);
        RatingBar campoNota = (RatingBar) activity.findViewById(R.id.formulario_nota);
    }

    public Aluno pegaAluno() {
        Aluno aluno = new Aluno();
        aluno.setNome(campoNome.getText().toString());
        aluno.setEndereco(campoEndereco.getText().toString());
        aluno.setTelefone(campoTelefone.getText().toString());
        aluno.setSite(campoSite.getText().toString());
        aluno.setNota(Double.valueOf(campoNota.getProgress()));
        return aluno;
    }
}
package br.com.alura.agenda.modelo;

public class Aluno {
    private Long id;
    private String nome;
    private String endereco;
    private String telefone;
    private String site;
    private Double nota;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public String getSite() {
        return site;
    }

    public void setSite(String site) {
        this.site = site;
    }

    public Double getNota() {
        return nota;
    }

    public void setNota(Double nota) {
        this.nota = nota;
    }
}

Se tento debugar a app, aparece as seguintes linhas:

Connecting to br.com.alura.agenda Connected to the target VM, address: 'localhost:9332', transport: 'socket' Disconnected from the target VM, address: 'localhost:9332', transport: 'socket'

O que pode ser?

6 respostas

Fala ai Jonathan, olhando o seu código, a principio parece estar correto, tente colar aqui o erro que da no logcat assim que a mensagem de erro aparecer, ai fica mais fácil ajudar.

Opa, Matheus, segue ai o erro. Ainda não consigo entender...

null
            java.nio.BufferOverflowException
            at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:206)
            at com.android.ddmlib.JdwpPacket.move(JdwpPacket.java:197)
            at com.android.ddmlib.Debugger.send(Debugger.java:337)
            at com.android.ddmlib.jdwp.JdwpAgent.incoming(JdwpAgent.java:86)
            at com.android.ddmlib.MonitorThread.processClientActivity(MonitorThread.java:312)
            at com.android.ddmlib.MonitorThread.run(MonitorThread.java:256)
E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: br.com.alura.agenda, PID: 3845
                                                                   java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
                                                                       at br.com.alura.agenda.FormularioHelper.pegaAluno(FormularioHelper.java:27)
                                                                       at br.com.alura.agenda.FormularioActivity.onOptionsItemSelected(FormularioActivity.java:40)
                                                                       at android.app.Activity.onMenuItemSelected(Activity.java:3204)
                                                                       at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:408)
                                                                       at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
                                                                       at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:113)
                                                                       at android.support.v7.app.AppCompatDelegateImplV9.onMenuItemSelected(AppCompatDelegateImplV9.java:679)
                                                                       at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
                                                                       at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:156)
                                                                       at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:969)
                                                                       at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:959)
                                                                       at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:623)
                                                                       at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:154)
                                                                       at android.view.View.performClick(View.java:5637)
                                                                       at android.view.View$PerformClick.run(View.java:22429)
                                                                       at android.os.Handler.handleCallback(Handler.java:751)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                       at android.os.Looper.loop(Looper.java:154)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
solução!

Fala ai Jonathan, seu problema esta no construtor da classe FormularioHelper:

public FormularioHelper(FormularioActivity activity){
    EditText campoNome = (EditText) activity.findViewById(R.id.formulario_nome);
    EditText campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
    EditText campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
    EditText campoSite = (EditText) activity.findViewById(R.id.formulario_site);
    RatingBar campoNota = (RatingBar) activity.findViewById(R.id.formulario_nota);
}

Veja que você esta criando variáveis novas para os campos do formulário, mas o certo seria passar o valor delas para os atributos da classe:

public FormularioHelper(FormularioActivity activity){
    this.campoNome = (EditText) activity.findViewById(R.id.formulario_nome);
    this.campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
    this.campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
    this.campoSite = (EditText) activity.findViewById(R.id.formulario_site);
    this.campoNota = (RatingBar) activity.findViewById(R.id.formulario_nota);
}

Do jeito que você estava fazendo dava erro na linha 27 da classe FormulaioHelper provavelmente porque o atributo referente ao nome do aluno estava nulo, causando um erro de execução.

Espero ter ajudado.

Obrigado Matheus, não precisa declarar novamente, até mesmo sem o this compila. O Android Studio marcou a variável cinza, possivelmente já identificando o erro, mais não prestei atenção.

Estranho pq na aula o professor faz da mesma forma que estava o meu, e compila normal. Sabe me explicar porque?

Obrigado!

Fala ai Jonathan, realmente não precisa adicionar o this porém por questões de boa prática sempre que precisamos referenciar atributo da própria classe, usa-se this.

Durante a aula o primeiro código que o professor fez foi:

public FormularioHelper(FormularioActivity activity)  { 
    EditText campoNome = (EditText) activity.findViewById(R.id.formulario_nome);
    EditText campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
    EditText campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
    EditText campoSite = (EditText) activity.findViewById(R.id.formulario_site);
    RatingBar campoNota = (RatingBar) activity.findViewById(R.id.formulario_nota);    
}

Veja que o mesmo é equivalente ao seu, porém depois ele faz a refatoração para:

public class FormularioHelper(FormularioActivity activity)  {
    campoNome = (EditText) activity.findViewById(R.id.formulario_nome);
    campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
    campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
    campoSite = (EditText) activity.findViewById(R.id.formulario_site);
    campoNota = (RatingBar) activity.findViewById(R.id.formulario_nota);
}

Veja que estamos passando agora os valores para os atributos da classe, para futuramente podermos utiliza-los dentro do nosso método pegaAluno.

No seu código, faltou apenas essa refatoração.

Abraços