1
00:00:00,920 --> 00:00:05,689
And this video, you are going to learn how to use routines and why do we need quarantines?

2
00:00:05,720 --> 00:00:11,660
Well, in Android, some operations or tasks take a longer time to complete, and these tasks blocked

3
00:00:11,660 --> 00:00:17,060
the user interface and until they are completed, the user interface is not interactive with so the

4
00:00:17,060 --> 00:00:23,000
user cannot interact with it, or at least with parts of the application and which will make the user

5
00:00:23,000 --> 00:00:25,370
idle and will make him bored and so forth.

6
00:00:25,370 --> 00:00:26,540
So it's not a good process.

7
00:00:26,660 --> 00:00:27,980
It's not a good approach, basically.

8
00:00:28,400 --> 00:00:35,750
So to avoid this, Android's UI system was built to only accept delays of maximum five seconds.

9
00:00:35,760 --> 00:00:36,800
So let's look at that.

10
00:00:37,010 --> 00:00:42,470
So have this little application here, and once I click on this button, there will be a very long lasting

11
00:00:42,470 --> 00:00:43,380
task running.

12
00:00:43,430 --> 00:00:44,750
And let's just run it.

13
00:00:44,750 --> 00:00:46,760
You see, the UI is frozen.

14
00:00:46,760 --> 00:00:48,260
I cannot click on anything.

15
00:00:48,560 --> 00:00:49,940
The app is frozen basically.

16
00:00:50,240 --> 00:00:54,650
And after five seconds, Android decides, Hey, this is a bad application.

17
00:00:55,280 --> 00:00:56,210
It's not responding.

18
00:00:56,210 --> 00:00:58,010
Let's close it, even though you see it's done.

19
00:00:58,250 --> 00:01:03,800
So even though the application did finish in the meantime, while this pop up appears so I can close

20
00:01:03,800 --> 00:01:06,590
the app or I can wait and then go back to the app and it works right?

21
00:01:06,770 --> 00:01:11,690
Otherwise, the user would just close it because he believes the app is bad and he's going to uninstall

22
00:01:11,690 --> 00:01:13,280
it, or she's going to uninstall it.

23
00:01:13,730 --> 00:01:16,400
So what is going on in this application that I've built here?

24
00:01:16,700 --> 00:01:22,370
So I've just this button, and once I click on it, it just runs this full loop, which runs 100000

25
00:01:22,370 --> 00:01:24,650
times and it only adds a log entry.

26
00:01:24,650 --> 00:01:25,550
Nothing too fancy.

27
00:01:25,760 --> 00:01:28,280
And once it's done, it's going to write this toast.

28
00:01:28,610 --> 00:01:33,680
But I'm doing that in the on create, and I'm doing that on the main threats or on the user interface

29
00:01:33,680 --> 00:01:36,650
thread, which really is not good.

30
00:01:37,010 --> 00:01:43,820
And we can avoid that by using code routines, which will basically push tasks that last longer into

31
00:01:43,820 --> 00:01:49,700
the background onto a different thread so that the UI thread will not be blocked and can still run and

32
00:01:49,700 --> 00:01:53,960
will still run flawlessly and fluidly so that the user can properly use it.

33
00:01:54,680 --> 00:02:01,020
So let's look at what called routines are in a little presentation and see the advantages and then build

34
00:02:01,020 --> 00:02:02,310
the little application around it.

35
00:02:03,360 --> 00:02:07,820
So let's look at correlations and those scopes in the little more details.

36
00:02:08,030 --> 00:02:10,940
So to summarize the features of code routines.

37
00:02:11,300 --> 00:02:12,830
First of all, they are lightweight.

38
00:02:13,100 --> 00:02:18,740
This means that you can run many core routines on a single thread due to the support of suspension.

39
00:02:19,460 --> 00:02:21,380
Then you have fewer memory leaks.

40
00:02:21,590 --> 00:02:28,910
By running a routine and a specific scope, you ensure that they do not leak as it terminates at the

41
00:02:28,910 --> 00:02:30,080
end of its scope.

42
00:02:30,800 --> 00:02:33,140
Then you have built in cancellation support.

43
00:02:33,470 --> 00:02:40,970
So the launch option returns a job which can be used to cancel the running call routine, and it is

44
00:02:41,180 --> 00:02:42,560
integrated into jetpack.

45
00:02:42,740 --> 00:02:49,520
So many jetpack libraries include support for Cortines, for example, room and the work manager.

46
00:02:49,730 --> 00:02:57,350
So basically, if you want to develop for Android Wear, then 2021 and later does is definitely going

47
00:02:57,350 --> 00:02:58,190
to be the way to go.

48
00:02:58,580 --> 00:03:01,310
OK, so then let's look at courtin scopes.

49
00:03:01,320 --> 00:03:06,050
So there are built in scopes you can use to launch a Cortines to finally execute this function.

50
00:03:06,200 --> 00:03:12,070
However, we need to tackle routine school and Cortines follow the principle of stent structured concurrency,

51
00:03:12,080 --> 00:03:17,000
as I said, which means that news code genes can only be launched in a specific code routine scope.

52
00:03:17,390 --> 00:03:22,220
So if you create a scope and don't clear it at the end, you can run into memory leaks and you want

53
00:03:22,220 --> 00:03:23,000
to avoid that.

54
00:03:23,450 --> 00:03:25,790
So let's look at the view model scope.

55
00:03:26,360 --> 00:03:31,820
It can be used to launch a call routine, and if you model class, it will automatically be cancelled

56
00:03:31,820 --> 00:03:33,770
once this view model is cleared.

57
00:03:35,000 --> 00:03:41,510
And then you have the lifecycle scope, which is used to launch Cortines in the activity or the fragment

58
00:03:41,990 --> 00:03:45,710
and is cancelled automatically when they are destroyed.

59
00:03:45,830 --> 00:03:51,860
So when the lifecycle is destroyed, which is good because then you are not running into memory leaks

60
00:03:52,790 --> 00:03:59,750
and you can as well create a custom scope, but it is important that you attach it to a job and clear

61
00:03:59,750 --> 00:04:04,100
it when the execution is done to create one in your activity.

62
00:04:04,460 --> 00:04:06,720
You create a global job variable.

63
00:04:07,130 --> 00:04:13,110
You create a call routine scope and attach a job to it and then you execute it.

64
00:04:13,130 --> 00:04:17,269
And finally, you cancel the job when the activity is destroyed.

65
00:04:17,730 --> 00:04:22,670
OK, so this is how you could potentially do it if you were to create your custom scope.

66
00:04:23,150 --> 00:04:25,580
OK, so now let's look at this.

67
00:04:25,940 --> 00:04:31,040
First of all, instead of running this code in here, I'm going to create a little function that I'm

68
00:04:31,040 --> 00:04:32,360
going to then adjust.

69
00:04:32,720 --> 00:04:33,950
So I have this private.

70
00:04:35,650 --> 00:04:36,110
Fun.

71
00:04:36,550 --> 00:04:37,240
Execute.

72
00:04:37,330 --> 00:04:41,500
I'm going to call it, and I'm going to pass a result into it, which will be of type string.

73
00:04:41,860 --> 00:04:43,860
And it's just going to execute my follow.

74
00:04:44,140 --> 00:04:50,800
So here I just want to run the execute method and I need to pass a string to it, which will be.

75
00:04:52,560 --> 00:04:54,720
For example, task.

76
00:04:57,650 --> 00:05:01,370
Here task executed successfully.

77
00:05:01,910 --> 00:05:02,280
All right.

78
00:05:02,300 --> 00:05:07,430
And this should, of course, be used here, so the results should be used as the text of the toast.

79
00:05:08,180 --> 00:05:13,190
OK, so once I execute it now, well, now basically the same thing would happen, only that the toast

80
00:05:13,190 --> 00:05:14,660
message would change slightly.

81
00:05:15,200 --> 00:05:16,610
So that's not really helping us.

82
00:05:16,910 --> 00:05:19,310
So how can we fix the problem that we have?

83
00:05:19,670 --> 00:05:26,600
Well, in order to fix it, we are going to use the suspend keyword here, suspend.

