This is a practice when you want to execute different processing groups serially, not limited to Android.
Processing is handled by the concept of Event, and processing is executed through a manager class that executes Events sequentially. Please get the source code from GitHub. https://github.com/ken-maki/k_commons.eventChain
The configuration is as follows.
com.android.k.commons.eventchain ┣lib ┃┣EventChainManager ┃┃ A manager class that executes Events sequentially, a method that interrupts when the processing result of Event fails, and ┃┃ It has a method to execute all Events regardless of the processing result of Event. ┃┣EventChaining ┃┃ Interface for implementing Event. ┣events ┃┣EventFoo ┃┃ Just display the sample event and toast. ┃┣EventBar ┃ ┃ Sample Event, toast display and Event result is returned as false (processing failure). ┃┗EventBaz ┃ Just display the sample event and toast. ┗MainActivity Event Sample Activity to execute.
EventChainManager.java
public class EventChainManager {
List<Pair<EventChaining, Boolean>> mEvents = new ArrayList<Pair<EventChaining, Boolean>>();
/**
* add event.
* <p>
* added event is serial executed.if event failed, break execute.
* </p>
*
* @param event executable event
* @return this EventChainManager instance
*/
public EventChainManager chain(final EventChaining event) {
mEvents.add(Pair.create(event, false));
return this;
}
/**
* add event.
* <p>
* added event is serial executed.if event failed, forward next event.
* </p>
*
* @param event executable event
* @return this EventChainManager instance
*/
public EventChainManager chainForce(final EventChaining event) {
mEvents.add(Pair.create(event, true));
return this;
}
/**
* execute chain events.
* <p>
* delete the event after execution
* </p>
*
* @return returns true if it event all succeeds.
*/
public boolean execute() {
boolean result = executeAndLeave();
removeAll();
return result;
}
/**
* execute chain events.
* <p>
* leave the event after execution
* </p>
*
* @return returns true if it event all succeeds.
*/
public boolean executeAndLeave() {
for (Pair<EventChaining, Boolean> event : mEvents) {
EventChaining chainEvent = event.first;
boolean isForced = event.second;
if (!chainEvent.action() && !isForced) {
return false;
}
}
return true;
}
/**
* remove all added Event.
*
* @param event event to removed
*/
public void remove(final EventChaining event) {
mEvents.remove(event);
}
/**
* remove all added Events.
*/
public void removeAll() {
mEvents.clear();
}
}
A class that executes an Event. There are two methods to add an Event. ・ Chain method If the Event processing result is false (failure), use it when you want to stop the processing there. ・ ChainForce method Used when you want to continue processing regardless of the success or failure of Event processing. After that, start the sequential processing of Events with the execute method. When you want to keep the added Event as it is (when you want to process it again later) after the sequential processing of Events is completed Use the executeAndLeave method.
EventChaining.java
public interface EventChaining {
/**
* execute an event.
*
* @return returns true if it event succeeds.
*/
boolean action();
}
A small class, an interface for implementing Events. Write the implementation of Event in the action method. The success or failure of Event processing is returned as boolean.
EventFoo.java
public class EventFoo implements EventChaining {
Context mContext;
public EventFoo(final Context context) {
mContext = context;
}
@Override
public boolean action() {
Toast.makeText(mContext, "EventFoo executed.", Toast.LENGTH_SHORT).show();
return true;
}
}
Implementation of Event. All you have to do is implement Event Chaining and implement the action.
MainActivity.java
public class MainActivity extends AppCompatActivity {
EventChainManager eventChainManager = new EventChainManager();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Context context = this;
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
eventChainManager
.chain(new EventFoo(context))
.chainForce(new EventBar(context))
.chain(new EventBaz(context))
.execute();
}
});
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
eventChainManager
.chain(new EventFoo(context))
.chain(new EventBar(context))
.chain(new EventBaz(context))
.execute();
}
});
}
}
The usage is like this. The points are as follows.
eventChainManager .chain(new EventFoo(context)) .chainForce(new EventBar(context)) .chain(new EventBaz(context)) .execute();
When using it, if you implement it like this, it will be easy to read that Event is executed serially. In this case, it means that the process is executed up to EventBaz regardless of the process result of the second chained EventBar.
-Improved readability (should) Since you can write events by connecting them using eventChainManager # chain, This series of processes is connected in sequence, and you can express your intention because it is a batch of processes.
I thought it was written, but I wonder if it is suitable for cases where complicated processing is executed sequentially.
Source code https://github.com/ken-maki/k_commons.eventChain
Recommended Posts