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

Dúvida no Ex. 7 da Aula 5 - Integração com webservice

Pessoal boa tarde, estou com problemas no meu projeto, deve ser um probleminha simples, mas não encontrei ele. A mensagem de errado é a seguinte: FATAL EXCEPTION: AsyncTask #1 e essa é a causa: Can't create handler inside thread that has not called Looper.prepare()

Logcat:

03-30 15:43:07.793 326-733/com.example.gabriel.agenda E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
                                                                        Process: com.example.gabriel.agenda, PID: 326
                                                                        java.lang.RuntimeException: An error occured while executing doInBackground()
                                                                            at android.os.AsyncTask$3.done(AsyncTask.java:300)
                                                                            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
                                                                            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
                                                                            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                                            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                                                                            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                                            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                                            at java.lang.Thread.run(Thread.java:818)
                                                                         Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                                                                            at android.os.Handler.<init>(Handler.java:200)
                                                                            at android.os.Handler.<init>(Handler.java:114)
                                                                            at android.widget.Toast$TN.<init>(Toast.java:336)
                                                                            at android.widget.Toast.<init>(Toast.java:100)
                                                                            at android.widget.Toast.makeText(Toast.java:250)
                                                                            at com.example.gabriel.agenda.converter.AlunoConverter.toJson(AlunoConverter.java:41)
                                                                            at com.example.gabriel.agenda.EnviarDadosServidor.doInBackground(EnviarDadosServidor.java:38)
                                                                            at com.example.gabriel.agenda.EnviarDadosServidor.doInBackground(EnviarDadosServidor.java:17)
                                                                            at android.os.AsyncTask$2.call(AsyncTask.java:288)
                                                                            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
                                                                            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                                                                            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                                                                            at java.lang.Thread.run(Thread.java:818) 
03-30 15:43:08.096 326-408/com.example.gabriel.agenda D/OpenGLRenderer: endAllStagingAnimators on 0xb4bc3c00 (RippleDrawable) with handle 0x9e87d680
03-30 15:43:08.319 326-326/com.example.gabriel.agenda E/WindowManager: android.view.WindowLeaked: Activity com.example.gabriel.agenda.ListaAlunosActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{37012215 V.E..... R......D 0,0-1368,643} that was originally added here
                                                                           at android.view.ViewRootImpl.<init>(ViewRootImpl.java:375)
                                                                           at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
                                                                           at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
                                                                           at android.app.Dialog.show(Dialog.java:298)
                                                                           at android.app.ProgressDialog.show(ProgressDialog.java:116)
                                                                           at android.app.ProgressDialog.show(ProgressDialog.java:104)
                                                                           at com.example.gabriel.agenda.EnviarDadosServidor.onPreExecute(EnviarDadosServidor.java:27)
                                                                           at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
                                                                           at android.os.AsyncTask.execute(AsyncTask.java:535)
                                                                           at com.example.gabriel.agenda.ListaAlunosActivity.onOptionsItemSelected(ListaAlunosActivity.java:75)
                                                                           at android.app.Activity.onMenuItemSelected(Activity.java:2892)
                                                                           at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:404)
                                                                           at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:167)
                                                                           at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:100)
                                                                           at android.support.v7.app.AppCompatDelegateImplV7.onMenuItemSelected(AppCompatDelegateImplV7.java:646)
                                                                           at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:811)
                                                                           at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
                                                                           at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:958)
                                                                           at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:948)
                                                                           at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:618)
                                                                           at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:139)
                                                                           at android.view.View.performClick(View.java:4761)
                                                                           at android.view.View$PerformClick.run(View.java:19767)
                                                                           at android.os.Handler.handleCallback(Handler.java:739)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                           at android.os.Looper.loop(Looper.java:135)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5312)
                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                           at java.lang.reflect.Method.invoke(Method.java:372)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
03-30 15:43:09.726 326-733/com.example.gabriel.agenda I/Process: Sending signal. PID: 326 SIG: 9

Task para enviar dados no Servidor:

    @Override
    protected void onPreExecute() {
        aguarde = ProgressDialog.show(context, "Aguarde", "Enviando dados para servidor...", true, true);
        aguarde.show();
    }

    @Override
    protected String doInBackground(Void... params) {
        WebCliente webCliente = new WebCliente(context);
        AlunoConverter converter = new AlunoConverter(context);
        AlunoDAO alunoDAO = new AlunoDAO(context);
        List<Aluno> alunoList = alunoDAO.listar();
        alunoDAO.close();
        String json = converter.toJson(alunoList);
        String post = webCliente.post(json);
        return post;
    }

    @Override
    protected void onPostExecute(String post) {
        aguarde.dismiss();
        Toast.makeText(context, post, Toast.LENGTH_LONG).show();
    }

WebClient:

package com.example.gabriel.agenda;

import android.content.Context;
import android.widget.Toast;

import java.io.IOException;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;

/**
 * Created by Gabriel on 29/03/2016.
 */
public class WebCliente {
    private final Context context;

    public WebCliente(Context context) {
        this.context = context;
    }

    public String post(String json){
        try {
            URL url = new URL("https://www.caelum.com.br/mobile");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("Content-type", "application/json");
            connection.setRequestProperty("Accept", "application/json");

            connection.setDoOutput(true);

            PrintStream outout = new PrintStream(connection.getOutputStream());
            outout.println(json);

            connection.connect();

            Scanner scanner = new Scanner(connection.getInputStream());
            String resposta = scanner.next();
            return resposta;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

O que significa essa causa Can't create handler inside thread that has not called Looper.prepare()?

2 respostas
solução!

De acordo com essas duas linhas da sua stacktrace:

at android.widget.Toast.makeText(Toast.java:250)
at com.example.gabriel.agenda.converter.AlunoConverter.toJson(AlunoConverter.java:41)

Dentro do seu AlunoConverter, lá na linha 41, você provavelmente tá disparando um Toast.

No entanto, você está usando esse toJson dentro do doInBackground:

    @Override
    protected String doInBackground(Void... params) {
        //...
        String json = converter.toJson(alunoList);
        //...
    }

Ou seja, você tenta disparar um Toast dentro do doInBackground. Para o Toast ser exibido, ele precisa ser disparado na thread da tela, só que o doInBackground roda numa thread diferente da thread da tela.

Então o Android avisa isso pra você disparando essa mensagem na exception:

Can't create handler inside thread that has not called Looper.prepare()

Em outras palavras: "não posso me ligar a outra thread antes de explicitamente ser configurado para isso".

Felipe obrigado.