84
00:05:27,470 --> 00:05:30,410
But that will do is it will make it a core routine function.

85
00:05:30,710 --> 00:05:32,540
So a suspend function.

86
00:05:32,750 --> 00:05:34,790
Now, as you see here, it's unhappy.

87
00:05:34,790 --> 00:05:40,100
So you cannot just execute a suspend function on the main threat, which is really the whole idea here.

88
00:05:41,740 --> 00:05:47,590
So now to stop the function from blocking the UI, we need to add suspense in front of the function,

89
00:05:47,860 --> 00:05:51,640
but also we actually need to make sure that it runs on a different thread.

90
00:05:52,630 --> 00:05:59,680
So the suspend function is just part of the call routine class and it has to invoke another suspend

91
00:05:59,680 --> 00:06:00,130
function.

92
00:06:00,670 --> 00:06:03,430
So now let's modify our function block a little bit.

93
00:06:03,910 --> 00:06:12,190
Therefore, I'm using the with context here with context method and then passing a dispatcher thought,

94
00:06:12,490 --> 00:06:13,330
I o here.

95
00:06:13,630 --> 00:06:21,060
So neither of those is recognized, and that has to do with me not having the right implementation here.

96
00:06:21,070 --> 00:06:22,210
So when the right dependencies.

97
00:06:22,480 --> 00:06:26,320
So we need to add this dependency and it's the activity.

98
00:06:26,320 --> 00:06:32,710
Katie X and in my case, the version is one Dot 4.0 beta 01 and you could of course, use a different

99
00:06:32,710 --> 00:06:33,200
version.

100
00:06:33,460 --> 00:06:39,340
But either way, we need to use Caity X activity here and then we need to sync it.

101
00:06:40,030 --> 00:06:45,250
And once this is linked, we will find that we can now add the classes.

102
00:06:45,250 --> 00:06:47,800
And did I read it correctly?

103
00:06:47,830 --> 00:06:48,640
No, I did not.

104
00:06:49,060 --> 00:06:55,420
So with all enter, you see, now we have the two imports up here and we can now use it.

105
00:06:55,840 --> 00:06:59,680
So with context, it's not going to run a call routine.

106
00:07:00,220 --> 00:07:03,790
So now, of course, we need to put our code in there now.

107
00:07:04,420 --> 00:07:10,870
And at this point, backed security up here is still not happy, but at least our code here is more

108
00:07:10,870 --> 00:07:11,380
or less ready.

109
00:07:11,650 --> 00:07:14,590
So here we use the with context method to run.

110
00:07:14,590 --> 00:07:20,380
The task with context is a method created to move an operation into a different thread until it completes

111
00:07:20,380 --> 00:07:21,190
its process.

112
00:07:21,190 --> 00:07:23,560
And then it is moved back into the original thread.

113
00:07:24,010 --> 00:07:25,930
And then we're passing dispatchers.

114
00:07:25,930 --> 00:07:26,620
I o.

115
00:07:28,050 --> 00:07:33,810
Which moves the task to a different threat, which is the input output, Fred, which is different from

116
00:07:33,810 --> 00:07:34,590
the UI Fred.

117
00:07:34,860 --> 00:07:39,030
So it's running on a Fred that is not blocking the user interface.

118
00:07:39,720 --> 00:07:44,160
And when we look at the on click, listen, they're here, we can see that it's not happy, right?

119
00:07:44,170 --> 00:07:45,750
So we need to make a change here.

120
00:07:46,200 --> 00:07:53,580
So in order to make it run, we need to say on which scope we want to run this and I'm going to run

121
00:07:53,580 --> 00:08:01,260
it on the lifecycle scope so we can launch it here and then and then in curly brackets, that's where

122
00:08:01,260 --> 00:08:03,240
we can execute our method.

123
00:08:03,600 --> 00:08:07,320
So in order for this to run, we need to import this launch as well.

124
00:08:07,770 --> 00:08:10,740
And you see here, Colton's launch has been added.

125
00:08:13,250 --> 00:08:18,560
But there are different types of existing quarantine blogs where you can launch a suspend function from

126
00:08:18,680 --> 00:08:21,500
depending on the class it has been called from.

