Flutter is one of the most interesting technologies among the new trends in mobile software development. Thus, it is no surprise that Codemotion Milan 2018 included a talk about Flutter in its agenda. Such talk was delivered by Faisal Abid, Google Developer Expert and CTO at Zoom.ai. Faisal divided his speech into two parts; he started by introducing Flutter, and then discussed how Android developers can benefit from using it.
Introducing Flutter
Flutter is a framework developed by Google, aimed at building native mobile applications for both Android and iOS platforms. Using this technology, developers can easily and quickly build applications that “feel natural”. Many of us have experienced weird behaviours from mobile applications, in terms of animations or features that do not appear consistent with the surrounding mobile OS ecosystem. According to Faisal, Flutter solved this issue by including material design in the Flutter widgets, producing applications with high quality and modern designs.
One of the most common mistakes about Flutter is the belief that it uses HTML5 and WebViews in order to implement both Android and iOS applications, similar to what other cross-platform development frameworks (e.g. PhoneGap) did in the past. Actually, this is not the case. In fact, Flutter allows the developer to create fully native mobile apps, using the Dart programming language.
As mentioned by Faisal, when Google decided to develop Flutter, they had to decide which language to use. Among the many choices available, including Javascript, Python, Scala, and many others, Google opted for Dart. One might consider this choice as driven by ownership (Dart has been developed by Google too). However, the main reason why Google choose Dart is in its learning curve, which resulted in it being the best one among the languages evaluated. Indeed, Dart allows us to develop applications very easily; while it was born as a sort of “evolution of Javascript”, this programming language has mostly simple features, usually included in other programming languages, and thus known by many developers.
By using Dart and Flutter, developers can decide how to deploy their applications; they can opt for Java or Kotlin for Android, or for Swift or Objective-C for iOS. It is worth highlighting that choosing one of these languages does not require any kind of knowledge from the developer’s point of view. Dart remains the only programming language processed by Flutter, while the aforementioned native mobile languages are just useful for understanding what the output will be.
Figure 1. Creation of a new Flutter project with IntelliJ, allowing selection of native languages.
Flutter for Android developers
In the second part of his speech, Faisal described some common patterns that are useful for Android developers who want to move to Flutter. In particular, he identified three interesting patterns: implementing AsyncTasks, managing navigation via Intents and understanding how the Activity’s life cycle is affected by Flutter.
For implementing asynchronous tasks in the background, it is crucial to understand that Flutter has a single-threaded execution model, supporting the so-called Isolates (a way to run Dart code on another thread). Instead of implementing the onPreExecute(), doInBackground() and onPostExecute() methods of the AsyncTask class, Flutter solves the problem by declaring a function as async, and using the await keyword for long run tasks. Dart will “figure out” how to pass this task to a background thread, avoiding freezing the UI.
loadData() async {
String dataURL = "https://mysite.com/data.json";
http.Response response = await http.get(dataURL);
setState(() {
widgets = json.decode(response.body);
});
}
In order to navigate among Activities, Android uses Intents. However, there is nothing like Intents in Flutter. Instead, you need to use Navigator and Routes. A Route is an abstraction for a “screen” or “page” of an app (i.e. an Activity on Android); a Navigator is a widget that manages routes. Navigators work like a stack on which you can push() new routes you want to navigate to, and from which you can pop() routes when you want to “go back”. The following snippet shows how to navigate to a route by pushing its name (“\b”) to the Navigator:
Navigator.of(context).pushNamed('/b');
Finally, the third common pattern described by Faisal is about understanding the Activity’s life cycle. In Flutter, all the Activities are widgets. Similar (but not equal) to what happens with Android Activities, you can observe for the following lifecycle events:
- inactive — The application is in an inactive state and is not receiving user input. This event only works on iOS, as there is no equivalent event to map to on Android
- paused — The application is not currently visible to the user, not responding to user input, and running in the background. This is equivalent to onPause() in Android
- resumed — The application is visible and responding to user input. This is equivalent to onPostResume() in Android
- suspending — The application is suspended momentarily. This is equivalent to onStop() in Android; it is not triggered on iOS as there is no equivalent event to map on iOS
Faisal concluded his talk by mentioning that the official Flutter documentation offers many additional information for Android developers who want to port their applications to Flutter. Moreover, information for other developers (iOS, React native, web devs, Xamarin.Forms) is also available.