Android MVP pattern package structure - android

I saw various great tutorials on MVP pattern in android, but the authors all seem to have different practice on packaging.
The first tutorial I saw did the packaging by functionalities. Such as, "Login", "Join", "UI" package.
The UI package has only activities, the "Login" package has the interfaces for the presenter and the concrete presenter, and this package contains a sub package "Model" that contains everything about the login model(communications with the server). The "Join" package has the same composition as the "Login" package.
But the other one I saw did the packaging by scene, such as "Join", "Login".
"Join" package contains an activity, and three sub packages named "Model", "View", "Presenter".
What is the best practice? Are there any articles that handles this issue?

App should have package according to features not by the common
functionality.
I find people make activity, fragments, Adapters,etc.
common purpose package in one group but this is bad practice!
Mostly developers group them like this because they do this to keep the same package structure for all the applications they work on. But that is very wrong decision cause it is always hard to find classes when they are grouped only because they share same parent classes!
We should group the classes according to parent classes but only if
we are making some API but if we are making a custom product for our
client then it is very bad practice.!
Like all activities most developers put in activity package because all activity classes extends the Activity class.That makes sense that this is only activity related package but it is hard to go through those packages.
Suppose we have One OrderListActivity class and we fetch the order list from server and then display it in one OrderListFragment class and obviously for that we need OrderListAdapter to show the order listing. so when customer ask for some modification or any feature he wants on that Order List screen we have to go to many packages to satisfy client need. Like we have to go to activity package and modify some thing in OrderListActivity and then go to OrderListFragment and then OrderListAdapter and then OrderListViewHolder,etc.!So This becomes too hard and we may create issues in process of modifying!
so we should group together the classes which are getting
changed/modify together.
That's the best practice and so we should group all those classes who are responsible for OrderListing feature in one package and we call it orderdlist package.
Please check my this medium post i have explained the package structure too in that:--
https://medium.com/#kailash09dabhi/mvp-with-better-naming-of-implementation-classes-dry-principle-e8b6130bbd02

