Bryan Lindsey - Big Nerd Ranch Tue, 19 Oct 2021 17:47:20 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 Google I/O ’21: The Ranch Round-up https://bignerdranch.com/blog/google-i-o-21-the-ranch-round-up/ https://bignerdranch.com/blog/google-i-o-21-the-ranch-round-up/#respond Mon, 24 May 2021 13:05:32 +0000 https://bignerdranch.com/?p=7497 Google I/O just wrapped up, and as usual, Google had plenty of goodies to announce, especially for the development community. We got a handful of big announcements, such as the reveal of Android 12 and the upcoming Material You design updates, a ton of new privacy and security features, and some flashy demos of new […]

The post Google I/O ’21: The Ranch Round-up appeared first on Big Nerd Ranch.

]]>
Google I/O just wrapped up, and as usual, Google had plenty of goodies to announce, especially for the development community.

We got a handful of big announcements, such as the reveal of Android 12 and the upcoming Material You design updates, a ton of new privacy and security features, and some flashy demos of new AI efforts – including a conversation with a paper airplane and Pluto (which I’m pretty sure the Google CEO referred to as a “planet” #plutoIsAPlanetConfirmed #googleOfficial)

There were so many announcements and sessions though that it’s easy to miss a lot of the smaller details. I asked a few of my fellow Nerds what things they found interesting at Google I/O this year, and here’s what they had to say:

Tony Kazanjian

The sparkly ripple effect!

Just kidding… Having a coroutines debugger in Android Studio now should be pretty useful. With StateFlow gaining in popularity, it’ll hopefully help developers use Lifecycle CoroutineScope launchers more effectively to avoid wasting resources.

You can hear more about the Coroutine Debugger in the “State of Kotlin on Android” session.

Brandon Himes

I am really interested in the renewed focus on Wear OS. For the last couple of years I was afraid google was going to abandon wearables. To see that they have partnered with Samsung and that both Samsung and the recently acquired Fitbit will be creating watches that run on Wear OS is very encouraging. As someone who always liked the build quality of both brands (and the affordability of many Fitbit watches), but didn’t want to deal with Tizen or Fitbit OS, I am excited to see what comes of these new developments. Spotify even made a guest appearance to say that they are working on allowing Wear OS users to download music for offline play which has been a huge pain point for many. Google nailed it on this one.

You can hear more about the updates to Wear OS in the Keynote and in the “Now is the time: What’s new with Wear” session.

Anthony Kiniyalocts

I’m interested in the new updates and features added to the Widgets APIs. Supporting rounded corners as a first class citizen, easy access to the systems new dynamic colors to make your widgets “fit in” with the users theme, new native controls (Checkboxes, switches), seamless transitions when entering an app from a widget.

You can learn more about updates on widgets in the “Refreshing widgets” session.

Michael Yotive

I’m really excited about Flutter enabling null safety by default for new projects. Google seems to be steering the language in the direction of Kotlin, which will hopefully ease developer concerns when jumping into the platform.

I’m also really happy for all the iOS bug fixes. There has been a long history of iOS jank and it looks like, with the Skia allowing for pre-compilation of Metal shaders, that a lot of those performance issues have been fixed. More documentation on those issues here: https://github.com/flutter/flutter/projects/188 and https://github.com/flutter/flutter/issues/79298

I’m very excited to dig into the documentation for adaptive layouts. The big issue on cross-platform technologies is dealing with how layout work across device sizes, as well as the expected behaviors (mouse vs touch, for example): https://flutter.dev/docs/development/ui/layout/building-adaptive-apps

You can also learn more about Flutter in the “What’s new in Flutter” session, as well as the other numerous Flutter sessions.

Bryan Lindsey

Hey, that’s me!

I’m excited to hear that Jetpack Compose will be released to a stable version in July! Having used it a fair amount recently, I can’t wait for it to be truly production-ready. You can hear more about Compose in sessions like “What’s new in Jetpack Compose”“Using Jetpack libraries in Compose”, and “Build beautiful Material Design apps with Jetpack Compose”.

I’m also looking forward to the new testing tools and improvements that were announced, especially around making emulators more reliable and useful. You can learn more about testing updates in the “What’s new in Android testing tools” session.

This was just a small sample of a few of the things that we found interesting here at the Ranch. We barely scratched the surface of all the announcements, so check out the Google I/O 2021 playlist if you’re interested in learning even more!

The post Google I/O ’21: The Ranch Round-up appeared first on Big Nerd Ranch.

]]>
https://bignerdranch.com/blog/google-i-o-21-the-ranch-round-up/feed/ 0
Android Dev Summit 2019 Recap https://bignerdranch.com/blog/android-dev-summit-2019-recap/ Tue, 29 Oct 2019 13:47:06 +0000 https://nerdranchighq.wpengine.com/?p=3906 Another year, and another Android Dev Summit has wrapped up. We wanted to share the biggest highlights from the conference in case you missed it.

