Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-15443] Android: Enable proxies to get window/tabgroup activity lifecycle events #6179

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
Expand Down Expand Up @@ -512,6 +513,7 @@ public void onResume(Activity activity)
public void onDestroy(Activity activity) {}
public void onStart(Activity activity) {}
public void onStop(Activity activity) {}
public void onCreate(Activity activity, Bundle savedInstanceState) {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To comply with the updated interface since onCreate was added

});
view.setBuiltInZoomControls(true);
view.setScrollable(true);
Expand Down Expand Up @@ -1123,4 +1125,4 @@ protected boolean allowRegisterForTouch()
// Handled inside the LocalMapView as it is not working in the TiUIView
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import android.app.LocalActivityManager;
import android.content.Intent;
import android.os.Message;
import android.os.Bundle;
import android.view.Window;

@Kroll.proxy(creatableInModule = MapModule.class, propertyAccessors = {
Expand Down Expand Up @@ -113,6 +114,11 @@ public TiUIView createView(Activity activity)
// based on its context;
rootLifecycleListener = new OnLifecycleEvent()
{
@Override
public void onCreate(Activity activity, Bundle savedInstanceState)
{
}

@Override
public void onStop(Activity activity)
{
Expand Down Expand Up @@ -483,6 +489,10 @@ public double getLatitudeDelta()
return mapView.getLatitudeDelta();
}

public void onCreate(Activity activity, Bundle savedInstanceState)
{
}

public void onDestroy(Activity activity)
{
destroyMapActivity();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,6 @@ protected void handlePostOpen()
// Prevent any duplicate events from firing by marking
// this group has having focus.
isFocused = true;

// Setup the new tab activity like setting orientation modes.
onWindowActivityCreated();
}

@Override
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call to onWindowActivityCreated is redundant since it's already called in TiBaseActivity.onCreate for both Windows and TabGroups. That function is not idempotent thus it's a bug.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Bundle;
import android.view.View;
import android.view.ViewParent;

Expand Down Expand Up @@ -855,6 +856,10 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP
}
}

public void onCreate(Activity activity, Bundle savedInstanceState)
{
}

public void onDestroy(Activity activity)
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import ti.modules.titanium.ui.widget.tableview.TiTableView.OnItemLongClickedListener;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.ListView;
Expand Down Expand Up @@ -218,6 +219,7 @@ public void onResume(Activity activity) {
}
}

@Override public void onCreate(Activity activity, Bundle savedInstanceState) {}
@Override public void onStop(Activity activity) {}
@Override public void onStart(Activity activity) {}
@Override public void onPause(Activity activity) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import ti.modules.titanium.ui.widget.tabgroup.TiUIActionBarTab.TabFragment;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar.Tab;
Expand Down Expand Up @@ -329,6 +330,9 @@ public void onTabUnselected(Tab tab, FragmentTransaction ft) {
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}

@Override
public void onCreate(Activity activity, Bundle savedInstanceState) {}

@Override
public void onStart(Activity activity) { }

Expand Down
74 changes: 73 additions & 1 deletion android/titanium/src/java/org/appcelerator/kroll/KrollProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.TiContext;
import org.appcelerator.titanium.proxy.ActivityProxy;
import org.appcelerator.titanium.proxy.TiWindowProxy;
import org.appcelerator.titanium.TiLifecycle.OnLifecycleEvent;
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.util.TiRHelper;
import org.appcelerator.titanium.util.TiUrl;

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import android.util.Pair;

import org.json.JSONObject;
Expand All @@ -42,7 +45,7 @@
* the view object is a proxy itself.
*/
@Kroll.proxy(name = "KrollProxy", propertyAccessors = { KrollProxy.PROPERTY_HAS_JAVA_LISTENER })
public class KrollProxy implements Handler.Callback, KrollProxySupport
public class KrollProxy implements Handler.Callback, KrollProxySupport, OnLifecycleEvent
{
private static final String TAG = "KrollProxy";
private static final int INDEX_NAME = 0;
Expand Down Expand Up @@ -182,6 +185,12 @@ public void setActivity(Activity activity)
this.activity = new WeakReference<Activity>(activity);
}

public void attachActivityLifecycle(Activity activity)
{
setActivity(activity);
((TiBaseActivity) activity).addOnLifecycleEventListener(this);
}

