OneSignal / OneSignal-Android-SDK

OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your native Android or Amazon app with OneSignal. https://onesignal.com
Other
605 stars 370 forks source link

Investigate if an Application Context can be retrieved statically #1307

Open jkasten2 opened 3 years ago

jkasten2 commented 3 years ago

Motivation

OneSignal requires OneSignal.initWithContext(context) be called from Application.onCreate. However there is no guarantee the app developer does this so the OneSignal SDK may not have a Context instance. This has the following downsides:

  1. Requires OneSignal to be initialized in Application.onCreate. This means SDK initialization is not very flexible.
    • Getting a Context is just half the problem, ActivityLifecycleCallbacks have to be setup before any Activities are shown.
  2. Lots of null Context checks in our code. (one example)
    • There are design patterns to make this null check much cleaner, but even better if we can remove all checks completely.
  3. Prevent future null Context bugs in the SDK.

Scope

Research and make note of options (even thoughts on things that don't work and why) to get an Application Context without requiring the developer to supply it.

Possible Options

  1. LocalContext.current, this might only work with Jetpack UI components and it seems it requires adding s @Composable attribute to your method. Example code
  2. Jetpack App Startup - Runs when app starts, might have an API to get Context.
  3. ContentProvider - Runs when app starts, it has a way to get a Context.
    • Disadvantage of not being available for the older Android versions
    • This is not what a ContentProvider is designed for, but I think it is ok to use this way.
phileo99 commented 3 years ago

OneSignal.java line 629 is already retrieving the Application Context from whatever context was passed in. So that means whoever calls OneSignal.startInit() can pass in an Activity Context or Service Context. In other words, OneSignal.startInit() can be called from any Activity or Service if necessary, and is not restricted to being called from Application.onCreate().

Many consumers of your library already subclass the Application class for their own app specific initialization, and those who don't have their own Application subclass can easily call OneSignal.startInit() from their Activity or Service without issues. So is there really a problem that you're trying to solve here, or am I missing something ?