Skip to main content

Loading on a Thread

Lesson 12 from: Building a Twitter App

Tony Hillerson

Loading on a Thread

Lesson 12 from: Building a Twitter App

Tony Hillerson

buy this class

$00

$00
Sale Ends Soon!

starting under

$13/month*

Unlock this classplus 2200+ more >

Lesson Info

12. Loading on a Thread

Lesson Info

Loading on a Thread

so step for loading on a thread. That's kind of like a living on a prayer, but quite all right. Enough comedy. The user should trust our application. Um, and they're not gonna trust her application if we're doing something that, um, completely freezes the view. So what we want to do is load anything's and and network operations are long running applications. No matter what you. No matter how quickly they return their applications, that will freeze. Um, they are operations that will freeze the view, and they should be. They should be done on a different thread. They should be done somewhere different than the u I thread. So let me talk a little bit more about what that means and what we're gonna do. What we're gonna do to show the user that something is happening is have a couple different progress views show up. One of them is this this dialogue here, which will show up when we're loading the home timeline for the first time. Because, as you've seen, we don't show any progress right no...

w, but we're also going to show some some progress in the header of the application and then in each of the the header and footer views of the of the list whenever we do something with those views. So let's talk a little bit about units of work and what they mean on the U I thread. So let's moving as as time goes on in your application, like your application might not be getting do anything, so there's kind of idle. So let's say for like, little chunks of time, your application is idle, and each one of these boxes, um, shows that something's happened, your applications, your applications, sitting there, idle, not doing anything. And then some easier interaction happens. And because of the user interaction, the application redraws the view. And maybe there's some or user interaction. It clicks on a button or something like that, and then some short operation will reduce some calculation or something like that. Um, it doesn't. There's no problem. It just fits into the normal flow of things. Then the U I re draws and then it's idle again. This is kind of like the normal set of operations that your application does, but let's say instead of a short operation something that could be accomplished pretty quickly, we have something long. So let's say there's some user interaction like the user kicks off a load like, for instance, loading the loading, more tweets. Then the application redraws. And then the application starts this long running apple operation where it goes and loads the new tweets. It can't do any redrawing during that part, so it can't respond to user interaction. They can't show progress. It can't scroll the list. It can't do anything besides that network operation because it's blocking that thread. The U. S. The U I threat is what we call it. And then, um after that operations done that it can continue redrawing and and finally catches up to where the user wanted to be. But that's the user experience problem right there. It doesn't. It doesn't allow the user to see that something is going on. And they're like, Wait, why? Why is my application frozen? Okay, now, finally, it's back. So what you want to do instead is, um, run that application. I'm sorry. Run that operation in another thread threads airways that modern programming ranges, languages allow you to do concurrent units of work, so have some work happening alongside some other work that she wants some important work, and, ah, that's handled at a really low level. However, that's handled. But all you need to worry about as a programmer is that you can put long running up operations on another thread, and that will run alongside whatever important work the U I is doing so that you can let the U I continue to update. And the user doesn't think the application just froze. So what you want to do instead of what we did before, where we have a long running operation that we just slam in the middle of the U I thread, you kick off that long running operation on another thread, and then you're able to show progress or somehow respond to user interaction during that long running operation. And then when it returns, we handle the results. And then we continue on as if, um is normal. So let's look at how we do that in our application. So I'm going to open up Step four loading with the thread, and everything that happens is going to be happening on the status list activity. So, first differences online. 25. You can see that I've created a handler class. And if you remember from the beginning of class, I talked about the handler being the class that android uses to communicate, Um, like, sort of the jumping off period and and the re entering period when those when those threads air kicked off in the background and then when they complete the handler handler, is what response or helps us notify the main thread that that work is done. Um, Then we're also going to create online 31 a progress dialogue. The last is to show that something's happening. And then we're also going to do something online. 39 which is new. We're going to call a method that is on activity. Ah, called request window feature. And we have to call this before we set the content view. And we're going to request that we show, um, a window feature called a feature indeterminant progress. And I'm sure you've all seen this. I'll show you in action in just a second, but you've all seen a little like Spinney progress indicator up on the title of any of your android applications. That's what we're That's what we're setting up here. I'll show you how that works in just a second. But this is That's tells Android that we want to use one of those guys, um, progress indicator upon the title bar. So now what we're going to do and everything is pretty much the same on resume. We're going to say load timeline if not loaded. But now, in load timeline, if not loaded, things are a little different. If our are listed after is no, um, this is how we're gonna load the home timeline instead of what we're doing before First of all progress dialogue, which is the switch back to this view here. This this guy, this thing that says we're loading tweets with a spinner there. That's a progress dialogue. And it's pretty easy to construct here. If you say projects, dialogue that show it needs to take a context, and so we could pass along the status list activity. This is a context, and then it needs a title, and it needs some some description texts, and so we can load those off of the resource is a string resource, and we just have loading title in loading home timeline description. Um, that basically puts this text in the place loading tweets and loading your home timeline. So we're gonna kick that progress dialogue off right there. But and here's the next interesting part. We're going to create a new thread on anonymous thread here and then implement Run. This is all kind of standard thread programming stuff or implement run, which is what is called when the thread starts inside. The threat is where we're gonna call load home timeline and load Home timeline, as you remember, loads everything from Twitter. Um And then when it's done, we use the handler to post back to the U I thread that were done. And what you do with the Post is you post you pass along a run a ble. So basically what the handler does is it's kind of a queue of things. And when we and each one of those, each one of those things in the queue is a run, a ble task, which is just rentable, is just a job, a interface, the basic job interface that that specifies a method called Run. So when you say handler dot post and you pass a run a ball, it's just gonna call run on that guy and that guy is able to actually exist back on the u I thread. So that's how we tell the you I thread that everything is done. So again, this thread when we call start online run is called on the thread. The low home timeline is loaded. And then we post a run a ble to the handler which tells, Are you? I thread that everything is done, and in this case, we're gonna call. We're gonna use this run noble um, finished loading list tasks. Let's go look at that guy. I hover over him and hit F three and down at the bottom of the file. You can see that I've defined this run Herbal, um, is anonymous run herbal. I implemented it right here. It has a method called run, and basically, we say finished loading list inside of there. So let's go Look at that. Hit F three finished loading list again. This this can exist back on the EU. I thread so it can have access to all of this stuff that we've defined here. I do pretty much everything that I used to do. In fact, maybe it be would be useful here to show side by side. Step three. Um, status list activity. Um, load home timeline, so I'm going to steps. Three steps. Three Status list activity load. Home timeline online 58. Do you line 67. I'm gonna put it up side by side with, um lied. 95 of step fours. Status list activity, which is finished loading list. So in the old version, which is on the right, I load everything from Twitter. I said the adapter set load more views, um, set the list adapter to the after I created and then set the selection toe one. And then in finish loading list, which is again called by that running bull that we post back through the handler. When the threat is done of loading all the tweets. I'm pretty much doing the same things, except for setting up the adapter. I just passing the adapter to the list and then set the listsview too. Show the first the second, because it zero based tweet is this a czar item as the selection. And then I dismiss the progress dialogue. So that makes the progress go away. So let me go through that just one more time in load timeline if not loaded, we close this guy online. 60 created thread. When that threat has run, it loads the home timeline. And then when that part is done, because this, this is, is all sequential here. When Load Home Timeline has done that, I post that run noble back through the handler. It's run is called, Um, let's go look at that And that calls finish loading list, which finalizes all that stuff, puts the adapter in the place, shuts off the progress dialogue and, uh, that allows our application to be responsive. So let's show that and then I'll then I'll kind of walk through the through the code where I load thanks to the headers. Instead, I think I need to go over here two week to step for and say Brunnis Android application. Look back at the emulator in this time when the application starts up. When we start loading the home timeline, we should see some progress instead of just a blank screen for a little while. So there we go, the thread kicked off. The progress indicator starts, and pretty soon the thread will end and the thread will post back through the handler that everything is done. And then this this method, um that the run a ble that we posted through the handler finished loading list will call. We'll get called and then will set the load. More of you set up the headers, um, stabilised adapters at the selection toe one and dismissed the progress dialogue so that all happened in the interface remained responsive instead of showing just a blank screen that the user could interact with, So it's a much better user experience. Um, let me go through the whole process of flicking a header. Um, I think this should load pretty quickly, so I'm not sure how quick will be able to see everything happen. But this time, when I click load, newer tweets will see progress appear. Do that again. You see progress appear in the top left of the header each time. So that's now the user knows something's happening and then remember, I I I asked, asked Android for the indeterminant here appearing on create and status list activity on create, I say request window feature feature indeterminate progress that allows us to show when I click the header up here in the top rate. Some progress as well. Right there. Okay, so let's look at the code that does that. So, again, that is in, um, on list item, click online. 85 of status list activity. Unlisted him. Click. Now, I say interview showed progress and that progress will continue to show because when I say load newer tweets by hover over here and head off three down on line I guess I'm being redundant here in the code. I need to clean that up. But when I say load your tweets, I say head review show progress and then set the progress bar Indeterminate visibility to true. That's a method on activity which will show a search back to the emulator that shows this progress indicator up in the top right of the title bar. Then much the same as I did with the, uh, with the initial tweet Lodi, sepa, new thread, implement, run. And then I call the get home timeline, um, with the paging, which, um, in the other case, I did outside of the thread when and the other case in the previous code, um, which I think I just did. Inside of load your tweets, Aiken second, set these up side by side to show kind of a little bit of progress here. So this is status list activity from step three when I go down to load newer tweets. Um, on I stack these up side by side, this is the older one on the right. I say, uh, beside progress. For some reason, I said, hi progress there. But, um, instead of loading things in a thread, I just do things right here on the main main thread. Get the home timeline, append a newer statuses and set the selection toe one. Where is here in the newer code online, One of five created thread. And then inside the threads run. I call, get home timeline here and then create. Okay, so then let me close. Close this up because again to inform the the U. S. Thread that were done. Um, what I'm have to somehow post back through the handler a rentable. So I'm doing here is a slightly different strategy. I'm creating a new run, a ble that I define, um, lower on down the the chain. I'm calling it a load newer result run noble. And then I post that back to the handler. And so let's look at that really quickly. And then we'll look at lowering the older result. Rentable. So hit F three on here, and it shows on line 1 64 Here's this run a bill that I define here. So it's a private class implements rideable. It has a an instance Variable, which holds the new status, is the new tweets that got loaded during that load. New operation, Um, and then in the constructor, I just passing their statuses and let them hold them around because this is the only way I can send data back. I have to have something to hold the data as it as it Ah, as it gets posted through the rubble because I can't years. Here's the rule. I can't do any air interaction on the activity from the from the outside thread that causes an exception because it doesn't want you implementing. It doesn't want you changing things on the main thread from other threats because that you can get some rule. You could get into some Harry concurrency problems there. So LD operations that you that you do as well as a result of the threat, need to be done by the handler inside of a run a ball. So, um, that's what we're doing here. We create a run a ball and this is the guy that can actually passing some data by calling finished finish loading. Newer In this case on, I can kind of compare the reason I did load newer result as a rentable and load. Older result is a rentable was because I need to do different things. And so I call a different method for finish loading, older results or finished loading newer results. So school, Look at what I do there. Um, online 1 73 Finished loading results are finished loading. Newer is called by big load, newer rentable, and it's run method. Um, and when I finished loading newer, I pass on some statuses and again, just like before a pen newer statuses studio to the adapter Hide the progress on the head of you Shut off the title of our progress by calling sent par progress bar indeterminate visibility to false. And then I set the selection toe one in the case when I'm loading newer statuses. And then let's look it. Ah, finish. Oops! Not open resource open method. Finished loading older in this case online 43 When I hit the footer instead of the header that run Herbal will call finish loading older, which will just append older statuses to the adapter. Hide the progress on the foot Orville, footer view and then shut off the indeterminate visibility loader up in the title. And I don't need to do anything else there. So, um, that's what's happening here when I go back to the emulator and this will be a longer running one when I hit the footer to load older tweets, um, show progress, shoot progress up in the title bar. And then once the once that Ted threat is done, I post the run a ble through the through the handler. And it will, um, hold the list of status is that I got back from Twitter and then posts and then ah, actually call a method on the status list activity, which is on the main thread with those new statuses, and I can put those in the place and shut off. The showing progresses. So there I am, looming loading smolder tweets. The loader older treats come into place. All the progress is shut off and everything works like the user expects. And the APP is responsive, which is the main point. So units of work again, short operations are fine long running operations. Which network operations, no matter how quickly, need Teoh be classified as need to go in their own thread. And they need to run concurrently with EU I thread and then, in summary, a handler is what makes it possible to coordinate the activity between your background worker threads in the main thread. Again, the rule is you can't do any at interaction with um, and the main activity that you run threads off of, except through a run a ball that is posted through a handler. So I assume there will be some questions after that. Yes, any questions, and we'll take one from the audience in person. Audience here first, Is there any type of limitation to the number of the Reds that you can run from a nap? So, yeah, that threads take up memory. They also it's not like they're magically being done on some other processors somewhere else. They're all are running through the single processor that the application has there just some time sharing or whatever that's going on down there deep in the innards. So even if even if you're putting things off on another thread and there's a lot of those things that's still going to slow down the application and cause it to be unresponsive, in fact the whole whole device to be unresponsive because that processing power is getting taken up. So, yeah, there's a limit. I'm not sure what the limit is, but luckily, next class we're going to talk about away to make it easy to dio, um, what's called a thread pool, which is where you limit the number of threads that are running in at any one time and then recycle those threads, as as new units of work coming to be done, or stage up units of work to be done at a future point in time. We don't have to deal hardly any work to get that to happen, And that will be showing that in the next class there is an android class cold, a sink task, which does all that work for us. All right. Um, I have a couple questions about threads. Also, um, one is How do you protect against loading new and old at the same time? Or do you not have to worry about it since it's on the u I thread? Um, yes. So you'll notice that I had a I think what this person notices well, is that when I'm loading the initial tweets, um, you are you're you as a user, presented with a dialogue boxer. That's kind of motile. So you can't do any interaction with the APP. But when I load new or old tweets, I'm not actually stopping the app from working, so I don't know what would happen. I think everything will just happen. Fine. We could try really quick. I don't know if things would be, um, well, especially since there's so money. So many pieces of information s so many items in the list. I don't know if I could stroll down fast enough to try to hit him both. Well, the other ones running, but I think everything should happen, OK, I don't know why it wouldn't. Each one of those running running Bols will be posted back. Yeah, I was wondering if you synchronize the stat? I very able to prevent them both trying to write to it. Um, well, the adapter is dealing with that with the actual list. And so you say penned older and a pen newer at the same time, it should be putting him in the right place. Um, because no matter what, after those stretcher done, something is going to be happening in a synchronous fashion with the adapter. So I don't think that would cause any trouble. But, ah, you could try to prove it around, prove me wrong, See if you can hit him both at the same time and see if there's a problem. But I don't I don't think from a code point of view that there's any problem. And then somebody asked if Twitter for Jay is thread safe. Ah, good question. I don't know all directly to the the, uh the ah documentation that twitter for Jadot orig. All right. And then we had quite a few people wondering about the pros and cons of threads versus using asynchronous a sink task. Well, get if you already know that a sink task than use a sink task. I think the pros and cons. Er, um, facing task Will, will, I think everything. Everything on the falls on the side of a sink task. I would always use a sink task. I just like that way of programming. Better for everybody else who doesn't know what I'm talking about. We're gonna be going over that in the next class, So if you already do and you're already building an app, go ahead and use a sink task. It's pretty much, um it's better in a lot of different ways. All right? We had a couple of people who asked about the handler. One person wanted to know. I wanted to wanted you to quickly review how the thread gets the reference to the handler. And then another person wanted to know if the handler the threads that are queued, have the right to change whatever data they want in the main thread, Um, the threads don't but the run a bles do when they come back. I mean, if there's if there's anything like, if we were having problem problems with different calls returning a different times and modifying the status list adapter, we could we could synchronize something in there although who knows that Maybe synchronized up the chain. I don't know. The rebels are the ones that can change the data. Ah. What was the other question? How they got how the threads got access to the handler. Um, well, the threads since it's, um actually, I'm not quite sure of the any sort of pedantic rules about these things. But the thread since it's created here inside the status list activity has a reference to those variables so it can use the handler reference that's already on the activity, which we set up here online. 25. Okay. All right. Um, and then Sarah has a question from go to webinar. Yeah, from Jim and Goto Webinar. He asks, Do all of the new Java concurrency classes work on Android? Um, I don't know. What what new concurrency classes. Maybe I'm not up to date with what's new in Java. Um, we'll see if Jim clarifies that. Yes. The only ones I know about are like thread, thread, pool, um, rentable. And those air thread pool is made is made use of by the a sink task that we've been talking about. So that's definitely usable. I think they're all usable the ones that I know about. And I don't know when there's any changes to the concurrency libraries. So sorry about that. So somebody asked. This is Ruth again. Hi. Ah, somebody ask. Maybe I missed it. Or did we? Do we deliberately, um, sorry, I have to get rid of the second threat or doesn't go away by itself. I think there's some confusion about when does the second thread complete? And when is it Gon? Do we have to manage any memory there? No, you don't have to worry about it. It will be taken care of when ever run. So start kicks it off, and then when run is complete, it's eligible for grab. I think it'll be eligible for garbage collection sometime around there, so you don't have to worry about that about that kind of stuff. Ah, one other class offered. I think it was Jim, but I just thought of is a future task. I think that that may actually be new. Future is used by a sink as well. So that's That's another concurrency class that gets used and is available in Android

RELATED ARTICLES

RELATED ARTICLES