127
00:08:21,800 --> 00:08:28,730
So lifecycle scope is a quarantine block built to properly handle quarantines and any activity class.

128
00:08:29,180 --> 00:08:35,600
So now when we run the application and click on the button after it completes, the app crashes with

129
00:08:35,600 --> 00:08:35,990
an error.

130
00:08:35,990 --> 00:08:36,980
So let's test this.

131
00:08:41,890 --> 00:08:47,290
So you see in the background, it created all of our entries, all of our hundred thousands of entries,

132
00:08:47,290 --> 00:08:47,590
right?

133
00:08:48,160 --> 00:08:50,110
And in the end, it crashed.

134
00:08:51,310 --> 00:08:58,960
OK, so Cortines keeps stop working, so let's close the app, and I still have the other iteration

135
00:08:58,960 --> 00:08:59,740
of the app running.

136
00:09:02,000 --> 00:09:09,350
And our application crashed because of a very simple thing, we are trying to run just toast on our

137
00:09:09,350 --> 00:09:10,220
background threat.

138
00:09:10,460 --> 00:09:15,500
But the toast itself is a foreground or a UI, a task.

139
00:09:15,650 --> 00:09:22,460
OK, so our UI related action like this toast can only be run on the UI thread, but currently we're

140
00:09:22,470 --> 00:09:26,600
running it on this dispatcher's i o thread and this cannot work.

141
00:09:26,960 --> 00:09:28,610
So how can we fix that?

142
00:09:29,060 --> 00:09:35,540
Well, we can add something that we want to run on the UI thread, specifically by calling the run on

143
00:09:35,750 --> 00:09:42,770
UI thread method here, and we can then say what kind of action we want to execute on the UI thread

144
00:09:43,040 --> 00:09:44,540
inside of this call routine.

145
00:09:44,990 --> 00:09:51,140
So here I'm just saying run this on UI thread and particularly the toast should be run on the UI thread.

146
00:09:51,710 --> 00:09:57,790
So let's test this again and see if our application is going to crash and we can see it's running in

147
00:09:58,160 --> 00:09:58,700
the background.

148
00:09:58,700 --> 00:10:02,420
So stuff is happening and our application doesn't crash.

149
00:10:02,420 --> 00:10:03,890
Well, I'm starting it again and again.

150
00:10:03,890 --> 00:10:10,430
So I have multiple iterations of my task, and once it's done, it should display my toaster at the

151
00:10:10,430 --> 00:10:10,910
bottom.

152
00:10:12,880 --> 00:10:13,930
And we could see here.

153
00:10:14,080 --> 00:10:14,740
There it is.

154
00:10:14,770 --> 00:10:15,790
It took quite a while.

155
00:10:16,090 --> 00:10:20,080
But that's just because it takes a while to run the task 200000 times.

156
00:10:20,650 --> 00:10:24,460
So now what we could do is, of course, limit it to ten thousand times.

157
00:10:24,470 --> 00:10:29,110
Then it would run a lot less or 50000, maybe 20000, something like that.

158
00:10:29,500 --> 00:10:29,830
OK.

159
00:10:30,100 --> 00:10:31,660
So that by itself was cool.

160
00:10:31,840 --> 00:10:35,180
But now let's see what is a good approach.

161
00:10:35,200 --> 00:10:40,960
If you have such a situation where you want to run something and you want the user to wait for a response?

162
00:10:41,290 --> 00:10:46,090
Well, what you can do is you can add a progress dialogue.

163
00:10:46,270 --> 00:10:54,340
OK, so I'm going to create this new dialogue entry here, which will be of type, dialogue and dialogue

164
00:10:54,340 --> 00:10:56,800
Nullarbor to be precise and will be null at the beginning.

165
00:10:57,520 --> 00:11:03,640
So this one will be a VAR custom progressed dialogue of type that, OK, let's import it and now we

166
00:11:03,640 --> 00:11:04,240
can use it.

167
00:11:04,480 --> 00:11:09,340
So this will be the progress dialogue, which will just be a dialogue inside of this context and setting

168
00:11:09,340 --> 00:11:15,280
the content to be this dialogue custom progress bar, which is this custom progress bar, which says

