cordova-android
cordova-android copied to clipboard
Access onCreate() Lifecycle in Cordova plugin
Feature Request
Motivation Behind Feature
Some plugins may require to perform actions inside the onCreate()
Activity Lifecycle.
An example of logic that needs to be inside onCreate
:
public class MainActivity extends AppCompatActivity {
private Foo mService;
private ServiceConnection mConnection;
private boolean isConnect = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
if(mConnection == null)
mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
mService = Foo.bar(service);
isConnect = true;
}
};
}
In my understanding onServiceConnected
should have ran when onCreate
has completed.
This logic would not behave the same inside the available CordovaPlugin
class methods like initialize()
or onStart()
.
(My real world use case is to write a Cordova plugin for the MCOP SDK).
Feature Description
From a Cordova plugin, we should be able to hook inside Cordova's MainActivity onCreate
. (We can currently inject code in Cordova's Activity but it can't be linked to plugin code afaik).
From my current Cordova knowledge I am unsure how it could be implemented.
Alternatives or Workarounds
I have not found any so far.
As of now it seems that I don't actually need this feature after all (And also my sample code was not really a valid example of why accessing onCreate
could be useful), so I guess this could be closed.
Alright then. In effort to not add things and require to maintain them (it's much more harder to remove features than it is to add them...) we'll close this feature request, especially since no one else expressed interest in this feature.
If things change, don't hesitate to open a new feature request, or comment on this one to reopen it.
I stumbled a case were this feature seemed to be required. The solution is quite simple though (setting onload
in the plugin.xml as explained below). I'm writing it down here in case someone else stumble up this issue like I did.
An SDK is using androidx.lifecycle.LifecycleRegistry
, which require initialization to happen:
- From the main thread.
- Before the activity is started.
When doing the SDK initialization in pluginInitialize
, I was getting:
Method addObserver must be called on the main thread
at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.java:317)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:172)
When running the initialization in a cordova.getActivity().runOnUiThread
block, I get randomly:
MainActivity@bcee696 is attempting to register while current state is RESUMED.
LifecycleOwners must call register before they are STARTED.
Which I guess is because runOnUiThread
might or might not happen before the activity is "started".
Reading through Cordova's code for onCreate
, I found out about the onload
parameter for plugins, which incidentally is documented here: https://cordova.apache.org/docs/en/latest/guide/platforms/android/plugin.html#plugin-initialization-and-lifetime
When onload
is set, the plugin will be loaded during processing f the onCreate
event. Not sure if this is 100% guaranteed to remain the case in the future, but this solves the issue with the current version of cordova-android.
on Android 14 it seems that startActivityForResult has been abandoned and that we must use registerForActivityResult, but that function can only be called in the onCreate, I quote:
Note: You must call registerForActivityResult() before the fragment or activity is created, but you can't launch the ActivityResultLauncher until the fragment or activity's Lifecycle has reached CREATED.
Reopening this because it may be required for https://github.com/apache/cordova-android/issues/1504#issuecomment-1819745585
thanks. I have used the solution suggested by @j3k0 , that is, to use <param name="onload" value="true" />
and the initialize()
callback in the plugin. It has worked! But as he also mentions, if you decide to call plugins initializations out of the onCreate this won't work any longer. It may be better to make this more explicit, for example by simply renaming initialize to onCreate or smth like that.
Besides, for future versions of this platform supporting android 14, the whole startActivtyForResults and onActivityResults should be removed in favour of the new mechanism.
Yah I'd have to refresh my memory on how plugins gets loaded... onload
parameter is used to initialize the plugin immediately which is probably during the onCreate
call... But a plugin that's lazy loaded is only initialized when a plugin API is called I think. Like you said, the plugin initialization is not explicitly declared. If the onload
path does work, it's probably working by accident, or by coincidence.
Edit:
the onload
works because the plugin manager is constructed and initialized during the loadUrl
call done by the app's MainActivity
template and part of the plugin manager init is instantiating all plugins that has the onload
flag.
Edit #2:
It may be better to make this more explicit, for example by simply renaming initialize to onCreate or smth like that.
I don't think we can change the name or anything like that, it would be too much of a breaking change, but I think using onload
flag would be the route to take if you need to do something via onCreate
.
I don't really see a good path of producing an onCreate
hook when the plugin system is intended to be lazy loaded.
I don't really see a good path of producing an onCreate hook when the plugin system is intended to be lazy loaded.
agreed, but as things are now, you would need to either
- make it sure and explicit that the
onload
flag initializes plugins always before the activity is created (forever like that, and documented as such) - or change the current way plugins manage permissions with something that is compatible with the new system.
I am not sure if the plugins interface is something dealt with in this project or elsewhere, but support for the new permissions mechanism needs to be fixed before the following release of cordova-android, if you are planning to support Android 14.