Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Android View-based architecture instead of Activity-based #12302

Closed
aem opened this issue Feb 9, 2017 · 13 comments
Closed

[Discussion] Android View-based architecture instead of Activity-based #12302

aem opened this issue Feb 9, 2017 · 13 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@aem
Copy link

aem commented Feb 9, 2017

Some background before I get into the meat of this issue. First, motivation. Currently my company has a diverse ecosystem of web apps (all React) that have lots of complex application logic that may change regularly, and thus shouldn't be duplicated across codebases. We also have existing Android and iOS apps which currently duplicate lots of code between them. We'd really love to be able to share logic between all 3 platforms and components between the two mobile apps to get as much code reuse as possible. Second, background around the Android app itself. We have an existing Android application using Flow as a UI router. This means that rather than having one Application with many Activities, we have one RootActivity with many views that Flow knows how to inflate/deflate based on unique keys passed into the router.

Ultimately, this means that react-native's architecture which revolves around Activities rather than Views is not viable for our application. We're trying to implement just pieces of our app in react-native while leaving the majority of our architecture in place, effectively just using react-native as a view layer.

If this is something that is possible and I'm just not fully understanding it, I would love an explanation. We're really trying to buy into native applications running JavaScript, I'm just really not able to grasp how that would be possible with the current state of react-native.

If this is not possible, would the core team be open to a discussion about maybe changing react-native a bit to be more usable as a pure view layer? Right now it seems react-native is based on the assumption that your entire application is a react-native application which simply isn't the case.

@lacker
Copy link
Contributor

lacker commented Feb 10, 2017

I don't think that React Native is based on the assumption that your whole app is in React Native - the Facebook and Instagram apps, after all, are not entirely built in React Native. But, I don't know how it would work in conjunction with an architecture that only has one RootActivity.

I think the core team would be open to discussion but it would really help to have a concrete suggestion for how React Native would be changeable.

@hey99xx
Copy link

hey99xx commented Feb 10, 2017

React Native is not based on the assumption that your whole app is in React native, but that assumption is totally understandable since in the public docs there's barely any example on how to achieve a view or fragment based setup.

You can create a ReactRootView yourself and place it inside the activity, destroy it, and create another one. As long as you create single ReactInstanceManager object, you can share the same JavaScript universe for creating multiple views in different activities.

One minor drawback of this approach is that the default ReactActivity gives you many hooks which you'll still need to call to get few native modules working https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java.

The major disadvantage I've seen is that the default navigator components that come out of the box become pretty useless since you have a native navigation bar and platform specific navigation code (push uiviewcontrollers, start activities) etc. and this is difficult to integrate.

@rodperottoni
Copy link

I'm afraid your suggestion goes against the basic engineering of the Android platform.
One day or another you'll need to leverage the Activity lifecycle events and when that happens you'll be in trouble with all the "ok the app resumed, now what view am I showing, what's my state, what should I do?!". I don't have much to add besides what @lacker said.

@lacker
Copy link
Contributor

lacker commented Feb 10, 2017

It would be really great if someone was interested in writing a doc of how to set up an app with one of these alternative setups!

@hey99xx
Copy link

hey99xx commented Feb 12, 2017

The old versions of react-native website had some brief explanation. I don't know why this link went away later.

http://facebook.github.io/react-native/releases/0.26/docs/embedded-app-android.html#content

Sharing a ReactInstance across multiple Activities / Fragments in your app

You can have multiple Activities or Fragments that use the same ReactInstanceManager. You'll want to make your own "ReactFragment" or "ReactActivity" and have a singleton "holder" that holds a ReactInstanceManager. When you need the ReactInstanceManager / hook up the ReactInstanceManager to the lifecycle of those Activities or Fragments, use the one provided by the singleton.

@aem
Copy link
Author

aem commented Feb 13, 2017

@rodperottoni definitely understand Activity lifecycle events are relevant, we've got some infrastructure in place to handle that. We just believed that the benefits Flow brought our team made the move away from the Activity-based architecture worth the tradeoff. I'd suggest reading about Flow, it was put together by Square and we've seen some pretty big benefits with it.

Furthermore, we've got the app in place with a lot of engineering investment behind it, and it's been working well for us, so until we run into some major issues, an architectural shift really isn't something we can entertain.

@lacker if we ever figure it out I'd be happy to write up some docs on it and share our story. We're pretty determined to figure it out as the code reuse issue between desktop and mobile, as well as between mobile platforms is something we're pretty committed to, so I can keep this issue updated as we make progress.

In terms of proposing a concrete solution, I personally can't really help with that as I'm very new to Android development so just understanding the react-native code has been a challenge, let alone proposing a new architecture. Having said that, I'm working with the rest of my team and hopefully they'll be able to try and come up with something. Will update here once I hear more from them

@aem
Copy link
Author

aem commented Apr 7, 2017

Going to close this. We settled on a somewhat makeshift architecture for our react-native components. We have an injected ReactInstanceManager that is created on launch and then in each View where we'd like some react-native components we have some code like:

    val rootView = ReactRootView(context)
    rootView.startReactApplication(reactInstanceManager, "MyComponent", null)
    addSubview(rootView)
    reactInstanceManager.onHostResume(this, this)

This solves my problem outlined here, now our only blocker is outlined in #13340

@aem aem closed this as completed Apr 7, 2017
@ahetawal-p
Copy link

Hi @aem
I have been following this thread, since we are in a similar situation are yours. Although adding the ReactRootViewdoes the trick. I am curious to know how does your addSubview(rootView) works, in terms of handling the layout.
Added my details here #13476, would be very interested on hearing your thoughts to handle adding react subViews.

@aem
Copy link
Author

aem commented Apr 16, 2017

@ahetawal-p i'd imagine re-writing individual components isn't very valuable, but rather having an entire view as react-native or pure native code, but no mixing/matching

@ahetawal-p
Copy link

I see, thanks @aem for the response. In my case as we iterate over the migration to RN, we want to move views inside a native Tablayout one by one, so will require some mix and match :)

@aem
Copy link
Author

aem commented Apr 26, 2017

as a follow up on this issue, i got some of my thoughts out in this medium post: https://t.co/4UPsodPBuJ

@Surendharopus
Copy link

Hi, pls give some example for JSON parsing(POST) in React Native Android

@hey99xx
Copy link

hey99xx commented Jul 6, 2017

@Surendharopus open a new issue! JSON parsing has nothing to do with what this issue is about.

@facebook facebook locked as resolved and limited conversation to collaborators May 24, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

8 participants