I just repost my answer here
I often put business logic code in Model Layer (don't make confusion with model in database). I often rename as XManager for avoiding confusion (such as ProductManager, MediaManager ...) so presenter class just uses for keeping workflow.
The rule of thumb is no or at least limit import android package in presenter class. This best practice supports you easier in testing presenter class because presenter now is just a plain java class, so we don't need android framework for testing those things.
For example here is my mvp workflow.
View class: This is a place you store all your view such as button, textview ... and you set all listeners for those view components on this layer. Also on this View, you define a Listener class for presenter implements later. Your view components will call methods on this listener class.
class ViewImpl implements View {
Button playButton;
ViewListener listener;
public ViewImpl(ViewListener listener) {
// find all view
this.listener = listener;
playButton.setOnClickListener(new View.OnClickListener() {
listener.playSong();
});
}
public interface ViewListener {
playSong();
}
}
Presenter class: This is where you store view and model inside for calling later. Also presenter class will implement ViewListener interface has defined above. Main point of presenter is control logic workflow.
class PresenterImpl extends Presenter implements ViewListener {
private View view;
private MediaManager mediaManager;
public PresenterImpl(View, MediaManager manager) {
this.view = view;
this.manager = manager;
}
#Override
public void playSong() {
mediaManager.playMedia();
}
}
Manager class: Here is the core business logic code. Maybe one presenter will have many managers (depend on how complicate the view is). Often we get Context class through some injection framework such as Dagger.
Class MediaManagerImpl extends MediaManager {
// using Dagger for injection context if you want
#Inject
private Context context;
private MediaPlayer mediaPlayer;
// dagger solution
public MediaPlayerManagerImpl() {
this.mediaPlayer = new MediaPlayer(context);
}
// no dagger solution
public MediaPlayerManagerImpl(Context context) {
this.context = context;
this.mediaPlayer = new MediaPlayer(context);
}
public void playMedia() {
mediaPlayer.play();
}
public void stopMedia() {
mediaPlayer.stop();
}
}
Finally: Put those thing together in Activities, Fragments ... Here is the place you initialize view, manager and assign all to presenter.
public class MyActivity extends Activity {
Presenter presenter;
#Override
public void onCreate() {
super.onCreate();
IView view = new ViewImpl();
MediaManager manager = new MediaManagerImpl(this.getApplicationContext());
// or this. if you use Dagger
MediaManager manager = new MediaManagerImpl();
presenter = new PresenterImpl(view, manager);
}
#Override
public void onStop() {
super.onStop();
presenter.onStop();
}
}
You see that each presenter, model, view is wrapped by one interface. Those components will called through interface. This design will make your code more robust and easier for modifying later.

The good practice is to separate stuffs by feature (sometimes considered as module) and layer, not by their role. Reason: class/interface name already told that, e.g LoginView, LoginPresenter, LoginFragment, LoginActivity etc.

Related

How to pass data from parent view's presenter to child view's presenter?

I am using MVP patterns in Android. And structure looks like below.
Activity - Presenter
|
Fragment
|
CustomView
|
views
So when the presenter gets data from the network, it directly passes data to fragment, and fragment pass data to a custom view and custom view pass data to views.
I am not sure how I can pass data used in views from activity with MVP patterns. If I make presenters for each fragments, custom views, and views, then how can I pass data from activity's presenter to other presenters?
Anyone can help me out with examples?
In order to give a more specific answer to your question you need to give a concrete example. Every solution is valid in a context. I'll give couple of ways you can do this. Choose the one that suits your problem.
Very important part of the MVP is the Model. As far as I'm aware the term Model became popular in programing with the release of the paper Thing Model View Editor which was later refined and renamed to MVC.
The definition of the concept of a Model from this paper is:
A Model is an active representation of an abstraction in the form of
data in a computing system
The Models are represented in the computer as a collection of data
together with the methods necessary to process these data.
With time and experience, people have discovered and specified different types of models.
Here are some of them:
Domain Model
Application Model (read this article for more information)
Presentation Model
MVP, since it derives from MVC, makes two major divisions of responsibilities: Model (the abstraction that represent concepts) and Presentation (View and Presenter to visualize the Model).
Because we have divided the Model from the Presentation, we can have multipe Views that show the same Model different ways. An example of that is a Model that represents Statistical Data that can be shown different ways: a Pie chart, a Bar chart etc. In this example the Statistical Data Model is a Domain Model.
In the example above, the Model will probably be shared between the two View-Presenter pairs , The PieChart and the BarChart. If you use the Observer pattern, when one of the View-Presenter pairs update the StatisticalModel, it will raise changed events, and both View-Presenter pairs will receive notifications for this change and update.
Sometimes an application needs an ApplicationModel. This model can be shared between different View-Presentation pairs. Let's take a look at a verfy simplified example.
Let's say we have a File Browser application like Windows Explorer. This GUI of the application has two major parts: The left panel that shows a Tree of the folders and the middle File-Folder panel. When a folder is selected in the left folders tree panel, files and folders from the selected folder must be shown in the middle panel. We can do this by defining an ApplicationModel that will capture and represent the above logic and be shared between both View-Presentation pairs for the left and middle panels.
Note: I'll omit details to simply the example and write less code
public class ApplicationState {
// singleton, it's evil I know,
// but it's the simplest way without DI or ServiceLocator
private static ApplicationState mInstance = new ApplicationState();
public static ApplicationState getInstance() { return mInstance; }
private Folder mSelectedFolder;
public bool hasSelectedFolder() { return mSelectedFolder != null; }
public Folder getSelectedFolder() { return mSelectedFolder; }
public Folder setSelectedFolder(Folder f) {
mSelectedFolder = f;
RaiseSelectedFolderChangedEvent();
}
// method for registering listeners, raising events etc.
}
public class FoldersTreeViewPresenter {
private ApplicationState mApplicationState;
public void onSelectFolder(FolderView view) {
// select the folder in the view
mApplicationState.setSelectedFolder(view.Folder);
}
}
public class FilesFoldersViewPresenter : ApplicationStateListener {
private ApplicationState mApplicationState;
public FilesFoldersViewPresenter() {
// you can use service locator, dependency injection, whatever
mApplicationState = ApplicationState.getInstance();
mApplicationState.addEventListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
private void clearView() {
// clear the panel
}
public void onApplicationStateChanged() {
if(mApplicationState.hasSelectedFolder()){
getFilesAndFoldersFromFileSystem(mApplicationState.getSelectedFolder());
}
else {
clearView();
}
}
}
In this example we created a shared object that represent the application state and the logic, that our application has a selection that can be changed. In this case the ApplicationState class is part of the Model and is an Application Model. Because it is shared and it's life time is the same as the application (it exists as long as the application is running) it will hold the state. Views and Presenters are created and destroyed, but this class will exist and hold the state, so that when a new View and/or Presenter is created it can check this state and do something.
In my experince people do concentrate on Views and Presenters more, while they should work on their Models. Peronally I use Models alot as it makes things cleaner and the application easier to understand.
Of course, using Models doesn't always work, so when they don't you can use messaging, having one Presenter sending messages to others. Here's an example with the same File Browser app.
public class MessageBus {
// static this time, you can use DI or ServiceLocator with interface
public static void sendMessage(object m) { }
public static void registerListener(MessageListener listener) { }
}
public class FoldersTreeViewPresenter {
public void onSelectFolder(FolderView view) {
// select the folder in the view
MessageBus.sendMessage(new FolderSelected(view.Folder));
}
}
public class FilesFoldersViewPresenter : MessageListener {
public FilesFoldersViewPresenter() {
MessageBus.addListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
public void onMessage(object m) {
if(m instanceof FolderSelected) {
FolderSelected folderSelectedMessage = (FolderSelected)m;
getFilesAndFoldersFromFileSystem(folderSelectedMessage.Folder);
}
}
}
Depending on your specific case, if you can create a nice Model, either a Domain, Application or Presentation, do it. Share this Model thus creating a dependency on the Model from the Presenters instead of creating a dependency between Presenters. This way you have loose coupling between Presenters and you can change them much easier
If you can't use a Model, use a Messages. It's a nice way to decouple Presenters by creating a protocol of messages that are used for communication.
Check this article on using messages for collaboration between components.
Also here are some good articles on GUI architectures:
https://martinfowler.com/eaaDev/uiArchs.html
http://aspiringcraftsman.com/2007/08/25/interactive-application-architecture/

How do I use AndroidInjection class in custom views or other android classes?

My issue with the Android-specific pattern is, if you use their AndroidInjection class, there is no way to members inject other objects besides Activities/Fragments/custom views/adapters, except with the Application Component. This is because you cannot get a reference the the Subcomponent (AndroidInjector) used to inject Activities/Fragments.
This makes injecting Dialogs (if you use DialogFragments).
The AndroidInjection class seems to support just the core Android types.
What follows is not an answer to your question, but an explanation why you shouldn't be asking this question at all.
You should avoid injections into custom Views in general. The reasons for this are listed in this article.
Advantages of using Method Injection in this case [injection into custom Views] are:
Dependencies will need to be propagated from top level component (Activity or Fragment)
Method Injection does not open door to Single Responsibility Principle violation
No dependency on the framework
Better performance
The first advantage might come as a surprise because propagation from
top level component is harder than adding annotation to fields, and
involves more boilerplate code. This is surely a bad thing, right?.
Not in this case. In fact, there are two good aspects associated with
such a propagation of dependencies. First of all, the dependencies
will be visible at the top level component. Therefore, just by looking
at e.g. Fragment‘s fields, the reader of the code will immediately
understand that this Fragment shows images. Such optimizations for
readability makes the system more easily maintainable in the long
term. Secondly, there are not many use cases in which sub-classes of
View need additional dependencies. The fact that you need to actually
work in order to provide these dependencies will give you a bit of
time to think about whether providing them is a good design decision
to start with.
The second advantage is related to collaborative construction. You
might be very experienced software engineer yourself, but you’ll
probably have also less experienced teammates. Or it is possible that
you’ll leave the project one day, and the guy who will take over will
not be as good as you. By injecting one single dependency using a
framework, you basically open a door for other injections. Imagine
that some data from SharedPreferences becomes required in custom View
in order to e.g. fix a bug. One of the less experienced developers
might decide that it is a good approach to inject SharedPreferences
into custom View directly. Doing this violates Single Responsibility
Principle, but that developer might not even be aware of such a
concept. Therefore, in the long term, such injection “backdoors” can
reduce design quality and lead to long debug sessions.
The third advantage of using Method Injection with custom Views is
that you don’t couple the View to dependency injection framework. Just
imagine that few years from now you (or some other poor guy) need to
replace the framework. The fact that you’ll probably have tens of
Activities and Fragments to start with will make your life miserable.
If you’ll have additional tens or hundreds of custom Views to handle,
then it might bring you into suicidal mood.
The last (but not least) advantage is performance. One screen can
contain one Activity, several Fragments and tens of custom Views.
Bootstrapping this number of classes using dependency injection
framework might degrade application’s performance. It is especially
true for reflection based frameworks, but even Dagger carries some
performance cost.
In addition, I advice to avoid the new injection method that involves AndroidInjection class. It is discussed in this video tutorial.
First, you should think over Vasily's answer.
But let's think for a moment how we did this before Dagger Android?
We built a subcomponent from the component that was taken from the Application class. Later, we could use this subcomponent in order to inject fields, for example, of a custom view.
So, we'll try to do the exact same thing now.
Suppose, our aim is to inject MyAdapter class into a MyButton:
public class MyButton extends AppCompatButton {
#Inject MyAdapter adapter;
public MyButton(Context context) {
super(context);
...
}
}
And let's make the adapter have a dependency on the activity Context, not application Context:
public class MyAdapter {
#Inject
public MyAdapter(#Named("activity") Context context) {
}
}
Let's start with the custom Application class.
MyApplication.java
public class MyApplication extends DaggerApplication {
#Inject
DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
public static MySubcomponent mySubcomponent;
#Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.builder()
.create(this);
}
}
AppComponent.java:
#Component(modules = {AndroidSupportInjectionModule.class, ActivityBindingModule.class, AppModule.class})
#Singleton
public interface AppComponent extends AndroidInjector<MyApplication> {
#Component.Builder
abstract class Builder extends AndroidInjector.Builder<MyApplication> {
}
}
AppModule.java
#Module
abstract class AppModule {
#Binds
#Singleton
#Named("app")
abstract Context providesContext(Application application);
}
ActivityBindingModule.java
#Module(subcomponents = MySubcomponent.class)
public abstract class ActivityBindingModule {
#Binds
#IntoMap
#ActivityKey(MainActivity.class)
abstract AndroidInjector.Factory<? extends Activity>
bindMainActivityInjectorFactory(MySubcomponent.Builder builder);
}
AndroidSupportInjectionModule.java is shipping with dagger itself. If you do not use classes from support package (i.e. android.support.v4.app.Fragment instead of android.app.Fragment), then use AndroidInjectionModule.java.
MySubcomponent.java
#ActivityScope
#Subcomponent(modules = {SubcomponentModule.class/*, other modules here, if needed */})
public interface MySubcomponent extends AndroidInjector<MainActivity> {
void inject(MyButton button);
#Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<MainActivity> {
public abstract MySubcomponent build();
}
}
SubcomponentModule.java
#Module
abstract class SubcomponentModule {
#Binds
#ActivityScope
#Named("activity")
abstract Context toContext(MainActivity activity);
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Inject
MySubcomponent subcomponent;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Will inject `subcomponent` field
AndroidInjection.inject(this);
// Saving this component in a static field
// Hereafter you are taking responsibility of mySubcomponent lifetime
MyApplication.mySubcomponent = subcomponent;
super.onCreate(savedInstanceState);
setContentView(new MyButton(this));
}
}
Having all of these, now here's how MyButton will look like:
public class MyButton extends AppCompatButton {
#Inject MyAdapter adapter;
public MyButton(Context context) {
super(context);
MyApplication.mySubcomponent.inject(this);
}
}
I admit that this looks hacky and certainly not an approach to stick to. I'm happy to see a better approach.
This is because you cannot get a reference the the Subcomponent (AndroidInjector) used to inject Activities/Fragments.
You can always just inject the component itself. Just add a field for the component to your Activity / Fragment and let Dagger inject it along with the rest.
// will be injected
#Inject MainActivitySubcomponent component;
The issue of whether the dagger-android classes like AndroidInjector should support injection inside Views or not has been discussed in the following Github issue:
https://github.com/google/dagger/issues/720
Quoting from one of the library authors:
There is both a philosophical point and logistical/implementation point to be made here.
First, it's not fully clear to us that injecting views is the right thing to do. View objects are meant to draw, and not much else. The controller (in a traditional MVC pattern) is the one which can coordinate and pass around the appropriate data to a view. Injecting a view blurs the lines between fragments and views (perhaps a child fragment is really the appropriate construct instead?)
From the implementation perspective, there is also a problem in that there isn't a canonical way to retrieve the View's parent Fragments (if any), or Activity to retrieve a parent component. There have been hacks suggested to build in that relationship, but so far we haven't seen anything that seems to suggest that we could do this correctly. We could just call View.getContext().getApplicationContext() and inject from there, but skipping the intermediate layers without any option for something in between is inconsistent with the rest of our design, and probably confusing to users even if it works.
This reinforces the opinion expressed in Vasily's answer.
To add further, people often seem to want to inject model-layer dependencies inside their custom views. This is a bad idea as it goes against the software engineering principle of separation of concerns.
The correct solution for associating a view and a model is to write an adapter like the adapters for RecyclerView and ListView. You can inject the model-layer dependency at the Fragment or Presenter level and set the adapter there.