/**
* @return the activity associated with this proxy. It can be null.
* @module.api
Expand Down Expand Up @@ -384,6 +393,21 @@ public void handleCreationDict(KrollDict dict)
if (dict.containsKey(TiC.PROPERTY_BUBBLE_PARENT)) {
bubbleParent = TiConvert.toBoolean(dict, TiC.PROPERTY_BUBBLE_PARENT, true);
}

if (dict.containsKey(TiC.PROPERTY_LIFECYCLE_CONTAINER)) {
KrollProxy lifecycleProxy = (KrollProxy) dict.get(TiC.PROPERTY_LIFECYCLE_CONTAINER);
if (lifecycleProxy instanceof TiWindowProxy) {
ActivityProxy activityProxy = ((TiWindowProxy) lifecycleProxy).getWindowActivityProxy();
if (activityProxy != null) {
attachActivityLifecycle(activityProxy.getActivity());
} else {
((TiWindowProxy) lifecycleProxy).addProxyWaitingForActivity(this);
}
} else {
Log.e(TAG, TiC.PROPERTY_LIFECYCLE_CONTAINER + " must be a WindowProxy or TabGroupProxy (TiWindowProxy)");
}
}

properties.putAll(dict);
handleDefaultValues();
handleLocaleProperties();
Expand Down Expand Up @@ -1306,5 +1330,53 @@ public String getApiName()
{
return "Ti.Proxy";
}

/**
* A place holder for subclasses to extend. Its purpose is to receive native Android onCreate life cycle events.
* @param activity the activity attached to this module.
* @module.api
*/
public void onCreate(Activity activity, Bundle savedInstanceState) {
}

/**
* A place holder for subclasses to extend. Its purpose is to receive native Android onResume life cycle events.
* @param activity the activity attached to this module.
* @module.api
*/
public void onResume(Activity activity) {
}

/**
* A place holder for subclasses to extend. Its purpose is to receive native Android onPause life cycle events.
* @param activity the activity attached to this module.
* @module.api
*/
public void onPause(Activity activity) {
}

/**
* A place holder for subclasses to extend. Its purpose is to receive native Android onDestroy life cycle events.
* @param activity the activity attached to this module.
* @module.api
*/
public void onDestroy(Activity activity) {
}

/**
* A place holder for subclasses to extend. Its purpose is to receive native Android onStart life cycle events.
* @param activity the activity attached to this module.
* @module.api
*/
public void onStart(Activity activity) {
}

/**
* A place holder for subclasses to extend. Its purpose is to receive native Android onStop life cycle events.
* @param activity the activity attached to this module.
* @module.api
*/
public void onStop(Activity activity) {
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
import org.appcelerator.titanium.TiLifecycle.OnLifecycleEvent;
import org.appcelerator.titanium.TiLifecycle.OnWindowFocusChangedEvent;
import org.appcelerator.titanium.TiLifecycle.interceptOnBackPressedEvent;
import org.appcelerator.titanium.TiLifecycle.onActivityResultEvent;
import org.appcelerator.titanium.TiLifecycle.OnInstanceStateEvent;
import org.appcelerator.titanium.TiLifecycle.OnCreateOptionsMenuEvent;
import org.appcelerator.titanium.TiLifecycle.OnPrepareOptionsMenuEvent;
import org.appcelerator.titanium.proxy.ActionBarProxy;
import org.appcelerator.titanium.proxy.ActivityProxy;
import org.appcelerator.titanium.proxy.IntentProxy;
Expand Down Expand Up @@ -75,6 +79,10 @@ public abstract class TiBaseActivity extends ActionBarActivity
private TiWeakList<OnLifecycleEvent> lifecycleListeners = new TiWeakList<OnLifecycleEvent>();
private TiWeakList<OnWindowFocusChangedEvent> windowFocusChangedListeners = new TiWeakList<OnWindowFocusChangedEvent>();
private TiWeakList<interceptOnBackPressedEvent> interceptOnBackPressedListeners = new TiWeakList<interceptOnBackPressedEvent>();
private TiWeakList<OnInstanceStateEvent> instanceStateListeners = new TiWeakList<OnInstanceStateEvent>();
private TiWeakList<onActivityResultEvent> onActivityResultListeners = new TiWeakList<onActivityResultEvent>();
private TiWeakList<OnCreateOptionsMenuEvent> onCreateOptionsMenuListeners = new TiWeakList<OnCreateOptionsMenuEvent>();
private TiWeakList<OnPrepareOptionsMenuEvent> onPrepareOptionsMenuListeners = new TiWeakList<OnPrepareOptionsMenuEvent>();
private APSAnalytics analytics = APSAnalytics.getInstance();

protected View layout;
Expand Down Expand Up @@ -548,6 +556,16 @@ protected void onCreate(Bundle savedInstanceState)
if (window != null) {
window.onWindowActivityCreated();
}
synchronized (lifecycleListeners.synchronizedList()) {
for (OnLifecycleEvent listener : lifecycleListeners.nonNull()) {
try {
TiLifecycle.fireLifecycleEvent(this, listener, savedInstanceState, TiLifecycle.LIFECYCLE_ON_CREATE);

} catch (Throwable t) {
Log.e(TAG, "Error dispatching lifecycle event: " + t.getMessage(), t);
}
}
}
}

public int getOriginalOrientationMode()
Expand Down Expand Up @@ -629,6 +647,15 @@ public void launchIntentSenderForResult(IntentSender intent, int requestCode, In
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
synchronized (onActivityResultListeners.synchronizedList()) {
for (onActivityResultEvent listener : onActivityResultListeners.nonNull()) {
try {
TiLifecycle.fireOnActivityResultEvent(this, listener, requestCode, resultCode, data);
} catch (Throwable t) {
Log.e(TAG, "Error dispatching onActivityResult event: " + t.getMessage(), t);
}
}
}
getSupportHelper().onActivityResult(requestCode, resultCode, data);
}

