@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
JavaScript
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