1 00:00:00,290 --> 00:00:03,330 Now that we know how all of these pieces fit together. 2 00:00:03,330 --> 00:00:05,220 It's time for us to get our hands dirty and 3 00:00:05,220 --> 00:00:09,700 turn this boring self serve breed of truck into something a lot more robust. 4 00:00:10,950 --> 00:00:14,353 Let's start by making a new class for our handler and 5 00:00:14,353 --> 00:00:22,307 let's call it DownloadHandler And 6 00:00:22,307 --> 00:00:25,620 let's make it extend the android.os.Handler class. 7 00:00:29,660 --> 00:00:32,512 Then, back in our DownloadThread, 8 00:00:32,512 --> 00:00:37,390 let's declare a public DownloadHandler field named M handler 9 00:00:45,230 --> 00:00:47,080 mHandler. 10 00:00:47,080 --> 00:00:51,527 Then, let's delete everything in the run method and 11 00:00:51,527 --> 00:00:59,470 type Looper.prepare, 12 00:00:59,470 --> 00:01:03,840 this creates a looper for a thread and also creates the message queue. 13 00:01:05,380 --> 00:01:10,419 Next, let's initialize our handler by typing mHandler 14 00:01:10,419 --> 00:01:16,130 equals new DownloadHandler. 15 00:01:16,130 --> 00:01:20,811 By default, a handler is associated with the looper for the current thread. 16 00:01:20,811 --> 00:01:26,186 Since we're in the run method of our DownloadThread, the current thread 17 00:01:26,186 --> 00:01:31,230 will be our DownloadThread, instead of the main thread, perfect! 18 00:01:31,230 --> 00:01:36,656 And once our handler is created, the last step is to call 19 00:01:36,656 --> 00:01:42,090 Looper.loop to start looping over the message queue. 20 00:01:43,560 --> 00:01:49,330 Back in main activity, let's take a look at our download buttons on click method. 21 00:01:50,660 --> 00:01:54,780 When we click this button, we want to start downloading our playlist 22 00:01:54,780 --> 00:01:58,910 one song at a time, like ordering a bunch of burritos at once. 23 00:02:00,060 --> 00:02:04,715 So inside this method, we'll be sending messages, or runnables, to our handler for 24 00:02:04,715 --> 00:02:05,491 processing. 25 00:02:05,491 --> 00:02:08,910 Let's add a comment at the bottom of this method, to say. 26 00:02:12,340 --> 00:02:17,126 Send Messages or Runnables 27 00:02:17,126 --> 00:02:22,130 to Handler for processing. 28 00:02:22,130 --> 00:02:26,430 But before we implement this, there's actually two problems we should fix. 29 00:02:27,600 --> 00:02:31,320 The first problem is that we're still creating a new thread 30 00:02:31,320 --> 00:02:32,650 each time we click the button. 31 00:02:33,880 --> 00:02:39,770 Since we're trying to use just one thread with a message queue, this is no good. 32 00:02:39,770 --> 00:02:43,760 The second, and much bigger issue, is that if we write this code, 33 00:02:43,760 --> 00:02:46,160 it will cause a null pointer exception. 34 00:02:47,160 --> 00:02:50,590 Here we are in the main thread, inside the onclick method. 35 00:02:51,610 --> 00:02:55,950 We create a new thread, give it a name, start it and 36 00:02:55,950 --> 00:02:58,950 then we start sending messages or runnables to the handler. 37 00:03:00,310 --> 00:03:02,950 But look over here at our DownloadThread, 38 00:03:02,950 --> 00:03:07,130 it's still working on getting set up and hasn't initialized the handler yet. 39 00:03:08,670 --> 00:03:13,420 When we call thread start, our download threads run method and 40 00:03:13,420 --> 00:03:16,020 will start executing almost immediately. 41 00:03:17,060 --> 00:03:23,180 But as fast as that is, the main thread moves on to the next line even faster. 42 00:03:24,220 --> 00:03:28,090 So when we try to communicate with our download threads handler, 43 00:03:28,090 --> 00:03:32,240 it won't have been created yet and our app will crash with a null pointer exception. 44 00:03:33,550 --> 00:03:37,230 We'll need to start our thread before we get to the OnClick method. 45 00:03:38,630 --> 00:03:42,330 Let's cut out our thread code and paste it above in the on create method. 46 00:03:49,720 --> 00:03:52,860 Awesome! Back in the on click method let's do some 47 00:03:52,860 --> 00:03:53,960 more planning. 48 00:03:55,000 --> 00:03:59,490 We could create a new runnable for each song we want to download. 49 00:03:59,490 --> 00:04:03,700 But then we need to specify not only which song to download, but 50 00:04:03,700 --> 00:04:08,640 also how to download it like bringing your own recipe to the burrito truck. 51 00:04:09,720 --> 00:04:13,650 Wouldn't it be better if we could just give our handler a bunch of song titles 52 00:04:13,650 --> 00:04:17,190 and we could trust it to handle them all by itself? 53 00:04:17,190 --> 00:04:19,190 Yes, yes it would. 54 00:04:19,190 --> 00:04:22,451 Let's start by changing our comment to no longer include runnables. 55 00:04:25,410 --> 00:04:29,151 Then, let's add a for each loop to loop through the playlist. 56 00:04:32,170 --> 00:04:37,217 For (String song : and Playlist.songs and 57 00:04:37,217 --> 00:04:40,536 brackets, inside the loop, 58 00:04:40,536 --> 00:04:46,531 let's create a new message variable named message. 59 00:04:52,281 --> 00:04:57,174 And let set it equal to Message.obtain. 60 00:04:58,520 --> 00:05:01,750 We could create a new message object, but 61 00:05:01,750 --> 00:05:05,670 since messages are used all over the operating system, 62 00:05:05,670 --> 00:05:09,500 Android keeps a pool of message objects available for us to use. 63 00:05:10,500 --> 00:05:13,610 This way, Android doesn't need to keep creating and 64 00:05:13,610 --> 00:05:15,689 deleting a bunch of message objects. 65 00:05:16,860 --> 00:05:22,080 Once a message has been handled, it just goes back to the pool to be re-used. 66 00:05:22,080 --> 00:05:27,701 Now that we've got our message, on the next line, 67 00:05:27,701 --> 00:05:31,900 let's type message.obj = song;. 68 00:05:31,900 --> 00:05:39,421 The OBJ property of a message lets us add any type of object we want to our message. 69 00:05:39,421 --> 00:05:43,392 Since we want to tell our handler about a song to download, 70 00:05:43,392 --> 00:05:46,400 we'll attach the song name to our message. 71 00:05:47,440 --> 00:05:51,480 Lastly, we just need to send our message to our handler, so 72 00:05:51,480 --> 00:05:53,220 it can be added to the message queue. 73 00:05:54,400 --> 00:06:03,030 We can do this by typing thread.mHandler.sendMessage and 74 00:06:03,030 --> 00:06:04,100 passing in our message. 75 00:06:06,810 --> 00:06:10,660 And remember, that we should declare thread as final, so we can use it and 76 00:06:10,660 --> 00:06:12,450 our onclick method. 77 00:06:12,450 --> 00:06:16,340 This might have happened automatically, almost done. 78 00:06:16,340 --> 00:06:18,070 The last thing we need to do, 79 00:06:18,070 --> 00:06:21,920 is tell our handler what it should do, when it gets a message. 80 00:06:23,170 --> 00:06:27,870 We can do this but over riding our handlers, handle message method. 81 00:06:29,140 --> 00:06:32,522 Let's go to the download handler class, and 82 00:06:32,522 --> 00:06:35,910 hit Ctrl+O to bring up the over ride dialog. 83 00:06:35,910 --> 00:06:40,011 Then let's choose to override the handleMessage method. 84 00:06:40,011 --> 00:06:45,737 And once we've done that, all we need to do is call our download 85 00:06:45,737 --> 00:06:50,830 song method with the song name supplied by our message. 86 00:06:51,880 --> 00:06:59,380 Let's cut the download song method out of our DownloadThread and 87 00:06:59,380 --> 00:07:01,205 paste it into our DownloadHandler. 88 00:07:06,130 --> 00:07:11,428 Then let's quickly update the tag constant Alt+Enter, 89 00:07:11,428 --> 00:07:15,755 downloadhandler.class.get simple name and 90 00:07:15,755 --> 00:07:19,877 instead of calling super.handlemessage. 91 00:07:19,877 --> 00:07:23,982 Let's call downloadSong, and 92 00:07:23,982 --> 00:07:29,304 pass in the song attached to our message, 93 00:07:29,304 --> 00:07:35,550 msg.obj.toString, to turn it into a string. 94 00:07:37,210 --> 00:07:45,351 Lastly, let's update the download song method to take in a song, String song. 95 00:07:45,351 --> 00:07:48,671 And let's change the log message to include the song name. 96 00:07:55,820 --> 00:07:56,640 Great work! 97 00:07:56,640 --> 00:08:01,630 I know this stuff seems complicated, but you're doing a fantastic job. 98 00:08:01,630 --> 00:08:05,700 And the next video, will test our app and learn about some potential improvements