169
00:11:15,280 --> 00:11:15,910
Please wait.

170
00:11:16,090 --> 00:11:20,170
OK, so this thing will circle and then this will say, please wait.

171
00:11:20,410 --> 00:11:25,660
And if you look at it, it's just this progress bar with a with a 50 50 with a little bit of margin.

172
00:11:25,660 --> 00:11:28,030
And then we have this text view which says, Please wait.

173
00:11:28,690 --> 00:11:29,230
OK.

174
00:11:29,470 --> 00:11:32,800
So then I have a way to show the progress dialogue.

175
00:11:32,800 --> 00:11:38,050
Now let's add a way to cancel the progress dialogue because otherwise we don't have a clean way of cancelling

176
00:11:38,290 --> 00:11:45,280
the progress dialogue, and I want to be able to cancel it once we are, for example, done with our

177
00:11:46,030 --> 00:11:46,990
execution here.

178
00:11:47,800 --> 00:11:48,190
All right.

179
00:11:48,550 --> 00:11:50,200
So what can we do now?

180
00:11:50,230 --> 00:11:56,920
Well, we can say once we clicked on the button here before we launched a lifecycle scope, let's show

181
00:11:56,920 --> 00:11:58,060
the progress dialogue.

182
00:11:58,780 --> 00:12:00,940
And then once we are done.

183
00:12:02,070 --> 00:12:04,440
And we start running something on the wife thread.

184
00:12:04,560 --> 00:12:06,900
We can cancel it in the thread.

185
00:12:07,380 --> 00:12:13,530
OK, so here cancel progressed dialogue, which handles a progress dialogue which should be also handled

186
00:12:13,530 --> 00:12:14,520
in the way threat.

187
00:12:14,940 --> 00:12:17,880
OK, so progress dialogue, they show something.

188
00:12:17,880 --> 00:12:21,510
If you show something specifically that has to do with the Why Fred?

189
00:12:21,810 --> 00:12:23,640
So let's run the supplication again.

190
00:12:23,650 --> 00:12:25,650
It will be a lot more appealing.

191
00:12:25,650 --> 00:12:26,430
So now we can see you.

192
00:12:26,610 --> 00:12:27,240
Please wait.

193
00:12:27,510 --> 00:12:28,830
And we know that we should wait.

194
00:12:28,830 --> 00:12:32,310
And once the task is done, you see tasks executed successfully.

195
00:12:32,700 --> 00:12:39,080
And you see, even if I click away the wise, the works and the task will still run in the background.

196
00:12:39,090 --> 00:12:43,560
It will succeed successfully and I can run my application cleanly.

197
00:12:43,950 --> 00:12:49,410
So this will make sense for tasks that will take longer, for example, loading data from the internet

198
00:12:49,410 --> 00:12:53,220
or like doing bigger calculations that will just take time.

199
00:12:53,460 --> 00:12:58,440
So that's where it really makes sense to use your call routines.

200
00:12:58,680 --> 00:13:06,030
So just quickly, a summary if you want a function to run as a call routine, you need to add the suspense

201
00:13:06,030 --> 00:13:11,370
keyword you need to add with context and then you say on which context you want this to run.

202
00:13:11,670 --> 00:13:14,610
So on which thread you want this to run the run multiple options.

203
00:13:14,610 --> 00:13:16,680
We're just using the dispatcher's i o here.

204
00:13:17,010 --> 00:13:21,660
And then if you want to execute this function, you need to define on what scope you want this to run.

205
00:13:21,900 --> 00:13:24,000
And I want to run it on the lifecycle scope here.

206
00:13:24,000 --> 00:13:28,260
I launch it and then I can execute my suspend function or my call routine function.

207
00:13:28,590 --> 00:13:32,430
So that's generally the structure that you can use for your call routines.

208
00:13:33,630 --> 00:13:38,110
There is, of course, a lot more to learn about core routines and even have a YouTube video on it where

209
00:13:38,110 --> 00:13:39,810
I go into a lot more depth.

210
00:13:40,050 --> 00:13:44,010
So definitely check that one out and yeah, see you in the next video.

