Problems with AsyncTask in second Activity

0

I have an app that should perform the following procedure:

Main_Activity has a button , which when clicked, directs you to a second activity ( Checkdata ). This, in turn, has a textbox that gets data through a public API by JSon. But it is not working, it brings me the following error:

09-16 15:12:22.737: W/dalvikvm(17743): threadid=1: thread exiting with uncaught     exception (group=0x41582d88)
09-16 15:12:22.737: E/AndroidRuntime(17743): FATAL EXCEPTION: main
09-16 15:12:22.737: E/AndroidRuntime(17743): Process: com.tcc.energymonitor, PID: 17743
09-16 15:12:22.737: E/AndroidRuntime(17743): java.lang.NullPointerException
09-16 15:12:22.737: E/AndroidRuntime(17743):    at com.tcc.energymonitor.ConsultaSituacao.onPostExecute(ConsultaSituacao.java:86)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at com.tcc.energymonitor.ConsultaSituacao.onPostExecute(ConsultaSituacao.java:1)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at android.os.AsyncTask.finish(AsyncTask.java:632)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at android.os.Handler.dispatchMessage(Handler.java:102)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at android.os.Looper.loop(Looper.java:212)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at android.app.ActivityThread.main(ActivityThread.java:5151)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at java.lang.reflect.Method.invokeNative(Native Method)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at java.lang.reflect.Method.invoke(Method.java:515)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
09-16 15:12:22.737: E/AndroidRuntime(17743):    at dalvik.system.NativeStart.main(Native Method)

This is my activity Checkdata :

public class Checkdata extends ActionBarActivity implements ConsultaSituacaoListener {

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

        new ConsultaSituacao().execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.checkdata, menu);
        return true;
    }

    /*@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }*/

    @Override
    public void onConsultaConcluida (String situacao) {
        TextView text =  (TextView) findViewById(R.id.main_resultado_servidor);
        text.setText(situacao);

    }

}

And here the AsyncTask process happens, but the program compiles normally, not to being able to identify the error here:

public class ConsultaSituacao extends AsyncTask<Void, Void, String> {

    private ConsultaSituacaoListener listener;
    private static final String URL_STRING = "http://api.openweathermap.org/data/2.5/weather?q=London";

    @Override
    protected String doInBackground(Void... params) {

        try {
            String resultado = consultaServidor();

            return interpretaResultado(resultado);
        }
        catch  (IOException e) {
            e.printStackTrace();
            return null;
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }


    private String interpretaResultado(String resultado) throws JSONException{

        JSONObject object = new JSONObject(resultado);

        JSONArray jsonArray = object.getJSONArray("weather");
        JSONObject jsonObjectWeather = jsonArray.getJSONObject(0);

        int id  = jsonObjectWeather.getInt("id");
        String descricao = jsonObjectWeather.getString("description");

        return "Situação do Tempo em Londres: " + id + " - " + descricao;

    }

    private String consultaServidor () throws IOException {

        InputStream is = null;
        try {
            URL url = new URL(URL_STRING);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.connect();
            conn.getResponseCode();

            is = conn.getInputStream();

            Reader reader = null;
            reader = new InputStreamReader(is);
            char[] buffer = new char [2048];
            reader.read(buffer);
            return new String(buffer);


        } finally {
            if (is != null) {
                is.close ();
            }
        }

    }

    @Override
    protected void onPostExecute(String result) {
        listener.onConsultaConcluida(result);
    }

    public interface ConsultaSituacaoListener {
        void onConsultaConcluida(String situacao);

    }

}

Can you help me?

    
asked by anonymous 16.09.2014 / 20:58

1 answer

2

You forgot to assign ConsultaSituacaoListener to your ConsultaSituacao .

In line: listener.onConsultaConcluida(result); you access null object, generating NullPointerException .

You need to pass Checkdata to ConsultaSituacao :

public class ConsultaSituacao extends AsyncTask<Void, Void, String> {

    // Restante do codigo

    // Setter
    public void setConsultaSituacaoListener(ConsultaSituacaoListener listener) {
        this.listener = listener;
    }

    @Override
    protected void onPostExecute(String result) {
        // Faça uma verificação por referência nula antes de usá-la
        if(listener != null) {
            listener.onConsultaConcluida(result);
        }
    }
}

And call this setter before executing AsyncTask :

public class Checkdata extends ActionBarActivity implements ConsultaSituacaoListener {

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

        ConsultaSituacao cs = new ConsultaSituacao();

        cs.setConsultaSituacaoListener(this);
        cs.execute();
}

Be careful when using AsyncTask where it stores a reference to a Activity .

If your Activity is destroyed before it is finished, it will notify the old Activity , not the new one being built. In this case it does not generate memory leaks, but if your Activity has a reference to AsyncTask , it can generate a leak.

When you have time, take a look at Loaders and AsyncTaskLoader . They are managed by Framework according to the life cycle of Activity / Fragment , and you do not have to worry about it.

    
16.09.2014 / 21:22