The post Android Dev Summit 2019 Recap appeared first on Big Nerd Ranch.

]]>
Another year and another Android Dev Summit has wrapped up. This year, a few of us Nerds were lucky enough to attend Google’s conference and we wanted to share the biggest highlights from the conference in case you missed it.

Modern Android Development

A major theme of this year’s Dev Summit is what Google is calling Modern Android Development. Modern Android Development consists of the team’s recommended approach and opinions to app structure, as well as the tools to make implementing that approach not only the best but also the fastest and easiest approach. The team at Google provided some great tools to achieve this through the current Jetpack offerings and they continue to invest in this—as evidenced by the great new tools that Google announced at Dev Summit this year.

Jetpack Compose

One of the biggest (and, in my opinion, most exciting) topics at the Dev Summit was Jetpack Compose. Compose was initially announced at Google I/O earlier this year and is a new declarative UI toolkit for Android. The big news is that it is now much easier to try Compose. In the past, trying Compose involved a complicated process, but it is now as simple as adding some Gradle dependencies in a project using the newly released Android Studio 4.0 Canary 1.

In addition to being easier to try, they showed off handy features like Composable previews in the editor, a new Setup Wizard option to add a Compose Activity, and interoperability between Compose and the existing View system.

Keep in mind that this is still a very early version. The team made sure to emphasize that this is not ready for production yet since things are very likely to change as development continues. But, if you want to try it out, there is updated documentation available, including a codelab and a sample project.

Motion Editor

Also announced as part of Android Studio 4.0 Canary 1 was the Motion Editor. It is a visual editor for creating animations and transitions for MotionLayout. It even lets you add click and swipe handlers right from the editor and it will generate the necessary code for you behind the scenes. We hope to have a more detailed post on Motion Editor soon, so keep an eye out on our blog!

Live Layout Inspector

The team showed off an updated Layout Inspector tool. It has many of the same features of the existing layout inspector, but with several new additions. To start, this new Inspector will show a live updating layout hierarchy as the views on your device change. It also includes tools to allow you to drill into resources right from the view to find where values like text and colors originate (trust me, it’s way cooler than it sounds). Lastly, they also showed off a cool 3D “exploded” view. In addition to looking awesome, it can help you identify issues with overdraw that can negatively affect UI performance.

Unfortunately, this isn’t available in the AS 4.0 Canary 1, but they said it should be coming soon.

And so much more!

In addition to these major new features, there were a ton of other things announced. This includes a new way to work in both Layout XML and Design views side-by-side, a new Build Profiler tool that can help to easily identify bottlenecks and slowdowns in your builds, improved Kotlin DSL support for Gradle, and a super cool way to use an emulator directly in the IDE.

In addition, there were some great talks that cover a wide range of topics. I personally recommend checking out the talks on LiveData with Coroutines and FlowDebugging Tips and Tricks, and the Opinionated Guide to Dependency Injection.

With all the new things being announced, it’s really exciting to see how the future of Android continues to evolve. With that, I’m off to go play with Compose and the new MotionEditor…

The post Android Dev Summit 2019 Recap appeared first on Big Nerd Ranch.

]]>
Activity and Fragment Layouts with AndroidX https://bignerdranch.com/blog/activity-and-fragment-layouts-with-androidx/ Tue, 27 Aug 2019 10:30:50 +0000 https://nerdranchighq.wpengine.com/?p=3818 Wouldn’t it be nice if there was a simpler way to inflate our views? I’m glad to say that with a few recent AndroidX library updates, there is a simpler way.

The post Activity and Fragment Layouts with AndroidX appeared first on Big Nerd Ranch.

]]>
For as long as Android development has been around, we’ve been using setContentView to inflate layouts in our Activity classes. And since the introduction of Fragments, we’ve had to override onCreateView and use a layout inflater to get our view from a layout ID. They’re so common to write that it’s easy to not think about them much. At the same time, they feel a bit like boilerplate, right? Wouldn’t it be nice if there was a simpler way to inflate our views?

I’m glad to say that with a few recent AndroidX library updates, there is a simpler way.

Show me the code!

During development of AndroidX Fragment 1.1.0 and AndroidX Activity 1.0.0, the kind folks at Google added a new way to inflate layouts. To start using these, add the following lines to the dependency block of your module-level build.gradle file:

