Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Welcome, Guest. Please login or register.
July 21, 2017, 05:46:25 PM
Home Help Search Login Register
News: Please DM @puremvc on Twitter to gain forum access. Spambots are why we can't have nice things.
Pages: [1]
Print
Author Topic: Android: Activity Management in PureMVC  (Read 8865 times)
mikebritton
Full Member
***
Posts: 42


View Profile Email
« on: April 06, 2011, 12:58:24 PM »

I may be barking up the wrong tree again, but it seems like managing views (Activities) from inside other Activities is bad.  How do I know which Activity is changing the page with an Intent?

Just for the hell of it, I implemented it in a Command.  Now I don't have to wonder which Activity did what; it's all centralized.  Granted it will have to have a case for each page in the application, but I see less scalability issues than with dispatching Intents inside Activities that should have no knowledge or control of them, in theory.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2870



View Profile WWW
« Reply #1 on: April 06, 2011, 02:40:35 PM »

Quote
it seems like managing views (Activities) from inside other Activities is bad
In Flex, it's common to have a relatively complex component that encapsulates the control of some of its children. Events can bubble up from those children and the container component and be handled by a single Mediator. If you need to determine who dispatched the Event you inspect the reference in the event target property. Thus Mediator to component granularity is not always 1 to 1, and it's OK to have compound components with the outermost containers controlling the inner ones.

However, being an Android outsider still, what I don't know is if Android Activities map to Flex Components closely enough for the above to be true. Can you have one Activity inside another? Also, I've not yet gotten the difference between Intents and Events (presumably one is you can't tell where an Intent came from).

-=Cliff>
PS: If I can't give a canonical answer here, at least I can throw some wood on the fire Smiley
Logged
Tekool
Sr. Member
****
Posts: 192


View Profile WWW
« Reply #2 on: April 07, 2011, 12:56:08 AM »

Mike as said in a previous post my choice was to use multicore because it uses the same paradigm as Android with Activities, one must not know each other.

Quote from: mikebritton
How do I know which Activity is changing the page with an Intent?

I investigated a little in this way when working on my demo app and if I remember well discovered some methods that can check if an Activity exists and methods on it to check if it is "displayed". A timer hidden in a thread can check if the Activity is paused meaning it's in background so not displayed.

Be careful when using intent that wait for a result the same Activity is automatically created multiple times without you even know it because Android consider it must not be closed before returning a result.
Logged
mikebritton
Full Member
***
Posts: 42


View Profile Email
« Reply #3 on: April 07, 2011, 03:05:47 PM »

I was playing around with centralizing Activity management in a Command.  Again, not sure if this is best practice but "it works"  Undecided.

Button is pressed on an Activity (handler below):

Code:
private void initDisplay() {
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
observable.setChanged();

//  Custom event is assigned a page vo
InteractionEvent evt = new InteractionEvent(this);
PageChangeVO vo = new PageChangeVO();

// page vo's newPageName variable is set
vo.newPageName = ActivityNames.SUB_PAGE;
evt.pageVO = vo;

observable.notifyObservers( evt );
observable.clearChanged();
}
});
}

Observer (Mediator) receives update from its Activity and sets the activity variable on the VO:

Code:
@Override
public void update(Observable arg0, Object arg1) {
Log.d(TAG, "UPDATE");
InteractionEvent evt = (InteractionEvent) arg1;
evt.pageVO.activity = this.getApplication();

this.sendNotification(NotificationNames.CHANGE_PAGE, evt);
}

ChangePageCommand is executed:

Code:
@Override
public void execute(INotification notification) {
super.execute(notification);

Log.d(TAG, TAG+"::execute");

String mediatorName;
InteractionEvent evt = (InteractionEvent) notification.getBody();
Activity act = (Activity) evt.pageVO.activity;
Activity newAct;
Mediator newMediator = null;
Intent intent = null;

// Remove the Mediator of the Activity doing the page change

if (act.getClass().getName().equalsIgnoreCase(ActivityNames.APPLICATION) ) {
mediatorName = MediatorNames.APPLICATION_ACTIVITY;
if (getFacade().hasMediator(MediatorNames.APPLICATION_ACTIVITY)) {
getFacade().removeMediator(MediatorNames.APPLICATION_ACTIVITY);
}
}

if (act.getClass().getName().equalsIgnoreCase(ActivityNames.SUB_PAGE) ) {
mediatorName = MediatorNames.SUB_PAGE_ACTIVITY;
if (getFacade().hasMediator(MediatorNames.SUB_PAGE_ACTIVITY)) {
getFacade().removeMediator(MediatorNames.SUB_PAGE_ACTIVITY);
}
}

// Instantiate the new Activity

if (evt.pageVO.newPageName == ActivityNames.APPLICATION) {
newAct = new ApplicationActivity();
newMediator = new ApplicationMediator(MediatorNames.APPLICATION_ACTIVITY, (ApplicationActivity)newAct);
intent = new Intent(act, ApplicationActivity.class);
}

if (evt.pageVO.newPageName == ActivityNames.SUB_PAGE) {
newAct = new SubPageActivity();
newMediator = new SubPageMediator(MediatorNames.SUB_PAGE_ACTIVITY, (SubPageActivity)newAct);
intent = new Intent(act, SubPageActivity.class);
}

getFacade().registerMediator(newMediator);

act.startActivity(intent);

act.finish();
}

Again, just playing around.  Thoughts?


Mike


Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2870



View Profile WWW
« Reply #4 on: April 07, 2011, 06:15:06 PM »

Code:
// Remove the Mediator of the Activity doing the page change
I would've had the Mediator that sent the notification remove itself immediately after sending the note, but I don't follow the sub page stuff.

-=Cliff>
Logged
mikebritton
Full Member
***
Posts: 42


View Profile Email
« Reply #5 on: April 08, 2011, 01:01:04 PM »

A value object contains the name of the next page.  A new Activity (coincidentally named "SubPage") is instantiated and replaces the old one (the page changes).
Logged
jason
Jr. Member
**
Posts: 13


View Profile
« Reply #6 on: July 13, 2011, 09:59:34 PM »

I've been experimenting a lot lately with this,
so far I have my facade hanging from the androidApplication,
I have proxies connected via a broadcast receiver locally instantiated in my proxy class, to services running in other processes. I tried variously to use the aidl mechanism but it was not reliable from the applicationcontext.
i have mediators(POJO's) that either call startActivity or PendingIntent.send. When an Activity is started the Activity creates
an Observable, then does a lookup from the facade for the current mediator instance and sets itself as the view. it also creates a Pendingintent and hands it to the Mediator.

because the Mediator is not an activity and does not have an Activity context, each time startActivity is called, a new copy of the Activity is created. So the pending intent reduces this pain somewhat. if its not null, then its used to callback to the existing activity directly.

I'm now experimenting with roboguice for context injection instead of directly accessing the ApplicationSingleton. I dont like all the annotations and total incursion of roboguice in my code, but I'm not aware of any other DI options, and roboguice can simplify context management quite a bit. I'm also considering basing my mvcApplication in a service instead of the applicationContext itself, since binding from a service context seems more reliable and more Androidy.
I'm currently toying with injecting the roboguice ActivityProvider directly into my mediator, as this could finally provide a reliable communication mechanism between the mediator and view that does not demand endless recreation of the Activity. Lets see how well it works in practice.
Next step is to get jbpm5 working, I've seen one post online and apparently it only needs a minor tweak to run in android.




Logged
Pages: [1]
Print
Jump to: