How to pass the application context to the Adapter by reading Json using Asynctask?

Asked

Viewed 1,222 times

1

private class GetEmpresas extends AsyncTask<Void, Void, Void> {

... 

@Override
    protected Void doInBackground(Void... arg0) {
        // Creating service handler class instance
        ServiceHandler sh = new ServiceHandler();

        // Making a request to url and getting response
        String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);

        //Log.d("Response: ", "> " + jsonStr);

        if (jsonStr != null) {

            try {
                JSONObject jsonObj = new JSONObject(jsonStr);

                // Getting JSON Array node
                empresasJson = jsonObj.getJSONArray(TAG_EMPRESAS);

                // looping through All Contacts
                for (int i = 0; i < empresasJson.length(); i++) {

                    JSONObject c = empresasJson.getJSONObject(i);

                    String id = c.getString(TAG_ID);
                    String name = c.getString(TAG_NOME);
                    String cidade = c.getString(TAG_CIDADE);
                    String endereco = c.getString(TAG_ENDERECO);

                    // tmp hashmap for single contact
                    HashMap<String, String> contact = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    contact.put(TAG_ID, id);
                    contact.put(TAG_NOME, name);
                    contact.put(TAG_CIDADE, cidade);
                    contact.put(TAG_ENDERECO, endereco);

                                                    empresas = new ArrayList<Empresas>();

                    Empresas item = new Empresas(name,endereco, R.drawable.logo);

                    empresas.add(item);

                    adapter = new AdapterEmpresas(empresas, ?????);

                    listView.setAdapter(adapter);

                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Log.e("ServiceHandler", "Couldn't get any data from the url");
        }

        return null;
    }

     ....

}

ERROR

01-30 18:21:25.058: E/AndroidRuntime(8276): FATAL EXCEPTION: AsyncTask #1
01-30 18:21:25.058: E/AndroidRuntime(8276): java.lang.RuntimeException: An error occured while executing doInBackground()
01-30 18:21:25.058: E/AndroidRuntime(8276):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at java.lang.Thread.run(Thread.java:856)
01-30 18:21:25.058: E/AndroidRuntime(8276): Caused by: java.lang.NullPointerException
01-30 18:21:25.058: E/AndroidRuntime(8276):     at com.solutudo.activities.Main$GetEmpresas.doInBackground(Main.java:137)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at com.solutudo.activities.Main$GetEmpresas.doInBackground(Main.java:1)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-30 18:21:25.058: E/AndroidRuntime(8276):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-30 18:21:25.058: E/AndroidRuntime(8276):     ... 4 more

Question:

How do I pass the context of the method Adapter that gets the context?

Before loading the Json, I had created another class, and when I passed the this as a parameter, it worked correctly. Now in this other method it does not work.

2 answers

1


I suggest some changes. First, the reason:

Operations related to the Android UI cannot be done in the InBackground method, as it does not run in the Main Thread. UI operations can only be performed on Main Thread. Thus, you should perform UI operations in the onPostExecute method, as it runs in Main Thread.

About the Context passage, the lucasb.Aquino suggestion is correct.

About the Nullpointerexception error, I believe it may be due to the inappropriate UI update point.

That way your code would look like this

The onCreate method

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new GetEmpresas(this).execute();
}

Your Asynctask Getempresas

private class GetEmpresas extends AsyncTask<Void, Void, List<Empresas>> {

    private Context mContext;

    public GetEmpresas(Context context) {
        super();
        mContext = context;
    }

    @Override
    protected List<Empresas> doInBackground(Void... params) {

        ...

        return empresas;
    }

    @Override
    protected void onPostExecute(List<Empresas> listEmpresas) {
        super.onPostExecute(listEmpresas);

        adapter = new AdapterEmpresas(listEmpresas, mContext);

        listView.setAdapter(adapter);

    }

}

If Nullpointerexception persists, make more of your code available so that a better assessment of the problem is possible.

  • Legal Francisco, thanks for the information. Now I put the filling of the list in Postexecute and it worked. Also missed, I have started Listview with findviewById, I did all this and is working now. Thanks anyway.

1

You can create a constructor that takes the context.

Declare within your Getbusiness class the mContext property as below:

private Context mContext;

And then create a constructor by passing Context.

public GetEmpresas(Context ctx){
    mContext = ctx;
}

Now in the call snippet you passed this, pass the mContext property.

adapter = new AdapterEmpresas(empresas, mContext);

Edit: in your Activity...

GetEmpresas getEmpresasAsync = new GetEmpresas(this);
getEmpresasAsync.execute();
  • Man, all this inside my getEmpresa? I’m making his call by Oncreate. Like this: new Getempresas(). execute(); Ai gives error if I pass nothing, pq it tries to pass to the constructor.

  • So, in fact, it’s all inside the getEmpresa. It extends from the Asynctask.

  • Yes, the only stretch out would be your call to Asynctask, where you need to instantiate it and then you pass the context of your Activity to the constructor created.

  • Calling it that way, you will call it the following: new Getempresas(this). execute(); Assuming you are calling from an Activity.

  • Made a mistake too... I did as you said, and the mistake comes at the same moment yet.

  • Post the Logcat error, please.

  • 01-30 18:21:25.058: E/androidruntime(8276): FATAL EXCEPTION: Asynctask #1 01-30 18:21:25.058: E/Androidruntime(8276): java.lang.Runtimeexception: An error occured while executing doInBackground() 01-30 18:21:25.058: E/Androidruntime(8276): at android.os.Asynctask$3.done(Asynctask.java:299) 01-30 18:21:25.058: E/Androidruntime(8276): at java.util.current.FutureTask.fi

  • The full log helps more. The line 299 would be that Adapter = new Adaptercompanies(companies, mContext)?

  • No, it does not arrive on line 299. I posted in the question the error.

  • Taking a look at your class I noticed that you are returning null but your Ackground method does not return anything (void). Try debugging and check that the mContext passed to Adapter is null. I believe it is not, and here we have another problem in the code. doInBackground is running fully, the problem may be onPostExecute().

  • So, but if I take off the Return, it’s a mistake. I also saw in the logcat that it’s an error on line 137, which is this: listview.setAdapter(Adapter);

  • Check that your Adapter is null. If you remove Return, what error happens? It makes no sense, your method is void, expect no return, theoretically should not even compile. " Void methods cannot Return a value".

  • No, my Adapter is not null, this with.nome.Adapter.Adaptercompanies@40e0ae30

  • Thanks for the help @lucasb.Let’s say the method as you said was right to pass the context, but it would need to be in Postexecute. Thank you!!

Show 10 more comments

Browser other questions tagged

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