implementation 'androidx.appcompat:appcompat:1.1.0-rc01' // this is needed to use the updated AppCompatActivity
implementation 'androidx.activity:activity-ktx:1.0.0-rc01' // or remove -ktx if not using kotlin
implementation 'androidx.fragment:fragment-ktx:1.1.0-rc04' // or remove -ktx if not using kotlin

Note that these versions are the latest as of this writing, but update them as needed. You can find the latest versions here.

These new versions add the ability to pass the layout ID to the constructor of the Activity or Fragment base class, and it will handle inflation behind-the-scenes. So, instead of something like:

class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {	
        super.onCreate(savedInstanceState)	
        setContentView(R.layout.my_activity_layout)	
    }
    // ...
}

… you can instead write:

class MyActivity : AppCompatActivity(R.layout.my_activity_layout) {
    // ...
}

This works similarly with Fragments as well. Make sure to import AndroidX Fragments (androidx.fragment.app.Fragment) rather than the framework version (android.app.Fragment).

Old way:

class MyFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {	
      return layoutInflater.inflate(R.layout.my_fragment_layout, container, false)
   }
    // ...
}
```

New way:

class MyFragment : Fragment(R.layout.my_fragment_layout) {
  // ...
}

If the only code that was inside of the Activity’s onCreate or the Fragment’s onCreateView method was layout inflation code (like in the examples above), then you can completely remove those overridden methods. This is especially useful in Fragments, since you can put any logic for after the view is inflated in the onViewCreated method.

Wrapping up

This new way of using layouts isn’t going to change the landscape of UI development on Android (I’m lookin’ at you, Jetpack Compose), but it’s a small step that can save us from writing a little bit of extra code when making our Activities and Fragments, which I can certainly appreciate.

Need an introduction to Kotlin? Download our free eBook to learn what this language means for your Android App.

The post Activity and Fragment Layouts with AndroidX appeared first on Big Nerd Ranch.

]]>
LiveDataReactiveStreams: Where RxJava meets LiveData https://bignerdranch.com/blog/livedatareactivestreams-where-rxjava-meets-livedata/ https://bignerdranch.com/blog/livedatareactivestreams-where-rxjava-meets-livedata/#respond Mon, 29 Apr 2019 09:00:00 +0000 https://nerdranchighq.wpengine.com/blog/livedatareactivestreams-where-rxjava-meets-livedata/ When choosing a library to make your Android application reactive, which do you choose - the trusty, ever-popular RxJava 2, or the newer, first-party LiveData? While it may be a subject of debate, the good news is that these two can work together using a tool called LiveDataReactiveStreams

The post LiveDataReactiveStreams: Where RxJava meets LiveData appeared first on Big Nerd Ranch.

]]>

When choosing a library to make your Android application reactive, which do you choose: the trusty, ever-popular RxJava 2, or the newer, first-party LiveData? While it may be a subject of debate, the good news is that these two can work together using a tool called LiveDataReactiveStreams.

In this post, we’ll explore how LiveDataReactiveStreams works, as well why (or why not) you might want to use it to bring RxJava and LiveData together. Note that it does assume some familiarity with RxJava and LiveData.

Syntax

LiveDataReactiveStreams is a class provided as part of Google’s Jetpack components. To use it, you need to add the ReactiveStreams dependency to your project. In your build.gradle file, add the following to your dependencies block (replacing $lifecycleVersion with the latest dependency version, which is 2.0.0 as of this writing):

implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"

In order to convert from an RxJava stream to a LiveData object, use the fromPublisher() method provided by LiveDataReactive streams, like so:

// Note, I've added explicit types for clarity. You can omit these in your code.
val myRxStream: Flowable<MyDataType> = Flowable.fromCallable{ fetchSomeDataViaNetworkCall() }

val myLiveData: LiveData<MyDataType> = LiveDataReactiveStreams.fromPublisher(myRxStream)

The fromPublisher() method takes an instance of the Publisher interface, which is implemented by RxJava Flowables, and returns a LiveData object. Also note that the type emitted by the RxJava stream (in this case, MyDataType) will be the type of the data held by the LiveData.

Importantly, what this does is it creates a LiveData object that updates its value any time the source RxJava stream emits a new item. This means that anything that observes the LiveData (such as a Fragment that updates the UI when the LiveData changes) will be notified when the RxJava stream emits.

But… why?

You might be wondering the benefit of converting like this as opposed to using your RxJava stream or your LiveData object all the way through. The answer is that doing so allows us to utilize the strengths of both in a fluid way.

In terms of strengths, RxJava is a robust toolset. There are tons of operators to allow you to manipulate your data stream in a multitude of ways, including built-in tools for specifying which threads operators execute on. This is great for complex operations on data, such as might be found in the business logic of applications.

While LiveData has a smaller set of operators, it offers the benefit of built-in lifecycle awareness. This means that it can safely and easily update UI elements even through the complex lifecycles of Activities and Fragments, which is not built in to RxJava (though there are tools like AutoDispose that can make this somewhat more automatic).

Also unlike RxJava, LiveData works with data binding out of the box.

What all of this means is that LiveData is great for pushing data to the UI but not as much for handling business logic, and RxJava is great for business logic but not as much for UI. The LiveDataReactiveStreams fromPublisher() method offers a simple way for us to push updates from our data/business-logic layers up to the UI while utilizing these strengths.

When used in this way, a cool feature of LiveDataReactiveStreams is that it automatically posts values to the main thread. If you’re using LiveData for updating UI elements, this saves you from having to manually call postValue() on a LiveData or use RxAndroid for returning to the main thread on the RxJava stream.

Finally, a key selling point of LiveDataReactiveStreams is that is a more direct way of connecting RxJava and LiveData together. Without it, you need to subscribe to your RxJava chain and post values to the LiveData in the subscriber:

// Private, mutable backing field - only update values internally
private val _myLiveData = MutableLiveData<String>()

// Observers will subscribe to this since it is immutable to them
val myLiveData: LiveData<String>
    get() = _myLiveData

// Keep a reference to the disposable, and make sure to clear it appropriately somewhere
val disposable: Disposable = Flowable.fromCallable{ methodThatReturnsString() }
        .subscribe(
            { myString -> _myLiveData.postValue(myString) },
            // Make sure to handle errors
            { error -> Log.e(TAG, "Oops, hit an error", error) }
        )

While this certainly works, calls to subscribe() feel like that you’re ending your RxJava chain and leaving the reactive world, even though you’re still trying to do reactive things with LiveData. LiveDataReactiveStreams bridges that gap so that you don’t have to leave the reactive world.

Download our free eBook to learn why professional development opportunities are key to your company’s success.

Caveats

While this tool offers simplicity in some ways, it also comes with a handful of limitations that you will want to consider. You can find a few major ones discussed below.

Error Handling

To start with, since LiveData does not have the option to add an onError handler like RxJava does, any errors that make it through LiveDataReactiveStreams from your RxJava stream will crash your application. That being said, you can use RxJava’s error handling operators in your RxJava chain to prevent this:

// Note, I've added explicit types for clarity. You can omit these in your code.
val myRxStream: Flowable<Int> = Flowable.fromCallable{ methodThatThrowsAnError() }
        .onErrorReturnItem(-1) // Use -1 as a error case

val myLiveData: LiveData<Int> = LiveDataReactiveStreams.fromPublisher(myRxStream)

Subscriptions and Lifecycles

Another major caveat lies in how the LiveData subscribes to the RxJava stream behind the scenes. When the LiveData becomes inactive because the lifecycle it is associated with moves to the DESTROYED state, then LiveData clears its subscription from the RxJava stream. It will then re-subscribe when the LiveData becomes active again. This has different implications depending on whether you are using hot vs. cold Flowables.

For cold Flowables, such as the one in the example above, the RxJava stream will start all over again when the LiveData re-subscribes. If this RxJava stream makes a network request, this means that the request will be made again when reattaching (unless you have some kind of caching mechanism in place).

For hot Flowables which can emit even with no subscribers, this has the implication that any emissions sent out after the LiveData becomes inactive will not be picked up by the LiveData.

In both cases, LiveData will still cache the last value emitted by the RxJava stream and send it to the Observer when it becomes active again, but won’t get an updated value until the stream emits another item.

Whether this behavior is problematic depends on your use case. In the end, with mindful use of RxJava features, you can still accomplish your desired flow. The key is being aware of how the lifecycle affects your subscription.

What about toPublisher()?

Astute readers may have noticed another method provided by LiveDataReactiveStreams called toPublisher(). Since we’re focusing on using LiveData to push data to the UI, fromPublisher() is sufficient to get the benefits of LiveData and RxJava together. However, I encourage you to learn more about toPublisher() if it seems like it fits your use-case.

Reactive Choices

When it comes to choosing whether to use RxJava or LiveData in your next project, keep in mind that they can work well together in the same codebase. As we’ve discussed, they have their individual strengths, and can work really well with the style of MVVM laid out by Google.

LiveDataReactiveStreams offers a simple interface that allows you to convert RxJava streams to LiveData in a direct way. However, keep in mind the slew of caveats that come with it. These caveats can bring their own complexity, so consider them when deciding if LiveDataReactiveStreams will work best for your situation.

The post LiveDataReactiveStreams: Where RxJava meets LiveData appeared first on Big Nerd Ranch.

]]>
https://bignerdranch.com/blog/livedatareactivestreams-where-rxjava-meets-livedata/feed/ 0