-2

I am currently developing an app for an project in my university. This project consists of me benig able to handle synchronous and assynchronous http request to a web-service that i've built. I have to create a class or some code that can send http requests (easy enought done throught AsyncTask) and callback the responsed back to an activity.

I don't know how to do this, since the onPostExecute() method is a void method, which doesn't return anything, and I can't save the contents of the response in a public variable because it's in another class.

What I want to do is the following:

From activity:

MessageCentre centre = new MessageCentre();
centre.getMessages(1); 

The 1 is an Id attributed to this device that is logged into my app-server. The server then retrieves all the messages associated with this ID in a JSONArray format. I cast those JSONObjects into a Message class that i've built, and save all of those new objects as an static array inside the MessageCentre class instance.

From here on, I have to disply the messages to the user, but I can't do that because inside the getMessages(1) method i execute an AsyncTask, which generates a secondary thread in my application. So the code goes on as shown below, but the ArrayAdapter doesn't show the messages (because he renders the adapter, before the messages arrive from the app-server)

ArrayAdapter a = new ArrayAdapter(getApplicationContext(),R.id.item_layout, centre.getMessagesList());
listview.setAdapter(a);

I also don't want to set the adapter from the AsyncTask because I wish to make this in a "black-box" format, where the user can simply call the methods and "make it work" by recieving plain object arrays and then implement their own views on top of that.

I also can't simply tell the activity to wait a couple of seconds by doing Thread.sleep() because that crashes the app and shows the ANR error.

So there are some ways i can think of handling this:

1) a way to make the activity wait for sometime without the ANR

2)returning the data back to the activity someway that isnt the onPostExecute() method, in some kind of callback method

3)making it so that the adapter and listview can, in Runtime, update and create the itens (OnCreateView() method) to show the messages, after they have been set and rendered, when the messages actually arrive, a couple of seconds later, from the app-server.

I think number 3 is more probable, and also resembles more what a chat application does. I just don't know how to update the messages list in runtime.

Any help is appreciated guys, thanks a lot!

1 Answers1

3

you can create an interface to make a callback.

Example:

create a class AsyncTaskMessage:

public class AsyncTaskMessage extends AsyncTask<Void, Void, Void> {


    Context context;
    public OnMessageListener mListener;

    public interface OnMessageListener {
        void messageCallback(ArrayList<String> messageList); // you can change the parameter here. depends on what you want.
    }

    public AsyncTaskMessage(Context context) {
        this.context = context;
        mListener = (OnMessageListener) context;
    }

    @Override
    public void onPreExecute() {

    }

    @Override 
    protected void onPostExecute() {
        // your code goes here for the callback.
        // messageList - A list of messages.
        mListener.messageCallback(messageList);
    }
}

then your MessageCentre class:

public class MessageCentre {

    Context context;
    public void MessageCentre(Context context) {
        this.context = context;
    }

    public void getMessages(int id) {
        // You said your asyncTask goes here.
        AsyncTaskMessage async = new AsyncTaskMessage(context);
        async.execute();
    }
}

then your activity where the ArrayAdapter

// A class where your ArrrayAdapter.
public class MainActivity extends AppCompatActivity implements AsyncTaskMessage.OnMessageListener {

    //.. 

    public void displayMessage() {
        MessageCentre centre = new MessageCentre(this);
        centre.getMessages(1); 
    }

    @Override
    public void messageCallback(ArrayList<String> messageList) {
        Log.i("MainActivity", "Response: " + messageList.toString());
        ArrayAdapter a = new ArrayAdapter(getApplicationContext(),R.id.item_layout, messageList);
        listview.setAdapter(a);
    }
}
dotGitignore
  • 1,597
  • 2
  • 15
  • 34
  • I didn't understand from where the "messageList" variable should be coming from, I don't have it inside the AsyncTaskMessage class. Do I pass it from the MessageCentre class as a parameter when I instantiate the AsyncTaskMessage class? – Christian Wolf Alves Hess Oct 22 '17 at 01:36
  • Also, i'm getting a cast error at the line mListener = (OnMessageListener) context; inside the AsyncTaskMessage constructor – Christian Wolf Alves Hess Oct 22 '17 at 01:47
  • The `messageList` is the `centre.getMessagesList()` – dotGitignore Oct 22 '17 at 01:47
  • got it. but i don't understand the CastException: Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.chris.testetcc1.AsyncTaskMessage$OnMessageListener – Christian Wolf Alves Hess Oct 22 '17 at 01:53
  • I edited my answer, change your `public void AsyncTaskMessage` to `public AsyncTaskMessage` – dotGitignore Oct 22 '17 at 01:56
  • I had done that, I noticed that was supposed to be the constructor, but the error is actually when trying to cast the context as an OnMessageListener, inside the constructor. In this line: mListener = (OnMessageListener) context it throws: Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.chris.testetcc1.AsyncTaskMessage$OnMessageListen‌​er – Christian Wolf Alves Hess Oct 22 '17 at 01:58
  • where did you call the AsyncTaskMessage? – dotGitignore Oct 22 '17 at 01:59
  • I instantiate from the activity the MessageCentre, call the getMessages method and from that method instantiate and then call the AsyncTaskMessage class – Christian Wolf Alves Hess Oct 22 '17 at 02:00
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157209/discussion-between-jerrol-and-christian-w-a-hess). – dotGitignore Oct 22 '17 at 02:01