public Object callSync(KrollObject krollObject, Object[] args) { if (!KrollRuntime.isInitialized()) { Log.w(TAG, "Runtime disposed, cannot call function."); return null; } return nativeInvoke(((V8Object) krollObject).getPointer(), getPointer(), args); }
@Override /** * When this activity stops, this method fires the javascript 'blur' and 'stop' events. Blur * events will only fire if the activity is not a tab activity. */ protected void onStop() { inForeground = false; super.onStop(); Log.d(TAG, "Activity " + this + " onStop", Log.DEBUG_MODE); if (getTiApp().isRestartPending()) { if (!isFinishing()) { finish(); } return; } if (activityProxy != null) { activityProxy.fireSyncEvent(TiC.EVENT_STOP, null); } synchronized (lifecycleListeners.synchronizedList()) { for (OnLifecycleEvent listener : lifecycleListeners.nonNull()) { try { TiLifecycle.fireLifecycleEvent(this, listener, TiLifecycle.LIFECYCLE_ON_STOP); } catch (Throwable t) { Log.e(TAG, "Error dispatching lifecycle event: " + t.getMessage(), t); } } } KrollRuntime.suggestGC(); }
public Object call(KrollObject krollObject, Object[] args) { if (KrollRuntime.getInstance().isRuntimeThread()) { return callSync(krollObject, args); } else { return TiMessenger.sendBlockingRuntimeMessage( handler.obtainMessage(MSG_CALL_SYNC), new FunctionArgs(krollObject, args)); } }
/** * Called by the onCreate methods of TiBaseActivity to determine if an unsupported application * re-launch appears to be occurring. * * @param activity The Activity getting the onCreate * @param savedInstanceState The argument passed to the onCreate. A non-null value is a "tell" * that the system is re-starting a killed application. */ public static boolean isUnsupportedReLaunch(Activity activity, Bundle savedInstanceState) { // If all the activities has been killed and the runtime has been disposed, we have to relaunch // the app. if (KrollRuntime.getInstance().getRuntimeState() == KrollRuntime.State.DISPOSED && savedInstanceState != null && !(activity instanceof TiLaunchActivity)) { return true; } return false; }
@Override public void doRelease() { long functionPointer = getPointer(); if (functionPointer == 0) { return; } nativeRelease(functionPointer); KrollRuntime.suggestGC(); }
public void releaseViews() { if (view != null) { if (children != null) { for (TiViewProxy p : children) { p.releaseViews(); } } view.release(); view = null; } setModelListener(null); KrollRuntime.suggestGC(); }
private void invokeCallback( TiBaseActivity callbackActivity, KrollFunction callback, KrollObject krollObject, KrollDict callbackArgs) { if (KrollRuntime.getInstance().isRuntimeThread()) { doInvokeCallback(callbackActivity, callback, krollObject, callbackArgs); } else { CallbackWrapper callbackWrapper = new CallbackWrapper(callbackActivity, callback, krollObject, callbackArgs); Message message = getRuntimeHandler().obtainMessage(MSG_INVOKE_CALLBACK, callbackWrapper); message.sendToTarget(); } }
protected TiMessenger initialValue() { if (Looper.myLooper() == null) { synchronized (threadLocalMessenger) { if (Looper.myLooper() == null) { Looper.prepare(); } } } TiMessenger messenger = new TiMessenger(); long currentThreadId = Thread.currentThread().getId(); if (currentThreadId == Looper.getMainLooper().getThread().getId()) { mainMessenger = messenger; } else if (currentThreadId == KrollRuntime.getInstance().getThreadId()) { runtimeMessenger = messenger; } return messenger; }
@Override /** * When the activity is created, this method adds it to the activity stack and fires a javascript * 'create' event. * * @param savedInstanceState Bundle of saved data. */ protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "Activity " + this + " onCreate", Log.DEBUG_MODE); inForeground = true; TiApplication tiApp = getTiApp(); if (tiApp.isRestartPending()) { super.onCreate(savedInstanceState); if (!isFinishing()) { finish(); } return; } // If all the activities has been killed and the runtime has been disposed, we cannot recover // one // specific activity because the info of the top-most view proxy has been lost // (TiActivityWindows.dispose()). // In this case, we have to restart the app. if (TiBaseActivity.isUnsupportedReLaunch(this, savedInstanceState)) { Log.w(TAG, "Runtime has been disposed. Finishing."); super.onCreate(savedInstanceState); tiApp.scheduleRestart(250); finish(); return; } TiApplication.addToActivityStack(this); // create the activity proxy here so that it is accessible from the activity in all cases activityProxy = new ActivityProxy(this); // Increment the reference count so we correctly clean up when all of our activities have been // destroyed KrollRuntime.incrementActivityRefCount(); Intent intent = getIntent(); if (intent != null) { if (intent.hasExtra(TiC.INTENT_PROPERTY_MESSENGER)) { messenger = (Messenger) intent.getParcelableExtra(TiC.INTENT_PROPERTY_MESSENGER); msgActivityCreatedId = intent.getIntExtra(TiC.INTENT_PROPERTY_MSG_ACTIVITY_CREATED_ID, -1); msgId = intent.getIntExtra(TiC.INTENT_PROPERTY_MSG_ID, -1); } if (intent.hasExtra(TiC.PROPERTY_WINDOW_PIXEL_FORMAT)) { getWindow() .setFormat(intent.getIntExtra(TiC.PROPERTY_WINDOW_PIXEL_FORMAT, PixelFormat.UNKNOWN)); } } // Doing this on every create in case the activity is externally created. TiPlatformHelper.intializeDisplayMetrics(this); if (layout == null) { layout = createLayout(); } if (intent != null && intent.hasExtra(TiC.PROPERTY_KEEP_SCREEN_ON)) { layout.setKeepScreenOn( intent.getBooleanExtra(TiC.PROPERTY_KEEP_SCREEN_ON, layout.getKeepScreenOn())); } super.onCreate(savedInstanceState); // we only want to set the current activity for good in the resume state but we need it right // now. // save off the existing current activity, set ourselves to be the new current activity // temporarily // so we don't run into problems when we give the proxy the event Activity tempCurrentActivity = tiApp.getCurrentActivity(); tiApp.setCurrentActivity(this, this); windowCreated(); if (activityProxy != null) { // Fire the sync event with a timeout, so the main thread won't be blocked too long to get an // ANR. (TIMOB-13253) activityProxy.fireSyncEvent(TiC.EVENT_CREATE, null, 4000); } // set the current activity back to what it was originally tiApp.setCurrentActivity(this, tempCurrentActivity); setContentView(layout); sendMessage(msgActivityCreatedId); // for backwards compatibility sendMessage(msgId); // store off the original orientation for the activity set in the AndroidManifest.xml // for later use originalOrientationMode = getRequestedOrientation(); if (window != null) { window.onWindowActivityCreated(); } }
@Override /** * When this activity is destroyed, this method removes it from the activity stack, performs clean * up, and fires javascript 'destroy' event. */ protected void onDestroy() { Log.d(TAG, "Activity " + this + " onDestroy", Log.DEBUG_MODE); inForeground = false; TiApplication tiApp = getTiApp(); // Clean up dialogs when activity is destroyed. releaseDialogs(true); if (tiApp.isRestartPending()) { super.onDestroy(); if (!isFinishing()) { finish(); } return; } synchronized (lifecycleListeners.synchronizedList()) { for (OnLifecycleEvent listener : lifecycleListeners.nonNull()) { try { TiLifecycle.fireLifecycleEvent(this, listener, TiLifecycle.LIFECYCLE_ON_DESTROY); } catch (Throwable t) { Log.e(TAG, "Error dispatching lifecycle event: " + t.getMessage(), t); } } } super.onDestroy(); boolean isFinishing = isFinishing(); // If the activity is finishing, remove the windowId and supportHelperId so the window and // supportHelper can be released. // If the activity is forced to destroy by Android OS, keep the windowId and supportHelperId so // the activity can be recovered. if (isFinishing) { int windowId = getIntentInt(TiC.INTENT_PROPERTY_WINDOW_ID, -1); TiActivityWindows.removeWindow(windowId); TiActivitySupportHelpers.removeSupportHelper(supportHelperId); } fireOnDestroy(); if (layout instanceof TiCompositeLayout) { Log.e(TAG, "Layout cleanup.", Log.DEBUG_MODE); ((TiCompositeLayout) layout).removeAllViews(); } layout = null; // LW windows if (window == null && view != null) { view.releaseViews(); view = null; } if (window != null) { window.closeFromActivity(isFinishing); window = null; } if (menuHelper != null) { menuHelper.destroy(); menuHelper = null; } if (activityProxy != null) { activityProxy.release(); activityProxy = null; } // Don't dispose the runtime if the activity is forced to destroy by Android, // so we can recover the activity later. KrollRuntime.decrementActivityRefCount(isFinishing); KrollRuntime.suggestGC(); }