
In the simplest case, to launch Activity in Android, you need to create an Intent with an indication of the class of the called activity and the Bundle from the parameters. And everything is fine, while we have a couple of screens in the application. Difficulties begin when the number of screens in our application will be in the tens. In this article I would like to offer a relatively simple way to organize work with a large number of Activities.
Introduction
In order to make the conversation more substantive, we will assume that there are at least 3 activations in our application:
')
- List of Documents Documents. It can be launched either without parameters for output of all documents, or with the int categoryId parameter for output of documents from this category;
- View DocumentView document. Called only with the UUID documentId parameter to view an existing document;
- DocumentEdit Document Editor. Called without a parameter to create a new document or with the UUID documentId parameter to edit an existing document.
Problem
What is the main disadvantage of the standard approach, in which Intent instances are created directly in the Activity code. This is code duplication. If we want to add another parameter to the activation call, we will have to change all the places where this activation is called. If the application is developed by more than one person, then you have to notify the whole team about the changes made. If you need to replace one activation with another, you will again need to look for all occurrences. And let such work for us can perform IDE, anyway, this is not feng shui.
Decision
So, I would like to get some object that allows:
- call the activation without explicitly specifying the class of the activated activation and without creating an explicit Intent;
- replace one activity with another;
- change the call parameters of an existing activation.
The
mediator pattern fits this description. Now it's up to the implementation.
Implementation
The class diagram is given at the beginning of the article. At first we will consider each of the classes in more detail.
The MyIntent class stores constants for the call parameters of an activity.
public class MyIntent extends Intent { public static final String EXTRA_CATEGORY_ID = "CategoryId"; public static final String EXTRA_DOCUMENT_ID = "DocumentId"; }
The ActivityMediator class implements the activation of the activity for this class. The constructor accepts the current activation and saves it in a private field. Two protected methods cause activations in this class without or with extras. Protected, these methods are designed to avoid the temptation to call them directly.
public class ActivityMediator { private Activity mActivity; public ActivityMediator(Activity activity){ mActivity = activity; } protected void startActivity(Class<?> cls){ Intent intent = new Intent(mActivity, cls); mActivity.startActivity(intent); } protected void startActivity(Class<?> cls, Bundle extras){ Intent intent = new Intent(mActivity, cls); intent.replaceExtras(extras); mActivity.startActivity(intent); } }
From the ActivityMediator class, we inherit the MyActivityMediator class.
public class MyActivityMediator extends ActivityMediator { public MyActivityMediator(Activity activity){ super(activity); } public void showDocumentsList(){ startActivity(DocumentsListActivity.class); } public void showDocumentsList(int categoryId){ Bundle bundle = new Bundle(); bundle.putInt(MyIntent.EXTRA_CATEGORY_ID, categoryId); startActivity(DocumentsListActivity.class, bundle); } public void showDocumentViewer(UUID documentId){ Bundle bundle = new Bundle(); bundle.putString(MyIntent.EXTRA_DOCUMENT_ID, documentId.toString()); startActivity(DocumentViewActivity.class, bundle); } public void showDocumentEditor(){ startActivity(DocumentEditActivity.class); } public void showDocumentEditor(UUID documentId){ Bundle bundle = new Bundle(); bundle.putString(MyIntent.EXTRA_DOCUMENT_ID, documentId.toString()); startActivity(DocumentEditActivity.class, bundle); } }
The MyActivity class is abstract, all other activities in the project are inherited from it.
public abstract class MyActivity extends Activity { private KadActivityMediator mActivityMediator = new KadActivityMediator(this); public KadActivityMediator getActivityMediator(){ return mActivityMediator; } }
Now in any activity of our application, we can call any other activity. For example, you can call the editor to create a new document:
getActivityMediator().showDocumentEditor();
View the selected document.
UUID documentId = getCurrentDocumentId(); getActivityMediator().showDocumentViewer(documentId);
Conclusion
This article has given an example of using the mediator pattern for organizing work with a lot of activity in the Android OS. Developing this idea, you can add startActivityForResult calls or an activation-based call to action.