What are the advantages of using DispatchingAndroidInjector<> and the other dagger.android classes?

I'm working on setting up Dagger 2 into my android project. It is my first time with this framework and everything goes well so far. But I'm seeing different approaches on the way you can set up this framework in your project and I wonder which one is better, because I compare both and for me the result is kind of the same.
I followed this guide: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
Searching on Internet all of them use this approach.
It use #Module and #Component to define the dependencies.
and your application ends up like this:
public class MyApp extends Application {
private NetComponent mNetComponent;
#Override
public void onCreate() {
super.onCreate();
// Dagger%COMPONENT_NAME%
mNetComponent = DaggerNetComponent.builder()
// list of modules that are part of this component need to be created here too
.appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
.netModule(new NetModule("https://api.github.com"))
.build();
// If a Dagger 2 component does not have any constructor arguments for any of its modules,
// then we can use .create() as a shortcut instead:
// mNetComponent = com.codepath.dagger.components.DaggerNetComponent.create();
}
public NetComponent getNetComponent() {
return mNetComponent;
}
}
But I found another way (I haven't tested it):https://google.github.io/dagger/android.html
And It looks like completely different, using different classes and annotations.
It uses something like this:
#Subcomponent(modules = ...)
public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {
#Subcomponent.Builder
public abstract class Builder extends AndroidInjector.Builder<YourActivity> {}
}
#Module(subcomponents = YourActivitySubcomponent.class)
abstract class YourActivityModule {
#Binds
#IntoMap
#ActivityKey(YourActivity.class)
abstract AndroidInjector.Factory<? extends Activity>
bindYourActivityInjectorFactory(YourActivitySubcomponent.Builder builder);
}
#Component(modules = {..., YourActivityModule.class})
interface YourApplicationComponent {}
public class YourApplication extends Application implements HasDispatchingActivityInjector {
#Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
#Override
public void onCreate() {
super.onCreate();
DaggerYourApplicationComponent.create()
.inject(this);
}
#Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return dispatchingActivityInjector;
}
}
So, my questions are:
which one is better?
What are the reasons for choosing one approach instead of the other?
The method of setting up Dagger 2 for Android that is now prescribed in official Dagger 2 documentation has a number of advantages and should be preferred. The advantages are just those elaborated there, namely:
Copy-pasting code makes it hard to refactor later on. As more and more developers copy-paste that block, fewer will know what it actually does.
More fundamentally, it requires the type requesting injection (FrombulationActivity) to know about its injector. Even if this is done through interfaces instead of concrete types, it breaks a core principle of dependency injection: a class shouldn’t know anything about how it isinjected.
Let's apply those reasons to your first example.
Reason 1
Assume we have an Activity that wants to use your NetComponent. Let's call it NetActivity. The onCreate(Bundle savedInstanceState) method of that NetActivity will look something like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((MyApp) getApplicationContext()).getNetComponent().inject(this);
}
This code has all the visual appeal of toenail clippings scattered on oatmeal (not my simile) and will end up copy-pasted in all of the injection site Activities where you use NetComponent. If you use more complicated components, such as this example from the docs:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DO THIS FIRST. Otherwise frombulator might be null!
((SomeApplicationBaseType) getContext().getApplicationContext())
.getApplicationComponent()
.newActivityComponentBuilder()
.activity(this)
.build()
.inject(this);
// ... now you can write the exciting code
}
Even worse. It can easily degenerate into a magical piece of code that must be copied and pasted throughout the injection sites. If it changes, it's easy to forget to update just one site and have your app crash.
Reason 2
One of the great advantages of dependency injection is injection sites need not know or care about their injectors, just as dependencies do not know or care about their dependents. To return to ourNetActivity, we have:
((MyApp) getApplicationContext()).getNetComponent().inject(this);
The Activity "knows" about its injector (NetComponent), and the Activity is now coupled with a concretion MyApp and the method getNetComponent() from the same. If either of these classes changes, NetActivity will have to change as well.
The advantages of following the new way of injection inside Activity and Fragments available in Dagger versions 2.10 and forward are just the opposite of these disadvantages:
You end up with less copy-paste code
Types requesting injection no longer have to know or care about their injectors or the sources of their injectors.
Furthermore, as pointed out in this blog, preferring subcomponents over dependent components reduces the method count of your app.
While using subcomponents may initially seem more difficult, there are some clear advantages. However, for the purposes of learning Dagger dependent components may be initially easier to understand. If the second example is too complicated initially, you can graduate to the preferred method when you have gained finesse.

