Beginning Flutter Debugging

Sep 29 2022 · Dart 2.18, Flutter 3.3, Visual Studio Code / Android Studio

Part 1: Beginning Flutter Debugging

07. Get a Tour of Dart DevTools

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 06. Debug with Android Studio Next episode: 08. Debug Common Layout Issues

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 07. Get a Tour of Dart DevTools

DevTools was opened on a different browser and the base url was copied and pasted in Firefox. The original url had some parameters which were unintentionally left out. The correct url should be something like this: http://127.0.0.1:9101/#/?hide=debugger&ide=VSCode. So take note of this if you intend copying the url to another browser. The student materials have been reviewed and are updated as of SEPTEMBER 2022.

Transcript: 07. Get a Tour of Dart DevTools

Dart Devtools is a tool that provides different utilities for debugging and monitoring our apps. It runs in a browser and also inside VSCode and Android Studio thanks to the Flutter plugin.

The app for this episode shows a list of dogs which you can pet. You select the specific dog you want then clicking on the dog detail pets the dog. You can pet each dog as much as you want.

To open up devtools from VSCode, click on the “Open DevTools” icon in the status bar below. This opens up the command pallete with the devTools menu. We can open up specific screens inside VSCode but i’ll select ‘Open DevTools in the Browser’ so we can explore it as a whole in this episode.

This opens up a browser window with devTools running. For android studio users, open up the debug pane then click on the “Open Devtools” icon. The devtools window contains different utilities. The first is the Flutter Inspector. It helps us visualize our widget tree and can be used to debug layout related issues.

By the left, you have the widget tree. This shows the composition of our widgets up to its root. You can browse through the widget tree to see different properties of indiviual widgets. But a more interactive approach would be to specifically select widgets to inspect. For this, you click on the “Select Widget Mode” button. Then you select the widget you want to inspect on your app screen.

Let’s select the dog avatar image below. This highlights the image and navigates to the widget in the widget tree. We can see it is an Image that is inside a Column. And this Column is contained in a Row.

Let’s select the Row from the widget tree. And you can see the Row is highlighted. You can also see the properties of a selected widget by the side in the details tree.

The default properties are shown with the icon denoted with the letter D.

With this, you can see the properties you’ve specifically set and check how it affects your layout. And for the layout explorer tab, we’ll be using it to solve some layout issues in this next episode so i’ll skip that for now. Let’s deactivate the “Select Widget” mode.

Next, you have the slow animations button. This is very helpful when debugging animations. The dog details widget animates in when we switch between dogs but we can’t really see that on my computer. This is simply because emulators can be slow depending on the configuration of your computer. And the best place to test your app while developing is on a real device with your app running in profile mode.

Okay, let’s select it and see how the slow animation plays out. You can see it slows down the app and we can have a detailed understanding of how the app animates. Let’s switch that off.

Next, is the overlay guidelines. This shows you the Box rendering of your widget. This includes, stuffs like padding, spacing, borders, alignment and even scroll direction for scrollable widgets.

This is just like the select widget mode but this shows these hints for the entire app screen. With this, you can actually see how padding and other box properties affects your widget which could be helpful while debugging.

Then we have the show baselines. It paints each line of text at its baseline. This can be used to check if our text aligns properly. You can see that the text for all the dog tile widgets are all on a straight line.

Next, is the Highlight Repaints. This shows alternating colors as flutter repaints widgets on the screen. Notice that the DogScreen isn’t really repainted when we switch between dogs. But when we pet the dog, we can see that the the dogscreen is repainted. And this is because the snackbar shown here is from the Scaffold widget of the DogScreen. So the DogScreen is always repainted.

We could use this to track unneccesary repaints. Finally, we have the “Highlight Oversized Images.” This highlights images that are using too much memory than required.

If we look at the console, we can see that all the images we’re using are guilty of this. You can see that it says an image uses a display size which is lesser than the original dimensions of the image. The best way to solve this is too reduce the size of the image file. In our example here, it would be wise to provide two different sets of images: One for the thumbnail and the other for the detail image above.

Next, we have the Performace, CPU Profiler and Memory utilities. These are used to track the performance of your apps. To use these utilities, you have to run your app in profile mode and on a real device. Doing this would give you the accurate metrics of your app’s performance.

This is because simulators cannot match the hardware of a real device. Also, apps that run in debug mode have additional layers of code running to support the development environment and this can slow down the app a bit.

To show you what i mean, let’s head over to the peformance page. And you can see the warnings at the top of the page. Flutter is designed to run our app’s UI at 60fps or 120fps on capable devices. Anything below these causes janks in our apps. A frame is janky if it takes more than 16.7ms to complete.

The frame rendering chart is displayed. First i’ll clear the chart. We can see the milliseconds on the vertical axis. We also have a horizontal line at 16.7ms to show that anything above this means that there was a jank. We also have legends at the right that shows the render categories.

Let’s go over to the app. And click on the dog details image multiple times. Then head back to DevTools. Each bar represents a frame. Any frame that takes more than 16.7ms to complete is highlighted in red. You can see that most frames take way above 16.7ms to complete.

So the rule of thumb is: run your app in profile mode on a real device. Performance profiling is beyond the scope of the course so we’ll move on to the next view which is the Debugging view. Devtools hides the debugger tab by default when you run your app with VSCode and that’s why we cant see it here.

This is because the debugger here is identical with that of VSCode. The Debugging view is enabled for Android Studio users that want a similar debugging experience with that of VSCode.

The Network Tab is used when you app interacts with data over a network. You simple use it to inspect HTTP, HTTPS and web socket data from your Flutter apps. Our sample project doesnt interact with an API so we wont be using it here.

Finally, we have the Logging view. This view displays log events from different sources while running your apps. It shows garbage collection events from dart, flutter related logs like the logs for frames and also application logs which we can set in our code. Let’s do a hot restart from inside of Devtools.

You can see some gargabe collection from dart runtime. Also where the hot restart was triggered and some flutter frame logs. We can also see the image size log prompting us to try resize the images.

We’ve used print statements in some previous episode. Print statements are not really ideal. Sometimes, when the output to print is too much, Android truncates the output. One way around this is to use the debugPrint provided by Flutter. But a more robust way is to use the log function from the dart:developer package.

Let’s head back to our IDE. And open up the DogScreen widget. First, i’ll import the dart developer package.

import 'dart:developer' as dev;

We import the dart:developer package which contains neccassary code debugging features for our dart apps. Then i’ll scroll down to where the DogTile is used ie these individual thumbnails. I’ll go ahead and log a simple message inside the onTapped method of the DogTile widget.

...
onTapped: () {
  // After setstate()
...
  dev.log("Some long message");

In here, we send a log event using the log function. Do note that the log function has more optional parameters that lets you further customize the log output. The log output would be displayed both in the debug console and inside the logging view of devtools.

Then we tap on a dogTile. Then i’ll head back to devTools. e can see the log message and we are rest assured that Android’s kernel won’t truncate the output since it is displayed in devtools.