Coder Social home page Coder Social logo

link-router's Introduction

link-router

This library contains the basic infrastructure for routing deepLinks, activities and fragments within a multi-module application in a way that a feature module does not need to explicitly depend of another.

Why did we write this library?

Not every project can follow the single Activity recommendation from Google, not every Activity has a public DeepLink to its screens.
Those are just some of the situations we find ourselves while working in a project that has been developed for many years.
We have screens that should only be accessed after the user is logged in, does Navigation Component help us with that? So we developed this library.

This library does less, so you can do more

There is no magic here, not even code generation, you will need to write code to make it work. This library just gives you access to Intents and Fragments instances, it does not start activities for you or commit fragments. We will just give you access to things that you would would not have access without direct access to the classes. Ok, Ok, we do start activities when routing DeepLinks, but this is usually fine since we need to start a whole stack of Activities for you.

Usage

The basic concept is the same for all routing, at the app startup we register all deeplink, activities and fragments mappers. And in a separated module (like :routes) we share basic implementations that works as indirections to the real implementations.

Activities

To make it possible to route your Activity into other modules we need to implement ActivityName, ActivityLink<ActivityName> and ActivityNameMapper<ActivityName> that reflects you needs.

  • ActivityName acts as key when routing to your Activity #shared
  • ActivityLink binds the ActivityName with parameters we want to pass to that Activity and #shared
  • ActivityNameMapper<ActivityName> maps the ActivityName into an Activity class. #internal

Things we need to share

The ActivityLink and ActivityName are used to route, so the client module needs to have access to that implementation. You can place it in a :routes module or in any other shared module that suits your needs (:mydomain:routes, maybe?).

object MyActivityName : ActivityName
class MyActivityLink(
    override val parameter: MyActivityParameter
) : ActivityLink<MyActivityName> {

    override val activityName: MyActivityName = MyActivityName
}

@Parcelize
data class MyActivityParameter(val data: String) : ParcelableParameter

Things that we keep inside

With that key we can implement an ActivityNameMapper<ActivityName> in your feature module.

object MyActivityNameMapper : ActivityNameMapper<MyActivityName> {
    override val supportedNames: Array<MyActivityName> = arrayOf(MyActivityName)

    override fun map(activityLink: ActivityLink<MyActivityName>): Class<out Activity> {
        return MyActivityName::class.java
    }
}

Pro tip

If your module has multiple activities you can use an enum for your ActivityName and only one implementation of ActivityNameMapper<ActivityName>.

enum class  MyFeatureModuleActivitiesNames : ActivityName {
    MyActivityName,
    MyOtherActivityName
}

and

object MyFeatureModuleActivityNameMapper :
    ActivityNameMapper<MyFeatureModuleActivitiesNames> {
    override val supportedNames: Array<MyFeatureModuleActivitiesNames> = MyFeatureModuleActivitiesNames.values()

    override fun map(activityLink: ActivityLink<MyFeatureModuleActivitiesNames>): Class<out Activity> {
        return when (activityLink.activityName) {
            MyFeatureModuleActivitiesNames.MyActivityName -> MyActivity::class.java
            MyFeatureModuleActivitiesNames.MyOtherActivityName -> MyOtherActivity::class.java
        }
    }
}

Fragments

Activities and Fragments have similar abstractions, so if you know how to route Activities, you know how to route Fragments.

Activity Fragment
ActivityNameMapper FragmentNameMapper
ActivityName FragmentName

DeepLinks

To each DeepLink we need an implementation of DeepLinkMapper<DeepLink>, where we describe for which apps that DeepLink is supported, what is the DeepLink authority and what stack of Activities should be created.

object MyDeepLinkMapper : DeepLinkMapper<UriDeepLink> {
    override val supportedSchemes: Array<Scheme> = arrayOf(Schemes.publicAppSchemes)
    override val supportedAuthority: String = "my schemne"

    override fun stack(deepLink: UriDeepLink): Array<ActivityLink<ActivityName>> {
        return arrayOf(
            ExternalDeepLinkRouterActivityLink(deepLink.parameter)
        )
    }

    override fun canHandle(deepLink: DeepLink): Boolean {
        return super.canHandle(deepLink) && deepLink is UriDeepLink
    }
}

Runtime registration

You can use the Application.create() method or Googles StartUp library to register your mappers. Use RouterBuilder to register ActivityNameMappers, FragmentNameMappers and DeepLinkMappers.

class MyFeatureModuleInitializer : AppStartUp<Unit>() {
    override fun create(context: Context) {
        with(GlobalRouterBuilder) {
            add(MyActivityNameMapper)
            add(MyFragmentNameMapper)
            add(MyDeepLinkMapper)
        }
    }
}

link-router's People

Contributors

juliocbcotta avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.