-
Notifications
You must be signed in to change notification settings - Fork 25
Ordering of plugins and the result on the call order
When adding Plugins to an composition object of CompositeAndroid it works the same as adding one layer of inheritance. When adding two Plugins, two layers of inheritance get created.
Here are two plugins added.
public class MainActivity extends CompositeActivity {
public MainActivity() {
addPlugin(new ViewTrackingPlugin("Main"));
addPlugin(new DevOptionsPlugin());
}
}
Spoken in inheritance this means:
class ViewTrackingMainActivity extends MainActivity { ... }
class DevOptionsViewTrackingMainActivity extends ViewTrackingMainActivity { ... }
And this is how the plugins get called. For every method call, the Delegate
calls from the more specialized implementation to the more generic. When the Activity calls onResume()
the following happens:
AppCompatActivity#onResume()
// calls the corresponding delegate to handle the call
ActivityDelegate#onResume()
// gets the latest added plugin (`DevOptionsPlugin`)
// sets a listener to the DevOptionsPlugin to listen for the super call
// calls DevOptionsPlugin#onResume()
DevOptionsPlugin#onResume()
// runs the code inside DevOptionsPlugin#onResume() until super.onResume() gets called
// the default implementation of every method is simply calling super.onResume()
ActivityDelegate#onResume() (inside DevOptionsPlugin super callback)
// got callback from DevOptionsPlugin#onResume() that super got called
// get next plugin (`ViewTrackingPlugin`)
// sets a listener to the DevOptionsPlugin to listen for the super call
// calls ViewTrackingPlugin#onResume()
ViewTrackingPlugin#onResume()
// runs the code inside ViewTrackingPlugin#onResume() until super.onResume() gets called
// super.onResume() is the first line in the method
ActivityDelegate#onResume() (inside ViewTrackingPlugin super callback)
// got callback from ViewTrackingPlugin#onResume() that super got called
// iterated through all plugins.
// Now call AppCompatActivity super#onResume()
// CompositeAndroid generated a method for it called CompostiteActivity#onResume__super()
CompostiteActivity#onResume__super()
// run code of AppCompatActivity super.onResume()
// method finished go back to caller
ActivityDelegate#onResume() (inside ViewTrackingPlugin super callback)
// Method inside of the ViewTrackingPlugin#onResume super listener callback of finished
// go back to caller
ViewTrackingPlugin#onResume()
// super was called
// run code after super call (which is the view tracking)
// method finished go back to caller
ActivityDelegate#onResume() (inside DevOptionsPlugin super callback)
// Method inside of the ViewTrackingPlugin#onResume finished
// go back to caller
DevOptionsPlugin#onResume()
// super was called
// run code after super call (no code because it's the default implementation)
// go back to caller
ActivityDelegate#onResume()
// called all plugins
// go back to caller
AppCompatActivity#onResume()
// runs code after calling the delegate (no code)
// go back to caller which called Activity#onResume() somewhere inside the Android Framework
It's also possible not to call super. This is important for functions like onOptionsItemSelected
. In this Example we add a options item and listen for clicks. When the Developer options item got clicked the method returns true
because the event is handled by starting an activity. In this case super
gets not called.
public class DevOptionsPlugin extends ActivityPlugin {
public static final String DEVELOPER_OPTIONS_TEXT = "Developer options";
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(DEVELOPER_OPTIONS_TEXT);
return true;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (DEVELOPER_OPTIONS_TEXT.equals(item.getTitle())) {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("mycompany://appname/devoptions"));
try {
// note: simply calling startActivity(intent); is not allowed because the call order
// would be different. The code before super.startActivity in this plugin would be executed
// first before a plugin added later and is more specialized.
getActivity().startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getActivity(), "Couldn't open Activity", Toast.LENGTH_SHORT).show();
}
// not calling super!!!
return true;
}
return super.onOptionsItemSelected(item);
}
}
Execution order in detail:
Activity#onOptionsItemSelected(item)
// calls the corresponding delegate to handle the call
ActivityDelegate#onOptionsItemSelected(item)
// gets the latest added plugin (`DevOptionsPlugin`)
// sets a listener to the DevOptionsPlugin to listen for the super call
// calls DevOptionsPlugin#onOptionsItemSelected(item)
DevOptionsPlugin#onOptionsItemSelected(item)
// runs the code inside DevOptionsPlugin#onResume()
// starts an activity and returns true
// not calling super
// method finishes go back to caller
ActivityDelegate#onOptionsItemSelected(item)
// super listener not called. Not calling through the super implementations
// ViewTrackingPlugin#onOptionsItemSelected(item) will *not* be called
// CompositeActivity#onOptionsItemSelected__super(item) will *not* be called
// Activity#onOptionsItemSelected(item) will *not* be called
// go back to caller
Activity#onOptionsItemSelected(item)
// runs code after calling the delegate (no code)
// go back to caller which called Activity#onOptionsItemSelected(item) somewhere inside the Android Framework