UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

301 lines • 13.3 kB
import { Frame } from '..'; import { Application } from '../../../application'; import { Trace } from '../../../trace'; import { profile } from '../../../profiling'; import { isEmbedded, setEmbeddedView } from '../../embedding'; const activityRootViewsMap = new Map(); const INTENT_EXTRA = 'com.tns.activity'; const ROOT_VIEW_ID_EXTRA = 'com.tns.activity.rootViewId'; export let moduleLoaded; export class ActivityCallbacksImplementation { getRootView() { return this._rootView; } onCreate(activity, savedInstanceState, intentOrSuperFunc, superFunc) { if (Trace.isEnabled()) { Trace.write(`Activity.onCreate(${savedInstanceState})`, Trace.categories.NativeLifecycle); } const intent = superFunc ? intentOrSuperFunc : undefined; if (!superFunc) { console.log('AndroidActivityCallbacks.onCreate(activity: any, savedInstanceState: any, superFunc: Function) ' + 'is deprecated. Use AndroidActivityCallbacks.onCreate(activity: any, savedInstanceState: any, intent: any, superFunc: Function) instead.'); superFunc = intentOrSuperFunc; } // If there is savedInstanceState this call will recreate all fragments that were previously in the navigation. // We take care of associating them with a Page from our backstack in the onAttachFragment callback. // If there is savedInstanceState and moduleLoaded is false we are restarted but process was killed. // For now we treat it like first run (e.g. we are not passing savedInstanceState so no fragments are being restored). // When we add support for application save/load state - revise this logic. const isRestart = !!savedInstanceState && moduleLoaded; superFunc.call(activity, isRestart ? savedInstanceState : null); // Try to get the rootViewId form the saved state in case the activity // was destroyed and we are now recreating it. if (savedInstanceState) { const rootViewId = savedInstanceState.getInt(ROOT_VIEW_ID_EXTRA, -1); if (rootViewId !== -1 && activityRootViewsMap.has(rootViewId)) { this._rootView = activityRootViewsMap.get(rootViewId)?.get(); } } if (intent && intent.getAction()) { Application.android.notify({ eventName: Application.AndroidApplication.activityNewIntentEvent, object: Application.android, activity, intent, }); } this.setActivityContent(activity, savedInstanceState, true); moduleLoaded = true; } onSaveInstanceState(activity, outState, superFunc) { superFunc.call(activity, outState); const rootView = this._rootView; if (rootView instanceof Frame) { outState.putInt(INTENT_EXTRA, rootView.android.frameId); rootView._saveFragmentsState(); } if (rootView) { outState.putInt(ROOT_VIEW_ID_EXTRA, rootView._domId); } } onNewIntent(activity, intent, superSetIntentFunc, superFunc) { superFunc.call(activity, intent); superSetIntentFunc.call(activity, intent); Application.android.notify({ eventName: Application.AndroidApplication.activityNewIntentEvent, object: Application.android, activity, intent, }); } onStart(activity, superFunc) { superFunc.call(activity); if (Trace.isEnabled()) { Trace.write('NativeScriptActivity.onStart();', Trace.categories.NativeLifecycle); } const rootView = this._rootView; if (rootView && !rootView.isLoaded && !isEmbedded()) { rootView.callLoaded(); } } onStop(activity, superFunc) { superFunc.call(activity); if (Trace.isEnabled()) { Trace.write('NativeScriptActivity.onStop();', Trace.categories.NativeLifecycle); } const rootView = this._rootView; if (rootView && rootView.isLoaded && !isEmbedded()) { rootView.callUnloaded(); } } onPostResume(activity, superFunc) { superFunc.call(activity); if (Trace.isEnabled()) { Trace.write('NativeScriptActivity.onPostResume();', Trace.categories.NativeLifecycle); } // NOTE: activity.onPostResume() is called when activity resume is complete and we can // safely raise the application resume event; // onActivityResumed(...) lifecycle callback registered in application is called too early // and raising the application resume event there causes issues like // https://github.com/NativeScript/NativeScript/issues/6708 if (activity.isNativeScriptActivity) { Application.setSuspended(false, { // todo: deprecate in favor of using event.activity instead. android: activity, activity, }); } } onDestroy(activity, superFunc) { try { if (Trace.isEnabled()) { Trace.write('NativeScriptActivity.onDestroy();', Trace.categories.NativeLifecycle); } const rootView = this._rootView; if (rootView) { rootView._tearDownUI(true); } // this may happen when the user changes the system theme // In such case, isFinishing() is false (and isChangingConfigurations is true), and the app will start again (onCreate) with a savedInstanceState // as a result, launchEvent will never be called // possible alternative: always fire launchEvent and exitEvent, but pass extra flags to make it clear what kind of launch/destroy is happening if (activity.isFinishing()) { const exitArgs = { eventName: Application.exitEvent, object: Application.android, android: activity, }; Application.notify(exitArgs); } } finally { superFunc.call(activity); } } onBackPressed(activity, superFunc) { if (Trace.isEnabled()) { Trace.write('NativeScriptActivity.onBackPressed;', Trace.categories.NativeLifecycle); } const args = { eventName: 'activityBackPressed', object: Application, android: Application.android, activity: activity, cancel: false, }; Application.android.notify(args); if (args.cancel) { return; } const view = this._rootView; let callSuper = false; const viewArgs = { eventName: 'activityBackPressed', object: view, activity: activity, cancel: false, }; view.notify(viewArgs); // In the case of Frame, use this callback only if it was overridden, since the original will cause navigation issues if (!viewArgs.cancel && (view.onBackPressed === Frame.prototype.onBackPressed || !view.onBackPressed())) { callSuper = view instanceof Frame ? !Frame.goBack() : true; } if (callSuper) { superFunc.call(activity); } } onRequestPermissionsResult(activity, requestCode, permissions, grantResults, superFunc) { if (Trace.isEnabled()) { Trace.write('NativeScriptActivity.onRequestPermissionsResult;', Trace.categories.NativeLifecycle); } Application.android.notify({ eventName: 'activityRequestPermissions', object: Application, android: Application.android, activity: activity, requestCode: requestCode, permissions: permissions, grantResults: grantResults, }); } onActivityResult(activity, requestCode, resultCode, data, superFunc) { superFunc.call(activity, requestCode, resultCode, data); if (Trace.isEnabled()) { Trace.write(`NativeScriptActivity.onActivityResult(${requestCode}, ${resultCode}, ${data})`, Trace.categories.NativeLifecycle); } Application.android.notify({ eventName: 'activityResult', object: Application, android: Application.android, activity: activity, requestCode: requestCode, resultCode: resultCode, intent: data, }); } resetActivityContent(activity) { if (this._rootView) { const manager = this._rootView._getFragmentManager(); manager.executePendingTransactions(); this._rootView._onRootViewReset(); } // Delete previously cached root view in order to recreate it. this._rootView = null; this.setActivityContent(activity, null, false); this._rootView.callLoaded(); } // Paths that go trough this method: // 1. Application initial start - there is no rootView in callbacks. // 2. Application revived after Activity is destroyed. this._rootView should have been restored by id in onCreate. // 3. Livesync if rootView has no custom _onLivesync. this._rootView should have been cleared upfront. Launch event should not fired // 4. resetRootView method. this._rootView should have been cleared upfront. Launch event should not fired setActivityContent(activity, savedInstanceState, fireLaunchEvent) { let rootView = this._rootView; if (Trace.isEnabled()) { Trace.write(`Frame.setActivityContent rootView: ${rootView} shouldCreateRootFrame: false fireLaunchEvent: ${fireLaunchEvent}`, Trace.categories.NativeLifecycle); } const intent = activity.getIntent(); rootView = Application.createRootView(rootView, fireLaunchEvent, { // todo: deprecate in favor of args.intent? android: intent, intent, savedInstanceState, }); if (!rootView) { // no root view created return; } activityRootViewsMap.set(rootView._domId, new WeakRef(rootView)); // setup view as styleScopeHost rootView._setupAsRootView(activity); if (isEmbedded()) { setEmbeddedView(rootView); } else { activity.setContentView(rootView.nativeViewProtected, new org.nativescript.widgets.CommonLayoutParams()); } this._rootView = rootView; // sets root classes once rootView is ready... Application.initRootView(rootView); } } __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [androidx.appcompat.app.AppCompatActivity, android.os.Bundle, Object, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onCreate", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [androidx.appcompat.app.AppCompatActivity, android.os.Bundle, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onSaveInstanceState", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [androidx.appcompat.app.AppCompatActivity, android.content.Intent, Function, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onNewIntent", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onStart", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onStop", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onPostResume", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onDestroy", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onBackPressed", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Number, Array, Array, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onRequestPermissionsResult", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Number, Number, android.content.Intent, Function]), __metadata("design:returntype", void 0) ], ActivityCallbacksImplementation.prototype, "onActivityResult", null); //# sourceMappingURL=activity-callbacks.js.map