Android MVP and framework specific code

I was reading an article by Dario Miličić regarding MVP here. I also thoroughly went through the code he provided on git hub. Anyways, i am pretty new to MVP for android and MVP in general, and so I have a question about what he said - "The implementation layer is where everything framework specific happens”. What if i have an android application that deals with Bluetooth? i.e. i have a small application to get a list of bluetooth devices using BluetoothAdapter which is an android class. So I started writing a use cases which was something like this
public interface BluetoothScanInteracotor {
interface View {
void onScanStarted();
void onScanCompleted();
}
void scanForDevices();
}
but then realised that I cant do that because of its framework specific.
How would I go about this?
Forgive me if that's a silly question, but I might be confused about something and I need someone to help me understand.
The CLEAN approach would be to implement a BluetoothDeviceRepository, which could have multiple implementations, one of which would actually access the system resources, but could easily be swapped for one with no external dependencies for test, etc. The Bluetooth device scan results would be converted by repository implementations to return POJO models that represented the information you needed, so that there would be no leakage of the Android system classes into this layer.
The issue with most MVP implementation out there is that they designate Activities and Fragments as Views, and propose to use "Android framework independent" presenters.
This sounds good until one encounters issues like yours - Bluetooth framework is part of Android framework, so it is not clear how to use it in the presenter that shouldn't depend on Android specific classes.
After researching MVx architectures on Android for several years I realized that the only sane conclusion that can be derived is that Activities and Fragments are not views, but presenters.
The more detailed discussion of this subject can be found here: Why Activities in Android are not UI Elements.
Based on this idea I proposed an alternative implementation of MVP in Android: MVP and MVC Architectures in Android.
I have an idea in MVP model that not bad to share with you,
Everything that depends on the OS,should be treated as View, and Logic is Presenter,
For example Activity is a View, we use it to intract with UI ,for example get Text of a Textview, and when we need to process on the text, we make a presenter class for this activity and also an interface to this presenter, then implement the interface in presenter,and call methods of interface in Activity with needed params(for example that Text)
If I want implement it in another OS, i should only change my Activity and get Text in other way,and remain process is same and doesn't change
As you have come to know basics of Clean Architechure. The following example depicts how actual your MVP pattern is implemented.
Example:
interface BaseContract {
interface BaseView {
//Methods for View
void onDoSomething();
}
interface BasePresenter {
void doSomething();
}
}
class BaseMainPresenter implements BaseContract.BasePresenter {
BaseContract.BaseView view;
BaseMainPresenter(BaseContract.BaseView view) {
this.view = view;
}
#Override
public void doSomething() {
if (view != null)
view.onDoSomething();
}
}
class DemoClass implements BaseContract.BaseView {
//Create object of Presenter
/****
* Example :
* BaseMainPresenter baseMainPresenter = new BaseMainPresenter(this);
*/
#Override
public void onDoSomething() {
//Deal with Context here.
}
}