Expand Down Expand Up @@ -805,11 +832,23 @@ public boolean onCreateOptionsMenu(Menu menu)
return false;
}

boolean listenerExists = false;
synchronized (onCreateOptionsMenuListeners.synchronizedList()) {
for (OnCreateOptionsMenuEvent listener : onCreateOptionsMenuListeners.nonNull()) {
try {
listenerExists = true;
TiLifecycle.fireOnCreateOptionsMenuEvent(this, listener, menu);
} catch (Throwable t) {
Log.e(TAG, "Error dispatching OnCreateOptionsMenuEvent: " + t.getMessage(), t);
}
}
}

if (menuHelper == null) {
menuHelper = new TiMenuSupport(activityProxy);
}

return menuHelper.onCreateOptionsMenu(super.onCreateOptionsMenu(menu), menu);
return menuHelper.onCreateOptionsMenu(super.onCreateOptionsMenu(menu) || listenerExists, menu);
}

@Override
Expand Down Expand Up @@ -838,7 +877,18 @@ public boolean onOptionsItemSelected(MenuItem item)
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
return menuHelper.onPrepareOptionsMenu(super.onPrepareOptionsMenu(menu), menu);
boolean listenerExists = false;
synchronized (onPrepareOptionsMenuListeners.synchronizedList()) {
for (OnPrepareOptionsMenuEvent listener : onPrepareOptionsMenuListeners.nonNull()) {
try {
listenerExists = true;
TiLifecycle.fireOnPrepareOptionsMenuEvent(this, listener, menu);
} catch (Throwable t) {
Log.e(TAG, "Error dispatching OnPrepareOptionsMenuEvent: " + t.getMessage(), t);
}
}
}
return menuHelper.onPrepareOptionsMenu(super.onPrepareOptionsMenu(menu) || listenerExists, menu);
}

public static void callOrientationChangedListener(Configuration newConfig)
Expand Down Expand Up @@ -885,6 +935,11 @@ public void addOnLifecycleEventListener(OnLifecycleEvent listener)
lifecycleListeners.add(new WeakReference<OnLifecycleEvent>(listener));
}

public void addOnInstanceStateEventListener(OnInstanceStateEvent listener)
{
instanceStateListeners.add(new WeakReference<OnInstanceStateEvent>(listener));
}

public void addOnWindowFocusChangedEventListener(OnWindowFocusChangedEvent listener)
{
windowFocusChangedListeners.add(new WeakReference<OnWindowFocusChangedEvent>(listener));
Expand All @@ -895,6 +950,21 @@ public void addInterceptOnBackPressedEventListener(interceptOnBackPressedEvent l
interceptOnBackPressedListeners.add(new WeakReference<interceptOnBackPressedEvent>(listener));
}

public void addOnActivityResultListener(onActivityResultEvent listener)
{
onActivityResultListeners.add(new WeakReference<onActivityResultEvent>(listener));
}

public void addOnCreateOptionsMenuEventListener(OnCreateOptionsMenuEvent listener)
{
onCreateOptionsMenuListeners.add(new WeakReference<OnCreateOptionsMenuEvent>(listener));
}

public void addOnPrepareOptionsMenuEventListener(OnPrepareOptionsMenuEvent listener)
{
onPrepareOptionsMenuListeners.add(new WeakReference<OnPrepareOptionsMenuEvent>(listener));
}

public void removeOnLifecycleEventListener(OnLifecycleEvent listener)
{
// TODO stub
Expand Down Expand Up @@ -1317,6 +1387,16 @@ protected void onSaveInstanceState(Bundle outState)
if (!isFinishing() && supportHelper != null) {
outState.putInt("supportHelperId", supportHelperId);
}

synchronized (instanceStateListeners.synchronizedList()) {
for (OnInstanceStateEvent listener : instanceStateListeners.nonNull()) {
try {
TiLifecycle.fireInstanceStateEvent(outState, listener, TiLifecycle.ON_SAVE_INSTANCE_STATE);
} catch (Throwable t) {
Log.e(TAG, "Error dispatching OnInstanceStateEvent: " + t.getMessage(), t);
}
}
}
}

@Override
Expand All @@ -1331,6 +1411,16 @@ protected void onRestoreInstanceState(Bundle savedInstanceState)
Log.e(TAG, "Unable to retrieve the activity support helper.");
}
}

synchronized (instanceStateListeners.synchronizedList()) {
for (OnInstanceStateEvent listener : instanceStateListeners.nonNull()) {
try {
TiLifecycle.fireInstanceStateEvent(savedInstanceState, listener, TiLifecycle.ON_RESTORE_INSTANCE_STATE);
} catch (Throwable t) {
Log.e(TAG, "Error dispatching OnInstanceStateEvent: " + t.getMessage(), t);
}
}
}
}

// called in order to ensure that the onDestroy call is only acted upon once.
Expand Down