Problems with Asynctask in second Activity

Asked

Viewed 68 times

0

I have a app which must carry out the following procedure:

Main_Activity has a button, that when clicking, directs to a second Activity (Checkdata). This, in turn, has a textbox which obtains data through a public API by Json. But it’s not working, brings me the following mistake:

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 happens the process of Asynctask, but the program compiles normally, not 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 help me?

1 answer

2

Forgot to assign the ConsultaSituacaoListener to his ConsultaSituacao.

On the line: listener.onConsultaConcluida(result); you make an access to a null object, generating the NullPointerException.

Need to pass your Checkdata to the 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 one setter before executing the 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();
}

Caution when using AsyncTask where she keeps a reference to a Activity.

If your Activity is destroyed before it ends, it will notify the Activity old, and not the new that is being built. In this case does not generate memory leak, but if Activity had a reference to the AsyncTask, 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 the Activity/Fragment, and you don’t have to worry about it.

Browser other questions tagged

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