Effect of Singleton class in case of a Library file

I have a design question on Android.
I have a class which used to register Accelerometer sensor in Andriod. I am passing the SensorEventListener as parameter in the defined function so that user will get the functionality to work on live sensor data or to store it using POJO class.
What will be the effect if I implement a Singleton Design Pattern on that class? Is there any blockage from devlepment side?
Sample Code :
public class Accel
{
private static Accel accelObj;
private Accel(Context context)
{
}
public static synchronized Accel getInstance(Context context)
{
if (accelObj == null)
accelObj = new Accel(context);
return accelObj;
}
public registerListener(SensorEventListener listener)
{
// To Do
}
}
This class I want to use for application development. Is there any drawback other then slower due to synchronized method for application development?
I have been using the same method and could not see any reason for it to be a bad idea for cases where your class only depends on a basic application context.
I found it to be a neat method for relieving my Activities and Fragments of having to hold code logic needed in multiple places across my app.
Things becomes more troublesome if you get to a point where have more objects constructed in this way and they have more complex dependencies. If you need Activity context in some cases, e.g. to show dialogs etc, or you need to have internal dependencies.
In my case I ended up writing a Factory that constructed the objects in the correct order and gave the dependencies as parameters. Though working it became very annoying to maintain. Imagine having a Service that can run in background even though the app is destroyed, now the 'guarentees' that the object has been constructed and reside in memory is once more gone.
The solution for me was to implement Dagger
Using this I can construct the object like this
#Singleton
public class Accel
{
#Inject
public Accel(#ForApplication Context context)
{
}
public registerListener(SensorEventListener listener)
{
// To Do
}
}
Now at any place that I need the Accel object in the app:
public {Activity, Fragment, Service} {
#Inject Accel acc; <- acc is now constructed and ready for use
}
This works with multiple dependencies too:
#Singleton
public class AnotherModule
{
#Inject
public AnotherModule(#ForActivity Context context, Accel acc, ThirdModule thridMod)
{
}
public registerListener(SensorEventListener listener)
{
// To Do
}
}
Notice the #ForActivity, this means that this module will not work in a module (as we depend on an Activity context being present)
public {Activity, Fragment} {
#Inject AnotherModule anotherMod; <- anotherModis now constructed and ready for use
}
Using Dagger greatly lifted the quality of my code as it removed any redundant and boilerplate code needed to setup the modules.
The price is that it is somewhat difficult to get working at first, at least it was for me. Took a week to learn and apply to ~15k lines of code, so as mentioned earlier. If you only need a single singleton object, then it might be overkill to do this :)
Hope this is helpful to you

Categories

Resources