0

So from what I've read, Android's AsyncTask is a great way to asynchronously load information from the Internet. However, I don't want to block up the UI and prevent the user from interacting with it.

A basic description of my problem.

Currently, I am using websockets in order to send/receive data from a web server. On events like a user entering the room, a song being added or removed from a playlist, a song being upvoted or downvoted, or one song ending and another one beginning, the UI must be updated in order to indicate changes. But ideally, these changes will be occurring very frequently, which means that constantly blocking the UI in order to refresh it would be cumbersome and annoying.

How would I update my UI without interrupting the user in their activities? Would AsyncTask suffice?

Quontas
  • 400
  • 1
  • 3
  • 19
  • AsyncTask is not the only way. There are also Handlers and Loopers, you can read about that in [Communicating with the UI Thread](https://developer.android.com/training/multiple-threads/communicate-ui.html) followed by Keeping your App Responsive. – OneCricketeer Jun 10 '16 at 04:04

2 Answers2

1

The asyncTask does not block the UI. It runs on a separate thread to send / receive the data from the web, and then returns the results. When you receive the results back, you can update the UI as you choose.

Your UI will not be stopped while the asyncTask is performing its background work. You can try it out by by building one in your activity and simply sleeping for some amount of time (let's say five seconds) in the doInBackground method. You will see that your UI is still functional during that five seconds.

Edit: You can do just about anything with the results you get back and it won't interrupt your UI either. If that's not the case, you'll probably want to look at optimizing what you are doing with your in memory objects. Anything not stored in memory should probably be retrieved or written to disk, database, or internet endpoint with an AsyncTask. As the commenter points out above, this is not the only way to use other threads, but it's easy and will probably work if you're making a reasonable web request and expect users to have a decent connection. You will just want to make sure you have timeouts and exceptions covered so that your app doesn't crash if the task takes longer than expected.

public class LoadCommentList extends AsyncTask<Integer, Integer, List<Comment>> {
    private String commentSubject;

    public LoadCommentList(commentSubject){
        this.commentSubject = commentSubject;
    }

    // Do the long-running work in here
    protected List<Comment> doInBackground(Integer... params) {
        // the data producer is a class I have to handle web calls
        DataProducer dp = DataProducer.getInstance();

        // here, the getComments method makes the http call to get comments
        List<Comment> comments = dp.getComments(commentSubject);

        return comments;
    }

    // This is called each time you call publishProgress()
    protected void onProgressUpdate(Integer... progress) {
      // setProgressPercent(progress[0]);
    }

    // This is called when doInBackground() is finished
    protected void onPostExecute(List<Comment> comments) {
        // calls a method in the activity to update the ui
        updateUI(comments);
    }
}

There are cleaner examples actually using the Integer... params for example, but this is just something I had handy as an example.

  • So if I'm using socket.io, where would I go about setting up the socket connection, in the Activity or the AsyncTask? – Quontas Jun 10 '16 at 04:44
  • Use your AsyncTask to do the long running work. I've updated the answer to show an example. Set up your socket connection in the AsyncTask, but you can use other classes or methods to actually do that, in order to keep your code clean and readable. – Michael Payne Jun 10 '16 at 16:30
  • So does the AsyncTask only run once? If it only runs once is there a way of having an AsyncTask run constantly? – Quontas Jun 10 '16 at 17:57
  • AsyncTask will run however often you ask it to. If you want it to run repeatedly, such as on a time interval, you will want to set up something else, like a Service and handler... see http://stackoverflow.com/questions/13954611/android-when-should-i-use-a-handler-and-when-should-i-use-a-thread for more information, that topic is probably outside the scope of your original question... – Michael Payne Jun 10 '16 at 18:54
0

I don't know where you read that but asyn task are worst way to make web service call this days. You should use Retrofit for service call, it is 8 Times faster and handle UI update smoothly. Read more about this here :-

http://googleweblight.com/?lite_url=http://instructure.github.io/blog/2013/12/09/volley-vs-retrofit&ei=qR4bQU5c&lc=en-IN&s=1&m=260&host=www.google.co.in&ts=1465531978&sig=APY536z0v15lfX3G6KY4nls4wf1kzttJdA

Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154