Nucleus is an Android library, which utilizes the Model-View-Presenter pattern to properly connect background tasks with visual parts of an application.

Overview

Nucleus

Deprecation notice

Nucleus is not under develpment anymore. It turns out that Redux architecture scales way better than MVP/MVI/MVVM/MVxxx and I do not see further development of Nucleus valuable.

I recommend considering ReKotlin as a simple Redux implementation.

Info

Android Arsenal Maven Central

Nucleus is a simple Android library, which utilizes the Model-View-Presenter pattern to properly connect background tasks with visual parts of an application.

MVP introduction article

Wiki

Introduction

Some time has passed since Model-View-Presenter and RxJava completely superseded Loader and AsyncTask in our applications.

But there are still some defects in our applications even when using such advanced technologies:

  • An application is unable to continue a background task execution after a configuration change.
  • An application does not automatically restart a background task after a process restart.

While most applications work without such capabilities, their absence is an obvious bug that just sits there and waits for a user who pressed "Login" button while being in a subway and switched to another application because his network connection was too slow. Bugs that almost any application produce in such cases are numerous.

Android docs are covering such problems very briefly, take a look at: Processes and Threads - 4. Background process "If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state."

This is not true - there WILL be a visible effect because we're not restoring background tasks. The application will restore it's visual state, but it will forget what it is doing. So, if an application restores a progress bar, but does not restore the background task itself - a user will see the usual "progress bar forever" bug.

Nucleus' main features

  • In case of configuration change Nucleus automatically re-attaches all running background tasks to the new View. The application will not forget what it is doing.

  • In case of process restart Nucleus automatically restarts background tasks. Even when running on a low memory device or waiting for a long running background task completion, the application is still reliable.

  • The entire library has been built keeping The Kiss Principle in mind. Anyone can read and understand it easily.

  • The library does not depend on Dagger, you don't need to write a whole class just to inject a presenter. One annotation is all you need. Despite presenters are instantiated without Dagger, their dependencies can still be injected.

  • Presenter in Nucleus is an external class that does not depend on View, this automatically prevents any troubles that are connected with activity context leaks.

History

At the moment of the first release, the library main idea was to be the simplest possible MVP implementation.

A couple of months later, I finally realized that RxJava has became the tool number one for smart background threads handling, so RxPresenter appeared. Since that moment, the main focus shifted in the direction of RxJava support.

The correct lifecycle handling was something that seemed obvious to me from the beginning, so I did not make an accent on this feature in the library description. However, since those times, more MVP libraries appeared, now I need to differentiate Nucleus from other implementations. The library description became: "Nucleus is a simple Android library, which utilizes the Model-View-Presenter pattern to properly connect background tasks with visual parts of an application."

Include this library:

dependencies {
    compile 'info.android15.nucleus:nucleus:6.0.0'
}

For additional view classes NucleusSupportFragment, NucleusFragmentActivity include:

dependencies {
    compile 'info.android15.nucleus:nucleus-support-v4:6.0.0'
}

For additional view class NucleusAppCompatActivity include:

dependencies {
    compile 'info.android15.nucleus:nucleus-support-v7:6.0.0'
}

ProGuard config:

-keepclassmembers class * extends nucleus.presenter.Presenter {
    <init>();
}

For RxJava 2:

dependencies {
    compile 'info.android15.nucleus5:nucleus:7.0.0'
}

For additional view classes NucleusSupportFragment, NucleusFragmentActivity include:

dependencies {
    compile 'info.android15.nucleus5:nucleus-support-v4:7.0.0'
}

For additional view class NucleusAppCompatActivity include:

dependencies {
    compile 'info.android15.nucleus5:nucleus-support-v7:7.0.0'
}

Hint: you can just copy/paste those classes code into ANY View class to keep your View classes hierarchy as you like to.

ProGuard config:

