Integrating Forgot Password feature within Login Screen in SUSI Android App

For a user’s point of view the interface and the flow of the app is of great importance, the UI of the app should be simple and sufficient so that it does not confuse the user and provides all the necessary information to the user with the first look. In all the  apps it is the user interface that engages the user and makes the user want to use the app. So, in SUSI Android app UI flow was improved by removing the Forgot Password activity altogether. What SUSI.AI android app previously had ? Previously the SUSI.AI android app used to have three different screens for the user’s account related support : Login Screen Forgot Password Screen SignUp Screen     The login screen had a Forgot Password? Option that takes the user to a new screen where the details entered in the login activity had to be entered again and only then can the user request a new password. What are the drawbacks of this ? Separately, providing a new activity for the specific purpose of resetting the password does not contribute towards an efficient use of UI items of the screen. A scenario where this will be annoying to the user is for eg :  when a user tries to login to the app and is unable to do so because of the incorrect credentials, user simply clicks on the Forgot Password option and on opening the Forgot Password activity to the user’s surprise all the fields entered in the login screen are to be entered again and this is really fuzzy and sometimes frustrating to the user. A simple solution implemented for this purpose was to automatically reflect the credentials entered by the user in the login screen on the forgot password screen so  that user did not had to enter all the details again. What better could be done and the solution? The simplest UI for the purpose of resetting a password is to just click the Forgot Password? and user receives an email to reset the password. Using this approach several changes were made to the app’s code. The first change to be made was to implement the ForgotPasswordPresenter.kt functions in the LoginPresenter.kt and similarly implement the IForgotPasswordView.kt functions in the LoginActivity.kt. The two major functions in the  IForgotPasswordPresenter.kt were : fun requestPassword(email: String, url: String, isPersonalServerChecked: Boolean) fun cancelSignup() Along with these functions in the LoginPresenter.kt the view functions to reflect the view actions of the ForgotPasswordActivity.kt had to be implemented in the LoginActivity.kt file, so the functions added to the ILoginView.kt file were : fun showForgotPasswordProgress(boolean: Boolean) fun resetPasswordSuccess() fun resetPasswordFailure(title: String?, message: String?, button: String?, color: Int) Now, the two functions above which were earlier present in the ForgotPasswordPresenter.kt file were implemented in the LoginPresenter.kt file and along with the requestPassword() method the listener IForgotPasswordModel.OnFinishListener had to be implemented in the Login Presenter too. So, on implementing this listener we implement a method : override fun onForgotPasswordModelSuccess(response: Response<ForgotPasswordResponse>) {   loginView?.showForgotPasswordProgress(false)   if (response.isSuccessful &&…

Continue ReadingIntegrating Forgot Password feature within Login Screen in SUSI Android App

Implementation of Sponsors API in Open Event Organizer Android App

New contributors to this project are sometimes not experienced with the set of libraries and MVP pattern which this app uses. This blog post is an attempt to walk a new contributor through some parts of the code of the app by implementing an operation for an endpoint of the API. We’ll be implementing the sponsor endpoint. Open Event Organizer Android app uses a robust architecture. It is presently using the MVP (Model-View-Presenter) architecture. Therefore, this blog post aims at giving some brief insights to the app architecture through the implementation Sponsor endpoint. This blog post will focus only on one operation of the endpoint - the list operation - so as to make the post short enough. This blog post relates to Pull Request #901 of Open Event Organizer App. Project structure: These are the parts of the project structure where major updates will be made for the implementation of Sponsor endpoint: core data Setting up elements in the data module for the respective endpoint Sponsor.java @Data @Builder @Type("sponsor") @AllArgsConstructor @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy.class) @EqualsAndHashCode(callSuper = false, exclude = { "sponsorDelegate", "checking" }) @Table(database = OrgaDatabase.class) public class Sponsor extends AbstractItem<Sponsor, SponsorsViewHolder> implements Comparable<Sponsor>, HeaderProvider {    @Delegate(types = SponsorDelegate.class)    private final SponsorDelegateImpl sponsorDelegate = new         SponsorDelegateImpl(this); This class uses Lombok, Jackson, RaizLabs-DbFlow, extends AbstractItem class (from Fast Adapter) and implements Comparable and HeaderProvider. All the annotations processor help us reduce boilerplate code. From the Lombok plugin, we are using: Lombok has annotations to generate Getters, Setters, Constructors, toString(), Equal() and hashCode() methods. Thus, it is very efficient in reducing boilerplate code @Getter,  @Setter, @ToString, @EqualsAndHashCode @Data is a shortcut annotation that bundles the features of @Getter, @Setter, @ToString and @EqualsAndHashCode The @Delegate is used for direct calls to the methods that are annotated with it, to the specified delegate. It basically separates the model class from other methods which do not pertain to data. Jackson @JsonNaming - used to choose the naming strategies for properties in serialization, overriding the default. For eg:  KEBAB_CASE, LOWER_CASE, SNAKE_CASE, UPPER_CAMEL_CASE @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy.class) @JsonProperty - used to store the variable from JSON schema as the given variable name. So, "type" from JSON will be stored as sponsorType. @JsonProperty("type") public String sponsorType; RaizLabs-DbFlow DbFlow uses model classes which must be annotated using the annotations provided by the library. The basic annotations are – @Table, @PrimaryKey, @Column, @ForeignKey etc. These will create a table named attendee with the columns and the relationships annotated. SponsorDelegate.java and SponsorDelegateImpl.java The above are required only for method declarations of the classes and interfaces that Sponsor.java extends or implements. These basically separate the required method overrides from the base item class. public class SponsorDelegateImpl extends AbstractItem<Sponsor, SponsorsViewHolder> implements SponsorDelegate { SponsorRepository.java and SponsorRepositoryImpl.java A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the…

Continue ReadingImplementation of Sponsors API in Open Event Organizer Android App

MVP in Loklak Wok Android using Dagger2

MVP stands for Model-View-Presenter, one of the most popular and commonly used design pattern in android apps. Where “Model” refers to data source, it can be a SharedPreference, Database or data from a Network call. Going by the word, “View” is the user interface and finally “Presenter”, it’s a mediator between model and view. Whatever events occur in a view are passed to presenter and the presenter fetches the data from the model and finally passes it back to the view, where the data is populated in ViewGroups. Now, the main question, why it is so widely used? One of the obvious reason is the simplicity to implement it and it completely separates the business logic, so, easy to write unit-tests. Though it is easy to implement, its implementation requires a lot of boilerplate code, which is one of its downpoints. But, using Dagger2 the boilerplate code can be reduced to a great extent. Let’s see how Dagger2 is used in Loklak Wok Android to implement MVP architecture. Adding Dagger2 to the project In app/build.gradle file dependencies { ... compile 'com.google.dagger:dagger:2.11' annotationProcessor 'com.google.dagger:dagger-compiler:2.11' }   Implementation First a contract is created which defines the behaviour or say the functionality of View and Presenter. Like showing a progress bar when data is being fetched, or the view when the network request is successful or it failed. The contract should be easy to read and going by the names of the method one should be able to know the functionality of methods. For tweet search suggestions, the contract is defined in SuggestContract interface. public interface SuggestContract { interface View { void showProgressBar(boolean show); void onSuggestionFetchSuccessful(List<Query> queries); void onSuggestionFetchError(Throwable throwable); } interface Presenter { void attachView(View view); void createCompositeDisposable(); void loadSuggestionsFromAPI(String query, boolean showProgressBar); void loadSuggestionsFromDatabase(); void saveSuggestions(List<Query> queries); void suggestionQueryChanged(Observable<CharSequence> observable); void detachView(); } }   A SuggestPresenter class is created which implements the SuggestContract.Presenter interface. I will not be explaining how each methods in SuggestPresenter class is implemented as this blog solely deals with implementing MVP. If you are interested you can go through the source code of SuggestPresenter. Similarly, the view i.e. SuggestFragment implements SuggestContract.View interface. So, till this point we have our presenter and view ready. The presenter needs to access the model and the view requires to have an instance of presenter. One way could be instantiating an instance of model inside presenter and an instance of presenter inside view. But, this way model, view and presenter would be coupled and that defeats our purpose. So, we just INJECT model into presenter and presenter into view using Dagger2. Injecting here means Dagger2 instantiates model and presenter and provides wherever they are requested. ApplicationModule provides the required dependencies for accessing the “Model” i.e. a Loklak API client and realm database instance. When we want Dagger2 to provide a dependency we create a method annotated with @Provides as providesLoklakAPI and providesRealm. @Provides LoklakAPI providesLoklakAPI(Retrofit retrofit) { return retrofit.create(LoklakAPI.class); } @Provides Realm providesRealm() { return Realm.getDefaultInstance(); }   If we look…

Continue ReadingMVP in Loklak Wok Android using Dagger2
Read more about the article Automatic handling of view/data interactions in Open Event Orga App
Abstract 3d white geometric background. White seamless texture with shadow. Simple clean white background texture. 3D Vector interior wall panel pattern.

Automatic handling of view/data interactions in Open Event Orga App

During the development of Open Event Orga Application (Github Repo), we have strived to minimize duplicate code wherever possible and make the wrappers and containers around data and views intelligent and generic. When it comes to loading the data into views, there are several common interactions and behaviours that need to be replicated in each controller (or presenter in case of MVP architecture as used in our project). These interactions involve common ceremony around data loading and setting patterns and should be considered as boilerplate code. Let’s look at some of the common interactions on views: Loading Data While loading data, there are 3 scenarios to be considered: Data loading succeeded - Pass the data to view Data loading failed - Show appropriate error message Show progress bar on starting of the data loading and hide when completed If instead of loading a single object, we load a list of them, then the view may be emptiable, meaning you’ll have to show the empty view if there are no items. Additionally, there may be a success message too, and if we are refreshing the data, there will be a refresh complete message as well. These use cases present in each of the presenter cause a lot of duplication and can be easily handled by using Transformers from RxJava to compose common scenarios on views. Let’s see how we achieved it. Generify the Views The first step in reducing repetition in code is to use Generic classes. And as the views used in Presenters can be any class such as Activity or Fragment, we need to create some interfaces which will be implemented by these classes so that the functionality can be implementation agnostic. We broke these scenarios into common uses and created disjoint interfaces such that there is little to no dependency between each one of these contracts. This ensures that they can be extended to more contracts in future and can be used in any View without the need to break them down further. When designing contracts, we should always try to achieve fundamental blocks of building an API rather than making a big complete contract to be filled by classes. The latter pattern makes it hard for this contract to be generally used in all classes as people will refrain from implementing all its methods for a small functionality and just write their own function for it. If there is a need for a class to make use of a huge contract, we can still break it into components and require their composition using Java Generics, which we have done in our Transformers. First, let’s see our contracts. Remember that the names of these Contracts are opinionated and up to the developer. There is no rule in naming interfaces, although adjectives are preferred as they clearly denote that it is an interface describing a particular behavior and not a concrete class: Emptiable A view which contains a list of items and thus can be empty public interface Emptiable<T>…

Continue ReadingAutomatic handling of view/data interactions in Open Event Orga App

Updating Settings Activity With MVP Architecture in SUSI Android

SUSI Android app includes settings that allow users to modify app features and behaviours. For example, SUSI Android allows users to specify whether they want voice output i.e text to speech irrespective of input type. Currently different settings available in SUSI Android are: Settings                                          Use Enter As Send It allows users to specify whether they want to use action button of soft keyboard as carriage return or send message Mic Input It allows users to specify whether they want to use speech for input type or not. User can also use keyboard to provide input. Speech Always It allows users to specify whether they want speech output i.e text to speech irrespective of input type Speech Output It allows users to specify whether they want speech output in case of speech input or not. Select Server It allows user to specify whether they want to use default susi_server or their own server. Language It allows users to select text to speech engine language. Android's standard architecture isn’t always sufficient, especially in the case of complex applications that need to be tested regularly. So we need an architecture that can improve the app’s testability and MVP(Model View Presenter) architecture is one of the best options for that. Working with MVP architecture to show settings MVP architecture creates three layers: Model, View and Presenter. Use of each layer is described below Model: The Model holds the business logic of the application. It controls how data can be created, stored, and modified. View: The View is a UI that displays data and routes user actions to the Presenter. Presenter: Presenter is a mediator between View and Model. It retrieves data from the Model and shows it in the View. It also processes user actions forwarded to it by the View. Steps followed to implement MVP architecture are: 1. I first created three interfaces: ISettingsView, ISettingModel and  ISettingsPresenter. These classes contain all the important functions we needed in model, presenter and view. Presenter’s interaction with model is handled by  ISettingModel and presenter’s interaction with view is handled by ISettingsPresenter and ISettingView. I created model, view and presenter class i.e SettingModel, SettingsPresenter and SettingsActivity and implemented ISettingModel, ISettingsPresenter and ISettingsView in SettingModel, SettingPresenter and SettingsActivity respectively so that presenter can communicate with both model and view. class SettingsPresenter(fragmentActivity: FragmentActivity): ISettingsPresenter, ISettingModel.onSettingFinishListener class SettingsActivity : AppCompatActivity(), ISettingsView class SettingModel: ISettingModel After that, I created ChatSettingsFragment class. It is a PreferenceFragment class which resides in SettingsActivity and contains all settings. class ChatSettingsFragment : PreferenceFragmentCompat()  How Presenter communicates with Model and View As already mentioned presenter’s interaction with view is handled by ISettingsView and ISettingsPresenter. So first I created object of ISettingsPresenter in ChatSettingsFragment, which is part of view, as shown below lateinit var settingsPresenter: ISettingsPresenter settingsPresenter = SettingsPresenter(activity) And used it to call method of presenter, SettingsPresenter settingsPresenter.sendSetting(Constant.ENTER_SEND, newValue.toString()) After that, I created an object of ISettingsView in SettingsPresenter, so that it can communicate with view, SettingsActivity. Presenter’s interaction with model is handled by ISettingModel. So first…

Continue ReadingUpdating Settings Activity With MVP Architecture in SUSI Android

Presenter Abstraction Layer in Open Event Organizer Android App

Open Event Organizer App design follows Model View Presenter (MVP) architecture which enables heavy unit testing. MVP is a trending architecture design followed these days. If you are not aware of MVP architecture, then please refer any of the tutorial (few links are given at the end of this blog) about it before reading this. In the design, the code becomes little repetitive as the application size increases due to so many presenters and views, which degrades the code readability. So to avoid this and keep the functionality code clean in the App, we have created a Presenter Abstraction Layer which contains the repetitive code and the layer is extended wherever required in the app. I will be talking about the Presenter Abstraction Layer implementation through the App in this blog. First of all, create a base interface. The base interface contains methods which every presenter will have. The base interface for presenter in the App looks like: public interface IBasePresenter { void start(); void detach(); }   In the method start, presenter loads all the required data from the model and sends it to the view. And releases all the resources in detach. These two methods are required in all the presenters. This interface is extended by other two interfaces which will be actually used by the views. The relevant code is: public interface IPresenter<V> extends IBasePresenter { void attach(V view); } public interface IDetailPresenter<K, V> extends IBasePresenter { void attach(K key, V view); }   Method attach is used to attach view and the data id (if required) to the presenter. In the app, most of the presenters require an extra data which is used in loading data from the model. Hence two interfaces are extended from the base interface. Now comes the implementation part. public abstract class BasePresenter<V> implements IPresenter<V> { private V view; private CompositeDisposable compositeDisposable; @Override @CallSuper public void attach(V view) { this.view = view; this.compositeDisposable = new CompositeDisposable(); } @Override @CallSuper public void detach() { view = null; compositeDisposable.dispose(); } protected V getView() { return view; } protected CompositeDisposable getDisposable() { return compositeDisposable; } }   The App uses ReactiveX Observables for async operations which contain fragment/activity context hence these need to be disposed at some lifecycle of fragment/activity. detach nulls the view and disposes the compositeDisposable. This method is called at the onStop lifecycle of fragment/activity. The observable subscriptions are one of the major reasons for memory leaks if not disposed at correct lifecycle in Android. So the detach method is called at onStop lifecycle when activity goes into background or fragment is switched by FragmentTransaction. Another base presenter class looks like: public abstract class BaseDetailPresenter<K, V> extends BasePresenter<V> implements IDetailPresenter<K, V> { private K id; @Override @CallSuper public void attach(K id, V view) { super.attach(view); this.id = id; } protected K getId() { return id; } }   This class extends the previous one except for the attach method. As the presenters extending this, require an extra data id which is passed…

Continue ReadingPresenter Abstraction Layer in Open Event Organizer Android App

Shifting from Java to Kotlin in SUSI Android

SUSI Android (https://github.com/fossasia/susi_android) is written in Java. After the announcement of Google to officially support Kotlin as a first class language for Android development we decided to shift to Kotlin as it is more robust and code friendly than Java. Advantages of Kotlin over Java Kotlin is a null safe language. It changes all the instances used in the code to non nullable type thus it ensures that the developer don't get any nullPointerException. Kotlin provides the way to declare Extensive function similar to that of C#. We can use this function in the same way as we use the member functions of our class. Kotlin also provides support for Lambda function and other high order functions. For more details refer to this link. After seeing the above points it is now clear that Kotlin is much more effective than Java and there is harm in switching the code from Java to Kotlin. Lets now see the implementation in Susi Android. Implementation in Susi Android In the Susi Android App we are implementing the MVP design with Kotlin. We are converting the code by one activity each time from java to Kotlin. The advantage here with Kotlin is that it is totally compatible with java at any time. Thus allowing the developer to change the code bit by bit instead of all at once.Let's now look at SignUp Activity implementation in Susi Android. The SignUpView interface contains all the function related to the view. interface ISignUpView {   fun alertSuccess()   fun alertFailure()   fun alertError(message: String)   fun setErrorEmail()   fun setErrorPass()   fun setErrorConpass(msg: String)   fun setErrorUrl()   fun enableSignUp(bool: Boolean)   fun clearField()   fun showProgress()   fun hideProgress()   fun passwordInvalid()   fun emptyEmailError()   fun emptyPasswordError()   fun emptyConPassError() } The SignUpActivity implements the view interface in the following way. The view is responsible for all the interaction of user with the UI elements of the app. It does not contain any business logic related to the app. class SignUpActivity : AppCompatActivity(), ISignUpView {   var signUpPresenter: ISignUpPresenter? = null   var progressDialog: ProgressDialog? = null   override fun onCreate(savedInstanceState: Bundle?) {       super.onCreate(savedInstanceState)       setContentView(R.layout.activity_sign_up)       addListeners()       setupPasswordWatcher()       progressDialog = ProgressDialog(this@SignUpActivity)       progressDialog?.setCancelable(false)       progressDialog?.setMessage(this.getString(R.string.signing_up))       signUpPresenter = SignUpPresenter()       signUpPresenter?.onAttach(this)   }   fun addListeners() {       showURL()       hideURL()       signUp()   }   override fun onOptionsItemSelected(item: MenuItem): Boolean {       if (item.itemId == android.R.id.home) {           finish()           return true       }       return super.onOptionsItemSelected(item)   } Now we will see the implementation of models in Susi Android in Kotlin and compare it with Java. Lets First see the implementation in Java public class WebSearchModel extends RealmObject {   private String url;   private String headline;   private String body;   private String imageURL;   public WebSearchModel() {   }   public WebSearchModel(String url, String headline, String body, String imageUrl) {       this.url = url;       this.headline = headline;       this.body = body;       this.imageURL = imageUrl;   }   public void setUrl(String url) {       this.url = url;   }   public void setHeadline(String headline) {       this.headline = headline;   }   public void setBody(String body) {       this.body = body;   }   public void setImageURL(String imageURL) {       this.imageURL = imageURL;   }   public String getUrl() {       return url;   }   public String getHeadline() {       return headline;   }   public String…

Continue ReadingShifting from Java to Kotlin in SUSI Android

Invalidating user login using JWT in Open Event Orga App

User authentication is an essential part of Open Event Orga App (Github Repo), which allows an organizer to log in and perform actions on the event he/she organizes. Backend for the application, Open Event Orga Server sends an authentication token on successful login, and all subsequent privileged API requests must include this token. The token is a JWT (Javascript Web Token) which includes certain information about the user, such as identifier and information about from when will the token be valid, when will it expire and a signature to verify if it was tampered. Parsing the Token Our job was to parse the token to find two fields: Identifier of user Expiry time of the token We stored the token in our shared preference file and loaded it from there for any subsequent requests. But, the token expires after 24 hours and we needed our login model to clear it once it has expired and shown the login activity instead. To do this, we needed to parse the JWT and compare the timestamp stored in the exp field with the current timestamp and determine if the token is expired. The first step in the process was to parse the token, which is essentially a Base 64 encoded JSON string with sections separated by periods. The sections are as follows: Header ( Contains information about algorithm used to encode JWT, etc ) Payload ( The data in JWT - exp. Iar, nbf, identity, etc ) Signature ( Verification signature of JWT ) We were interested in payload and for getting the JSON string from the token, we could have used Android’s Base64 class to decode the token, but we wanted to unit test all the util functions and that is why we opted for a custom Base64 class for only decoding our token. So, first we split the token by the period and decoded each part and stored it in a SparseArrayCompat public static SparseArrayCompat<String> decode(String token) { SparseArrayCompat<String> decoded = new SparseArrayCompat<>(2); String[] split = token.split("\\."); decoded.append(0, getJson(split[0])); decoded.append(1, getJson(split[1])); return decoded; }   The getJson function is primarily decoding the Base64 string private static String getJson(String strEncoded) { byte[] decodedBytes = Base64Utils.decode(strEncoded); return new String(decodedBytes); } The decoded information was stored in this way 0={"alg":"HS256","typ":"JWT"}, 1={"nbf":1495745400,"iat":1495745400,"exp":1495745800,"identity":344} Extracting Information Next, we create a function to get the expiry timestamp from the token. We could use GSON or Jackson for the task, but we did not want to map fields into any object. So we simply used JSONObject class which Android provides. It took 5 ms on average to parse the JSON instead of 150 ms by GSON public static long getExpiry(String token) throws JSONException { SparseArrayCompat<String> decoded = decode(token); // We are using JSONObject instead of GSON as it takes about 5 ms instead of 150 ms taken by GSON return Long.parseLong(new JSONObject(decoded.get(1)).get("exp").toString()); }   Next, we wanted to get the ID of user from token to determine if a new user is logging in or an old one, so…

Continue ReadingInvalidating user login using JWT in Open Event Orga App

Presenters via Loaders in Open Event Organizer Android App

Open Event Organizer's App design follows Model View Presenter (MVP) architecture which facilitates heavy unit testing of the app. In this design pattern, each fragment/activity implements a view interface which uses a presenter interface to interact with a model interface. The presenter contains most of the data of the view. So it is very important to restore presenters after configuration changes like rotation. As on rotation, the complete activity is re-created hence all the fields are destroyed and as a result, everything is re-generated resulting in state loss on configuration change which is unexpected. Open Event Organizer App uses the loader to store/provide presenters to the activity/fragment. Loader survives configuration changes. The idea of using the loader to provide presenter is taken from Antonio Gutierrez's blog on "Presenters surviving orientation changes with loaders". The first thing to do is make a PresenterLoader<T> class extending Loader<T> where T is your presenter's base interface. The PresenterLoader class in the app looks like: public class PresenterLoader<T extends IBasePresenter> extends Loader<T> { private T presenter; ... @Override protected void onStartLoading() { super.onStartLoading(); deliverResult(presenter); } @Override protected void onReset() { super.onReset(); presenter.detach(); presenter = null; } public T getPresenter() { return presenter; } }   The methods are pretty clear from the names itself. Once this is done, now you are ready to use this loader in for your fragment/activity. Creating a BaseFragment or BaseActivity will be clever as then you don't have to add same logic everywhere. We will take a use case of an activity. A loader has a unique id by which it is saved in the app. Use unique id for each fragment/activity. Using the id, the loader is obtained in the app. Loader<P> loader = getSupportLoaderManager().getLoader(getLoaderId());   When creating for the first time, the loader is set up with the loader callbacks where we actually set a presenter logic. In the Organizer App, we are using dagger dependency injection for injecting presenter in the app for the first time. If you are not using the dagger, you should create PresenterFactory class containing create method for the presenter. And pass the PresenterFactory object to the PresenterLoader in onCreateLoader. In this case, we are using dagger so it simplifies to this: getSupportLoaderManager().initLoader(getLoaderId(), null, new LoaderManager.LoaderCallbacks<P>() { @Override public Loader<P> onCreateLoader(int id, Bundle args) { return new PresenterLoader<>(BaseActivity.this, getPresenterProvider().get()); } @Override public void onLoadFinished(Loader<P> loader, P presenter) { BaseActivity.this.presenter = presenter; } @Override public void onLoaderReset(Loader<P> loader) { BaseActivity.this.presenter = null; } });   getPresenterProvider method returns Lazy<Presenter> provider to ensure single presenter creation in the activity/fragment. The lifecycle to setup PresenterLoader in activity is onCreate and in the fragment is onActivityCreated. Use presenter field from next lifecycle that is start. If the presenter is used before the start, it creates null pointer exception. For example, if implementing with the BaseFragment, setup loader in onActivityCreated method. @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Loader<P> loader = getSupportLoaderManager().getLoader(getLoaderId()); if (loader == null) { initLoader(); } else { presenter = ((PresenterLoader<P>) loader).getPresenter(); } }…

Continue ReadingPresenters via Loaders in Open Event Organizer Android App