-keepclassmembers class * extends nucleus5.presenter.Presenter {
    <init>();
}
Comments
  • When to destroy activity's presenter

    When to destroy activity's presenter

    We need a more reliable way to detect when to destroy activity's presenter.

    Here is where the issue that started the discussion: https://github.com/konmik/nucleus/issues/42#issuecomment-204233175

    TL/DR: activity's finish() can be called some time after onPause, so this code will leak the activity's presenter: https://github.com/konmik/nucleus/blob/master/nucleus/src/main/java/nucleus/view/NucleusActivity.java#L76

    Possible solutions:

    a) Leverage retained fragments. This will solve the presenter destruction issue but we will leak background tasks sometimes.

    b) Extend PresenterLifecycleDelegate lifecycle to explicitly call onDestroy.

    c) Install system-wide lifecycle listener registerActivityLifecycleCallbacks.

    opened by konmik 51
  • RxJava2 Support

    RxJava2 Support

    Hello Konstantin,

    Do your long-term plans for the library include the adoption of RxJava v2? It had recently reached RC1, which means the API should be quite stable by now.

    If yes, perhaps there's sense in creating another branch of nucleus containing preparations/adaptations for the new RxJava?

    I might be able to help with some crude initial conversion if needed.

    opened by Dev-iL 21
  • Nucleus 2.0.0

    Nucleus 2.0.0

    Is currently under testing.

    I hope that it will be production-ready in the middle of August.

    Want to join beta?

    compile "info.android15.nucleus:nucleus:2.0.0-beta8"
    

    Primary goals are:

    • Make RxPresenter to be completely usable without getView() - 100% done!
    • Replace OperatorSemaphore with standard RxJava operators. - 100% done!
    • Simplify internal structure: remove manager and helper. - 100% done!
    • Move all tests into unit tests to be testable without device. - 80%.

    Update: a little note about the new rx.Single. rx.Single is awesome and I'm already playing with it. However, creation of additional methods for it will cause much more confusion than advantage (I already implemented this, but dropped the implementation because it just looks bulky, imagine stranger method names like deliverSingleCache, restartableSingleCache). The right way to handle rx.Single in Nucleus is to cast it to Observable.

    opened by konmik 16
  • onRestoreInstanceState() should be called before onResume()

    onRestoreInstanceState() should be called before onResume()

    Hey, thanks for the library.

    Several times I caught the exception from here:

        /**
         * {@link android.app.Activity#onCreate(Bundle)}, {@link android.app.Fragment#onCreate(Bundle)}, {@link android.view.View#onRestoreInstanceState(Parcelable)}.
         */
        public void onRestoreInstanceState(Bundle presenterState) {
            if (presenter != null)
                throw new IllegalArgumentException("onRestoreInstanceState() should be called before onResume()");
            this.bundle = ParcelFn.unmarshall(ParcelFn.marshall(presenterState));
        }
    

    The exception message seems too low-level for any library user. After some source code exploring, I found, that we can't call getPresenter() in any point before onResume(). Thus, for instance, method references like

    private SomeView.ClickListener mViewClickListener = getPresenter()::viewClicked;

    can crash the app, because getPresenter() is obviously called before onCreate.

    Also I caught the crash several times in other callbacks, probably, in FragmentStatePagerAdapter (which can call onRestoreInstanceState before or even without onCreate, sorry, I don't remember a lot of details)

    Is it reasonable to:

    1. Replace throwing exception to some warning message, leaving developer's responsibility to save/restore state?
    2. (more complex) to separate Presenter constructor and onCreate() methods, so that some time, before onCreate call, Presenter can exist without state restored?
    opened by yankeppey 15
  • Fragment might lose the presenter id

    Fragment might lose the presenter id

    If a fragments (PresenterLifecycleDelegates) onSaveInstanceState method gets called before the PresenterFactory is set, it will not save its presenter id in the result bundle.

    I have a NucleusSupportFragment for which I set the PresenterFactory in onActivityCreated. When I detach that fragment (without destroying the presenter) and rotate the screen once, the presenter id will be saved in the bundle . After another rotate however the presenter id will not be saved anymore because getPresenter() will not restore the Presenter without a set Factory.

    opened by inv3rse 14
  • NucleusActionBarActivity with support library 26

    NucleusActionBarActivity with support library 26

    Hi,

    I've recently updated my support library to version 26.0.1 which does not include the deprecated ActionBarActivity class. This causes an error while creating a release APK file saying that the NucleusActionBarActivity can't be compiled since it has unknown method references:

    Warning:nucleus.view.NucleusActionBarActivity: can't find referenced method 'boolean isChangingConfigurations()' in program class nucleus.view.NucleusActionBarActivity

    I've tried removing only this class with gradle's 'exclude', but with no success. So currently I'm adding the sources without the problematic class directly into my app sources...

    I think this class should be removed from nucleus since it extends a class that has been removed from the android support library.

    opened by aralizer 13
  • leaks when using with addView/removeView

    leaks when using with addView/removeView

    I'm attempting to use a NucleusLayout as the base class for my view. Because the view life cycle is not tied to the activity life cycle, Nucleus is creating a new Presenter each time addView() is used, but not destroying it when removeView() is used. Due to the way PresenterHelper and NucleusLayour are implemented I am unsure how to fix this issue without duplicating the classes in their entirety.

    question 
    opened by scriptacus 13
  • Why no delivery() method?

    Why no delivery() method?

    Hi there! I don't understand how to implement a case where a data should be delivered without caching (like PublishSubject or EventBus event). For example, I have a UserAddedEvent event. I need to handle it in my presenter only if there is a view attached (I can skip it otherwise).

    add(userAdded()
        .compose(deliverLatestCache()) 
        .subscribe(split(View::addUser)));
    
    opened by Zeliret 12
  • Adds Presenter Factory

    Adds Presenter Factory

    This moves the logic of reflectively creating the presenter into a presenter factory, so that that functionality can be customized.

    In my case, I'm using Dagger to inject dependencies, and using a presenter factory allows me to inject the dependencies through the presenter constructor, without having to use a pseudo-singleton injector class.

    The superclasses include the default ReflectionPresenterFactory, so they have the same out of the box functionality, but by extracting that logic out of the PresenterHelper, the user is offered much more flexibility.

    Note: I'm not sure how you're handling versioning, so I changed the dependencies in the support libraries and the examples to point to the snapshot version that I made and installed locally. I didn't include that in this PR since that's a change that shouldn't go into production.

    opened by rharter 12
  • Question regarding getView() and reference the View in the presenter.

    Question regarding getView() and reference the View in the presenter.

    This is simply a question, please label it as such.

    I understand getView() is deprecated. The docs comments on the method mention the following:

    /**
     * Please, use restartableXX and deliverXX methods for pushing data from RxPresenter into View.
     */
    

    What if an Android Context is needed, in cases like parsing a local .json file from assets?

    For example:

    InputStream is = getView().getAssets().open("data.json");
    

    What is the best practice for this particular case?

    opened by Orbyt 11
  • [Q] How to work with ContentProvider?

    [Q] How to work with ContentProvider?

    I'm a RxJava newbie. In my opinion, Retrofit, RxJava and this library is the best practice to implement a client-server communication in Android. Retrofit and RxJava makes easily to call and handle (asynchronous) HTTP requests, Nucleus makes safety to implement the callback in the life circle of Activity or Fragment. Data could come from either remote server or local data base. In remote server side, I have an awesome Retrofit library. In local data base, I could use SQLite Database and ContentProvider. I haven't found the best way to make an asynchronous query to ContentProvider that use RxJava and implement callback with Nucleus yet. Would you mind suggesting me?

    opened by hnvn 11
  • Crashes when starting a new activity using kotlin

    Crashes when starting a new activity using kotlin

    I tried with extending AppCompactActivity it works. But with nucleusappcompactactivity crashes.

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dayanithi.supercamping/com.dayanithi.supercamping.activities.admin.AdminLoginClass}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2760) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2821) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:181) at android.app.ActivityThread.main(ActivityThread.java:6295) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:793) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference at android.content.ContextWrapper.getResources(ContextWrapper.java:86) at android.view.ContextThemeWrapper.getResourcesInternal(ContextThemeWrapper.java:127) at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:121) at android.support.v7.app.AppCompatActivity.getResources(AppCompatActivity.java:542) at android.view.Window.getDefaultFeatures(Window.java:1627) at android.view.Window.(Window.java:668) at com.android.internal.policy.PhoneWindow.(PhoneWindow.java:333) at com.android.internal.policy.PhoneWindow.(PhoneWindow.java:341) at android.app.Activity.attach(Activity.java:6797)

    opened by dayanithi06 0
  • clear the delivery cache

    clear the delivery cache

    Is there a way to clear the delivery cache used by deliverReply etc - for example if the underlying data query has changed and we want to forget the history?

    opened by maximosipov 0
  • Confusion about restartables and the Activity lifecycle

    Confusion about restartables and the Activity lifecycle

    I'm either confused on the wording of the Javadocs, or restartable is not behaving how I would expect. I'm using restartableLatestCache, which from dissecting the Javadocs indicates that it will emit the last onNext value each time it is started, plus any new onNext values if they are emitted in the future. A restartable will re-subscribe after a "process restart". I'm unsure exactly what entails a process restart, but I assumed that meant when an activity is being recreated for whatever reason.

    However, a simple pause/resume of the activity via backgrounding the app and bringing it back to the foreground triggers the restartable to fire off its cached value without a subsequent call to start. I didn't think that would qualify as a "process restart".

    So if someone would be so kind, could you explain to me if this is working as intended, and if so, qualify what a "process restart" means so I know what behavior to expect in the future? How could I achieve a "latestCache"-like result, but only if the Activity has been re-created (destroy/create)?

    question 
    opened by jrobinson3k1 3
  • add DeliverLatest

    add DeliverLatest

    Hi.

    DeliverLatest completes automatically when the source observable is done.

    In my case I have a Repository which emits data from Cache, DB and API. I can emit from Cache first, then from DB and API. It's a sequence of distinct items.

    Why I'm not using deliveryLatestCache?

    • to avoid keeping subscription to viewObservable
    • to avoid getting the last cache from observable, cause it can be incorrect (old)

    Why I'm not using deliveryFirst?

    • it will emit only first item (from Cache)

    Why I'm not using deliveryReplay?

    • the item sequence in ReplaySubject might be outdated and I want just to get the new sequence from Repository (it's already got own cache)
    opened by kanat 2
  • Active? [question]

    Active? [question]

    Hello, first thanks for great looking library, I would like to ask if you still maintain this library? Because I plan start using nucleus, but at the same time I am little curious. Most of work you did was done last year and first months of this year. So that's why I have some doubts.

    Thank you for your answer! Seidak

    question 
    opened by Seidak 2
  • Q/A (was: Some doubts)

    Q/A (was: Some doubts)

    Hi!

    I'm working on an app I want to use Nucleus for MVP+Rx.

    I have some doubts, and I couldn't find any solution in the documentation/wiki. Could you please help me?:

    1. How can I use two instances of the same view, and make each of them have their own instances of their presenters? Is it possible by telling the PresenterStorage with ID to use? Or by any other way?

    2. Why is the presenter being destroyed and pointed to null in the onPause method instead of doing so in onDestroy? The documentation seems to be out of date. What if I want to stack several activities of the same type, and want them to keep their presenters while not destroyed by the system? Is that working because you pass isFinishing() to the delegate?

    3. I think we need more documentation about the restartable* methods in RxPresenter. I know that it is documented in the code with Javadoc, but I think it would be great to add some explanation in the wiki. Something like the deliver* methods documentation (btw, some of them seem to be out of date since you released version 2.0.1).

    Thank you very much. Your library is great. Cheers, M.

    question 
    opened by mheras 64
Owner
Konstantin Mikheev
https://www.linkedin.com/in/konstantin-mikheev-9a5099ab/
Konstantin Mikheev
A Job Queue specifically written for Android to easily schedule jobs (tasks) that run in the background, improving UX and application stability.

This Project is Deprecated! Thanks to everybody who've used Android Priority JobQueue. It was designed in a world where there was no JobScheduler, RxJ

Yigit Boyar 3.4k Dec 31, 2022
a MVP library for Android favoring a stateful Presenter

DEPRECATED - no longer actively maintained ThirtyInch - a MVP library for Android This library adds Presenters to Activities and Fragments. It favors

HCI @ gcx 1k Dec 15, 2022
A data-binding Presentation Model(MVVM) framework for the Android platform.

PLEASE NOTE, THIS PROJECT IS NO LONGER BEING MAINTAINED. As personal time contraints, I am currently unable to keep up. Please use official android da

RoboBinding open source 1.3k Dec 9, 2022
Intellij Idea, Android Studio plugin for generating Kotlin data classes from JSON. Helps to avoid writing boilerplate code for model classes. Supports annotations for Gson, Moshi, Jackson.

JSONToKotlinClass Intellij Idea, Android Studio plugin. Plugin generates Kotlin data classes from JSON text. It can find inner classes in nested JSON.

Vasily 139 Dec 21, 2022
A plugin system that runs like a browser, but instead of load web pages, it load apk plugins which runs natively on Android system.

Android Dynamic Loader Android Dynamic Loader is a plugin system. The host application is like a browser, but instead of load web pages, it load plugi

Tu Yimin 1.4k Dec 28, 2022
VasSonic is a lightweight and high-performance Hybrid framework developed by tencent VAS team, which is intended to speed up the first screen of websites working on Android and iOS platform.

VasSonic: A Lightweight And High-performance Hybrid Framework VasSonic is a lightweight and high-performance Hybrid framework developed by tencent VAS

Tencent 11.6k Dec 30, 2022
A small, yet full-featured framework that allows building View-based Android applications

Conductor A small, yet full-featured framework that allows building View-based Android applications. Conductor provides a light-weight wrapper around

BlueLine Labs 3.9k Jan 6, 2023
dexposed enable 'god' mode for single android application.

What is it? Dexposed is a powerful yet non-invasive runtime AOP (Aspect-oriented Programming) framework for Android app development, based on the work

Alibaba 4.5k Dec 28, 2022
Kick-starts Android application development.

Synopsis If you've made it here, chances are you are not quite as satisfied with the Android application framework as you could be. Same for us, that'

Matthias Käppler 1.3k Dec 4, 2022
Moxy is MVP library for Android

Moxy This Moxy repository is deprecated and no longer supported. Please migrate to the actual version of the Moxy framework at Moxy communuty repo. De

Arello Mobile 1.6k Dec 28, 2022
Minimal UI library for Android inspired by React

Anvil - reactive views for Android Anvil is a small Java library for creating reactive user interfaces. Originally inspired by React, it suits well as

null 1.4k Dec 23, 2022
A Mosby based VIPER library for Android

Moviper A Mosby based VIPER library for Android Why Moviper? You got tired because of fact that your Activities and Fragments were becoming god classe

Mateusz Koślacz 78 Nov 29, 2022
Android app built with MVP architectural approach and uses Marvel Comics API that allows developers everywhere to access information about Marvel's vast library of comics. :zap:

Villains & Heroes Android app built with MVP architectural approach and uses Marvel Comics API that allows developers everywhere to access information

André Mion 53 Jul 13, 2022
Crossword library for Android

Ararat Ararat is a crossword library for Android, written for and used by alphacross. It includes: Parsers for various formats CrosswordRenderer, whic

Akop Karapetyan 28 Oct 3, 2022
The most complete and powerful data-binding library and persistence infra for Kotlin 1.3, Android & Splitties Views DSL, JavaFX & TornadoFX, JSON, JDBC & SQLite, SharedPreferences.

Lychee (ex. reactive-properties) Lychee is a library to rule all the data. ToC Approach to declaring data Properties Other data-binding libraries Prop

Mike 112 Dec 9, 2022
A lightweight, good expandability Android library used for displaying different pages like loading, error, empty, timeout or even your custom page when you load a page

中文 | English LoadSir ?? ?? LoadSir是一个高效易用,低碳环保,扩展性良好的加载反馈页管理框架,在加载网络或其他数据时候,根据需求切换状态页面, 可添加自定义状态页面,如加载中,加载失败,无数据,网络超时,如占位图,登录失效等常用页面。可配合网络加载框架,结合返回 状态

KingJA 3.3k Dec 21, 2022
Android part of the Android Studio(IntellijIDEA) OkHttp Profiler plugin

OkHttpProfiler Android Library Created by LocaleBro.com - Android Localization Platform The OkHttp Profiler plugin can show requests from the OkHttp l

Ievgenii 261 Dec 8, 2022
Android common lib, include ImageCache, HttpCache, DropDownListView, DownloadManager, Utils and so on

android-common-lib 关于我,欢迎关注 微博:Trinea 主页:trinea.cn 邮箱:trinea.cn#gmail.com 微信:codek2 主要包括:缓存(图片缓存、预取缓存、网络缓存)、公共View(下拉及底部加载更多ListView、底部加载更多ScrollView、

Trinea 5k Dec 30, 2022
LiteOrm is a fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line of code efficiently.

#LiteOrm:Android高性能数据库框架 A fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line

马天宇 1.5k Nov 19, 2022