A Model-View-Presenter / Model-View-Intent library for modern Android apps

Overview

Mosby

A Model-View-Presenter and Model-View-Intent library for Android apps.

Build Status

Dependency

dependencies {

  compile 'com.hannesdorfmann.mosby3:mvi:3.1.1' // Model-View-Intent
  // or
  compile 'com.hannesdorfmann.mosby3:mvp:3.1.1' // Plain MVP
  // or
  compile 'com.hannesdorfmann.mosby3:viewstate:3.1.1' // MVP + ViewState support
}

Additional modules:

dependencies {

  // MVP + ViewState + LCE Views
  compile 'com.hannesdorfmann.mosby3:mvp-lce:3.1.1'

  // Null Object Presenter for MVP
  compile 'com.hannesdorfmann.mosby3:mvp-nullobject-presenter:3.1.1'
  
  // Queuing Presenter for MVP
  compile 'com.hannesdorfmann.mosby3:mvp-queuing-presenter:3.1.1'
}

SNAPSHOT:

dependencies {

  compile 'com.hannesdorfmann.mosby3:mvi:3.1.2-SNAPSHOT'

  compile 'com.hannesdorfmann.mosby3:mvp:3.1.2-SNAPSHOT'
  compile 'com.hannesdorfmann.mosby3:viewstate:3.1.2-SNAPSHOT'

  compile 'com.hannesdorfmann.mosby3:mvp-lce:3.1.2-SNAPSHOT'
  compile 'com.hannesdorfmann.mosby3:mvp-nullobject-presenter:3.1.2-SNAPSHOT'
  compile 'com.hannesdorfmann.mosby3:mvp-queuing-presenter:3.1.2-SNAPSHOT'
}

You also have to add the url to the snapshot repository:

allprojects {
  repositories {
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
  }
}

Documentation

See the project website.

For Model-View-Intent check out this blog post series.

Changelog

The changelog can be found in the release section

Migrating

In Mosby 3.0 we have changed the package name from com.hannesdorfmann.mosby to com.hannesdorfmann.mosby3 (note the 3 at the end). Migrating a Mosby 2.x based app to Mosby 3.0 should be straightforward: Just replace all import statements of your app in android studio with Edit -> Find -> Replace in Path ... and set find import com.hannesdorfmann.mosby replace with import com.hannesdorfmann.mosby3. There were also some minor API changes (see changelog), but most apps should be fine by replacing the import statements.

Conductor

Mosby has a plugin for Conductor. You can find it here: https://github.com/sockeqwe/mosby-conductor

License

Copyright 2015 Hannes Dorfmann

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Async set fragment when app invisible

    Async set fragment when app invisible

    When I receive a response from the server, I create a new fragment. If the application is minimized I get an error

    io.reactivex.exceptions.OnErrorNotImplementedException: Can not perform this action after onSaveInstanceState

        public void render(LogoViewState logoViewState) {
            if (logoViewState instanceof LogoViewState.LoadingState) {
                statusView.setText("Connecting...");
            } else if (logoViewState instanceof LogoViewState.DataState) {
                statusView.setText(logoViewState.toString());
                if (getActivity() != null) {
                    ((MainActivity)getActivity()).showHomeFragment();
                }
            }
        }
    
    opened by DrobyshevAlex 26
  • Great library, but not quite

    Great library, but not quite

    Hi! Great library, but I think it is not radical enough and doesn't solve main problem: Activities and Fragments. Fragments are crap and so are Activities. So if you want to make good MVP/MVC/MVVP library for android, you have to discard any Fragment and Activity usage. More on that can be read here, for example: https://corner.squareup.com/2014/10/advocating-against-android-fragments.html

    For last week I'm building something very similar in concept to your library — basically the liberal port of iOS's ViewControllers to Android: http://www.youtube.com/watch?v=4S4vr23qB7k It have ViewController, NavigationController and TabController with backstack and up button support.

    Example of my library: https://github.com/virl/vcdroid

    opened by virl 26
  • Can't build samples

    Can't build samples

    Today I cloned your repo and now I'm trying to run samples. I don't know why, but gradle can't build them. I'm receiving following errors:

    e.g. sample project

    /mosby/mvp/src/main/java/com/hannesdorfmann/mosby/mvp/MvpActivity.java Error:(20, 32) error: cannot find symbol class MosbyActivity Error:(29, 67) error: cannot find symbol class MosbyActivity /mosby/mvp/src/main/java/com/hannesdorfmann/mosby/mvp/layout/MvpFrameLayout.java Error:(7, 19) error: package butterknife does not exist /mosby/mvp/src/main/java/com/hannesdorfmann/mosby/mvp/layout/MvpLinearLayout.java Error:(7, 19) error: package butterknife does not exist /mosby/mvp/src/main/java/com/hannesdorfmann/mosby/mvp/layout/MvpRelativeLayout.java Error:(7, 19) error: package butterknife does not exist /mosby/mvp/src/main/java/com/hannesdorfmann/mosby/mvp/lce/LceAnimator.java ...

    I'm using Android Studio 1.2 Build 3. Why can't I build them? Can you help me?

    opened by ziem 26
  • Stop accessing non-public fields in Fragment

    Stop accessing non-public fields in Fragment

    After updating the support library of my project to the new AndroidX scheme, the app started crashing after calling this method: BackstackAccessor.isFragmentOnBackStack(Fragment()) Crash: java.lang.IllegalAccessError: Method 'boolean androidx.fragment.app.Fragment.isInBackStack()' is inaccessible to class 'androidx.core.app.BackstackAccessor'

    After some investigation, I found that the issue is this file: https://github.com/sockeqwe/mosby/blob/master/utils-fragment/src/main/java/android/support/v4/app/BackstackAccessor.java which is accessing a non-public field by "faking" the package.

    As well as being a bad practice, this stops working after migrating to AndroidX due to the change of package names.

    Ideally this should be reverted to the commented-out version of the code still existing in the linked file.

    opened by mbarta 25
  • Production app with Mosby : RuntimeException: Parcel android.os.Parcel Unmarshalling unknown type code 47068 at offset 304

    Production app with Mosby : RuntimeException: Parcel android.os.Parcel Unmarshalling unknown type code 47068 at offset 304

    I can not reproduce it, As it was one some random users device, I just caught it in Crashlytics. Here is the crashlytics report ( with whole exception and other device/android details ) http://crashes.to/s/de64b446301/details

    Does it have anything to do with ParclablePlease ( or it's pro-guard configuration )? Or Any other Mosby components ?

    This is the first time such error has occurred and it doesn't see on a new device. it is a kind of old device. App works fine in many devices as I can see in the analytcis and crashlytics.

    Some discussion in similar Stack Overflow with similar question
    http://stackoverflow.com/questions/13997550/unmarshalling-errors-in-android-app-with-custom-parcelable-classes
    
    Pasting the stack trace here as well
    

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.timesbuzz.news/com.timesbuzz.news.MainActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@40da0ad0: Unmarshalling unknown type code 47068 at offset 304 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2205) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2240) at android.app.ActivityThread.access$600(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:156) at android.app.ActivityThread.main(ActivityThread.java:4987) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(NativeStart.java) Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@40da0ad0: Unmarshalling unknown type code 47068 at offset 304 at android.os.Parcel.readValue(Parcel.java:1926) at android.os.Parcel.readMapInternal(Parcel.java:2098) at android.os.Bundle.unparcel(Bundle.java:223) at android.os.Bundle.getParcelable(Bundle.java:1158) at android.app.Activity.onCreate(Activity.java:900) at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:255) at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:122) at com.hannesdorfmann.mosby.MosbyActivity.onCreate(MosbyActivity.java:38) at com.hannesdorfmann.mosby.mvp.MvpActivity.onCreate(MvpActivity.java:34) at com.timesbuzz.news.MainActivity.onCreate(MainActivity.java:58) at android.app.Activity.performCreate(Activity.java:4538) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2161) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2240) at android.app.ActivityThread.access$600(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:156) at android.app.ActivityThread.main(ActivityThread.java:4987) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(NativeStart.java)

    bug 
    opened by javajack 25
  • MVI: Eager Observable like Observable.just() are subscribed to late in MviBasePresenter

    MVI: Eager Observable like Observable.just() are subscribed to late in MviBasePresenter

    Seems like an internal bug with eager Observables when establishing the MVI chain.

    http://stackoverflow.com/questions/43680876/losing-events-during-rxjava-subscribeon

    bug mvi 
    opened by sockeqwe 20
  • Unit test presenters

    Unit test presenters

    Hi, I was wondering if you plan to demo unit testing (on the jvm) your presenters. This would be good to test the RXJava Observables. So far I just see instrumentation tests in Mosby samples.

    Thanks, Igor

    opened by IgorGanapolsky 20
  • Add support for DialogFragment

    Add support for DialogFragment

    It's almost exactly the same as regular Fragment, I'm not sure if there is an easy way to share the boilerplate code between them.

    If anyone does try to add support for DialogFragments, this will keep the dialog on the screen for orientation changes.

        @Override
        public void onDestroyView() {
            if (getDialog() != null && getRetainInstance()) {
                getDialog().setDismissMessage(null);
            }
            ButterKnife.reset(this);
            super.onDestroyView();
        }```
    
    enhancement 
    opened by fahimk 19
  • Unable to build with enabled proguard

    Unable to build with enabled proguard

    Mosby Version: 3.0.2

    Expected behavior Should build with proguard

    Actual behavior (include a stacktrace if crash) Not building with proguard:

    Warning:com.hannesdorfmann.mosby3.mvp.delegate.FragmentMvpDelegateImpl: can't find referenced class edu.umd.cs.findbugs.annotations.SuppressFBWarnings
    Warning:com.hannesdorfmann.mosby3.PresenterManager: can't find referenced class edu.umd.cs.findbugs.annotations.SuppressFBWarnings
    Warning:com.hannesdorfmann.mosby3.mvp.delegate.ViewGroupMvpDelegateImpl: can't find referenced class edu.umd.cs.findbugs.annotations.SuppressFBWarnings
    Warning:com.hannesdorfmann.mosby3.mvp.delegate.ActivityMvpDelegateImpl: can't find referenced class edu.umd.cs.findbugs.annotations.SuppressFBWarnings
    Warning:there were 4 unresolved references to classes or interfaces.
    

    Steps to reproduce the behavior or link to a sample repository Build with enabled proguard

    opened by dawidhyzy 17
  • onNewViewStateInstance called every time when returning Fragment from backstack

    onNewViewStateInstance called every time when returning Fragment from backstack

    There is how I put fragment in backstack

        private fun <T : Fragment> putContentFragment(fragment: T): T {
            val fragmentTag = fragment.javaClass.name
            logger.debug("putContentFragment: tag: {}", fragmentTag)
    
            fragmentMng.beginTransaction()
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .replace(R.id.content_frame_layout, fragment, fragmentTag)
                    .addToBackStack(fragmentTag)
                    .commit()
    
            return fragment
        }
    

    And there is how I navigateBack to the previous Fragment:

        override fun navigateBack() {
            if (fragmentMng.backStackEntryCount > 1) {
                callback.forceBackPressed() // it calls super.onBackPressed() for MainActivity
            } else {
                callback.finish() // it calls finish() for MainActivity
            }
        }
    

    I also call setRetainInstance(true) on my Fragment. Class variables are restored as they must. I test it via incrementing int var every onViewCreated():

        private var someValue = 0
    
        override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            someValue++
            logger.debug("someValue: {}", someValue)
            ...
        }
    
        override fun createViewState() = NotesViewState()
    

    UPD

    Sometimes onNewViewStateInstance() called, sometimes not.

    For example, I navigate to new fragment and then return back to the previous: image onNewViewStateInstance called only for new NoteFragment and NotesFragment was restored.

    Okay. Lets restart my app and do the same: image

    There it is: onNewViewStateInstance called every time when returning Fragment from backstack

    opened by alexandr2levin 17
  • IllegalArgumentException: class java.lang.Object is not an interface

    IllegalArgumentException: class java.lang.Object is not an interface

    This stacktrace is shown when attempting to detach an Activity that uses MvpNullObjectBasePresenter but does not implement any Interface

    java.lang.RuntimeException: Unable to destroy activity {com.mypackage/com.mypackage.ui.account.AccountActivity}: java.lang.IllegalArgumentException: class java.lang.Object is not an interface
    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3831)
    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849)
            at android.app.ActivityThread.-wrap5(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5422)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
            Caused by: java.lang.IllegalArgumentException: class java.lang.Object is not an interface
    at java.lang.reflect.Proxy.getProxyClass(Proxy.java:147)
            at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:228)
            at com.hannesdorfmann.mosby.mvp.NoOp.of(NoOp.java:41)
            at com.hannesdorfmann.mosby.mvp.MvpNullObjectBasePresenter.detachView(MvpNullObjectBasePresenter.java:42)
            at com.hannesdorfmann.mosby.mvp.delegate.MvpInternalDelegate.detachView(MvpInternalDelegate.java:70)
            at com.hannesdorfmann.mosby.mvp.delegate.ActivityMvpDelegateImpl.onDestroy(ActivityMvpDelegateImpl.java:71)
            at com.hannesdorfmann.mosby.mvp.MvpActivity.onDestroy(MvpActivity.java:47)
            at android.app.Activity.performDestroy(Activity.java:6422)
            at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1142)
            at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3818)
            at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849) 
            at android.app.ActivityThread.-wrap5(ActivityThread.java) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:148) 
            at android.app.ActivityThread.main(ActivityThread.java:5422) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
    

    I feel that the error message could be improved by checking in MvpNullObjectBasePresenter if the class to be detached implements MvpView, but I'm not sure if that's the best way, I haven't dig too much into Mosby code

    Class<V> viewClass = (Class<V>) types[0];
    //add check here? Throw an Exception if it doesn't implement MvpView?
    view = NoOp.of(viewClass);
    

    Also, this error is only happening in release version with ProGuard. It's been in development like that for months and it hasn't crashed.

    opened by Maragues 16
  • Improve GRADLE build Performance

    Improve GRADLE build Performance

    Configuration on demand. Configuration on demand tells Gradle to configure modules that only are relevant to the requested tasks instead of configuring all of them. We can enable this feature by setting org.gradle.configureondemand=true.

    ===================== If there are any inappropriate modifications in this PR, please give me a reply and I will change them.

    opened by hongdongni 0
  • Fatal Exception: java.lang.IllegalArgumentException: The generic type <V extends MvpView> must be the first generic type argument of class

    Fatal Exception: java.lang.IllegalArgumentException: The generic type must be the first generic type argument of class

    Mosby Version: 3.1.1

    Expected behavior Not to crash.

    Actual behavior (include a stacktrace if crash)

    Fatal Exception: java.lang.IllegalArgumentException: The generic type <V extends MvpView> must be the first generic type argument of class PostRegisterPresenter (per convention). Otherwise we can't determine which type of View this Presenter coordinates.
           at com.hannesdorfmann.mosby3.mvp.MvpNullObjectBasePresenter.<init>(MvpNullObjectBasePresenter.java:73)
           at mypackage.com.sdk.ui.base.BasePresenter.<init>(BasePresenter.java:15)
           at mypackage.com.sdk.ui.flow.register.PostRegisterPresenter.<init>(PostRegisterPresenter.java:16)
           at mypackage.com.sdk.core.di.module.PresenterModule.providePostRegisterPresenter(PresenterModule.java:227)
           at mypackage.com.sdk.core.di.module.PresenterModule_ProvidePostRegisterPresenterFactory.providePostRegisterPresenter(PresenterModule_ProvidePostRegisterPresenterFactory.java:29)
           at mypackage.com.sdk.core.di.component.DaggerLiveDIComponent.injectPostRegisterFragment(DaggerLiveDIComponent.java:786)
           at mypackage.com.sdk.core.di.component.DaggerLiveDIComponent.inject(DaggerLiveDIComponent.java:516)
           at mypackage.com.sdk.ui.flow.register.PostRegisterFragment.injectFragment(PostRegisterFragment.java:76)
           at mypackage.com.sdk.ui.base.BaseFragment.onAttach(BaseFragment.java:115)
           at androidx.fragment.app.Fragment.onAttach(Fragment.java:1603)
           at androidx.fragment.app.Fragment.performAttach(Fragment.java:2673)
           at androidx.fragment.app.FragmentStateManager.attach(FragmentStateManager.java:263)
           at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1182)
           at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1255)
           at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1138)
           at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:136)
           at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2001)
           at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1959)
           at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
           at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
           at android.os.Handler.handleCallback(Handler.java:873)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loop(Looper.java:214)
           at android.app.ActivityThread.main(ActivityThread.java:7094)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
    
    Caused by java.lang.ClassCastException: libcore.reflect.TypeVariableImpl cannot be cast to java.lang.Class
           at com.hannesdorfmann.mosby3.mvp.MvpNullObjectBasePresenter.<init>(MvpNullObjectBasePresenter.java:58)
           at mypackage.com.ui.base.BasePresenter.<init>(BasePresenter.java:15)
           at mypackage.com.ui.flow.register.PostRegisterPresenter.<init>(PostRegisterPresenter.java:16)
           at mypackage.com.core.di.module.PresenterModule.providePostRegisterPresenter(PresenterModule.java:227)
           at mypackage.com.core.di.module.PresenterModule_ProvidePostRegisterPresenterFactory.providePostRegisterPresenter(PresenterModule_ProvidePostRegisterPresenterFactory.java:29)
           at mypackage.com.core.di.component.DaggerLiveDIComponent.injectPostRegisterFragment(DaggerLiveDIComponent.java:786)
           at mypackage.com.core.di.component.DaggerLiveDIComponent.inject(DaggerLiveDIComponent.java:516)
           at mypackage.com.ui.flow.register.PostRegisterFragment.injectFragment(PostRegisterFragment.java:76)
           at mypackage.com.ui.base.BaseFragment.onAttach(BaseFragment.java:115)
           at androidx.fragment.app.Fragment.onAttach(Fragment.java:1603)
           at androidx.fragment.app.Fragment.performAttach(Fragment.java:2673)
           at androidx.fragment.app.FragmentStateManager.attach(FragmentStateManager.java:263)
           at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1182)
           at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1255)
           at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1138)
           at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:136)
           at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2001)
           at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1959)
           at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
           at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
           at android.os.Handler.handleCallback(Handler.java:873)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loop(Looper.java:214)
           at android.app.ActivityThread.main(ActivityThread.java:7094)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
    
    

    Our classes:

    @EFragment
    public class PostRegisterFragment extends BaseFragment<PostRegisterView, PostRegisterPresenter> implements PostRegisterView
    
    public abstract class BaseFragment<V extends BaseView, P extends BasePresenter<V>> extends MvpFragment<V, P> implements BaseView
    
    public interface PostRegisterView extends BaseView
    
    public interface BaseView extends MvpView
    
    public class PostRegisterPresenter extends BasePresenter<PostRegisterView>
    
    public abstract class BasePresenter<V extends BaseView> extends MvpNullObjectBasePresenter<V>
    

    Steps to reproduce the behavior or link to a sample repository

    • We received the logs from Google Play Store crashlytics. Until now we do not have any replication steps.
    • It seems that it doesn't affect all of our users.
    • Also we have proguard enabled.
    • The issue appeared out of the blue, we did not made any changes at those classes in our latest release.
    • We used to have mosby 2.0.1 when we first got the issue yesterday, we updated to 3.1.1 in order to fix the problem.
    • The problem seems to be contained a little but it still persists.
    opened by ptsiogas 3
  • Synthetic MviPresenter generated classes instances not GC cleared after Activity/fragment destruction

    Synthetic MviPresenter generated classes instances not GC cleared after Activity/fragment destruction

    Mosby Version: 3.1.1

    Expected behavior

    MviPresenter$classes instances should be garbage collected after leaving fragment and its activity host and not bound to any INSTANCE object

    Actual behavior (include a stacktrace if crash) No crash associated.

    The problem is that the generated synthetic classes instances in presenter are somehow bounded to an INSTANCE that is not garbage collected after leaving the screen despite several attempts to force GC on Android profiler.

    Most certain the synthetic classes can probably be the anonymous functions in the flatMap calls

    See image image

    Snippet of source code of presenter

    image

    This presenter lifecycle is being handled by mosby and not reference nor it is being passed to any other component outside the Fragment it belongs to.

    The TakePhotoInteractor instance is created on demand also

    Steps to reproduce the behavior or link to a sample repository

    Just implement this library and follow http://hannesdorfmann.com/android/mosby3-mvi-2

    Doesnt mosby disposes that observables created from the view intents?

    Any thoughts about this?

    opened by ruieduardosoares 12
  • MviConductorLifecycleListener : call destroy on null presenter

    MviConductorLifecycleListener : call destroy on null presenter

    App process killed -> conductor setRoot() called (back stack is not empty) -> postDestroy() called on controllers in the backstack -> destroy() called on a null presenter -> crash happened. Screen Shot 2020-07-30 at 23 03 34

    opened by meghdadfm 0
  • Mosby V4 - AndroidX support

    Mosby V4 - AndroidX support

    Unfortunately Mosby V3 is not compatable with AndroidX as accessing the backstack to see if a fragment is still in use (or presenter can be released) is not possible anymore in androidx as the method to get this information is "blacklisted" and no accessible from the outside anymore (it was in support.v4 days) see #338 #336

    Any workaround suggested in #338 seems to me fragile. Therefore I considering the following: What we actually need is a lifecycle callback that tells us when the Fragment is actually destroyed. We could get this information by using AndroidX ViewModel,onCleared().

    This will not be breaking change, rather it's a minor implementation detail under the hood.

    What do you think?

    help wanted 
    opened by sockeqwe 10
  • java.lang.IllegalAccessError: Method 'boolean androidx.fragment.app.Fragment.isInBackStack()' is inaccessible to class 'androidx.core.app.BackstackAccessor'

    java.lang.IllegalAccessError: Method 'boolean androidx.fragment.app.Fragment.isInBackStack()' is inaccessible to class 'androidx.core.app.BackstackAccessor'

    Need help to solve this error

    java.lang.IllegalAccessError: Method 'boolean androidx.fragment.app.Fragment.isInBackStack()' is inaccessible to class 'androidx.core.app.BackstackAccessor'

    I read on release to use BackstackAccessor.isFragmentOnBackStack(Fragment()).

    where should I use this line of code?

    opened by dharmesh8080 1
Releases(3.1.1)
  • 3.1.1(Dec 17, 2018)

    Minor release for better support with jetifier and androidx

    Solves:

    BackstackAccessor.isFragmentOnBackStack(Fragment()) Crash: java.lang.IllegalAccessError: Method 'boolean androidx.fragment.app.Fragment.isInBackStack()' is inaccessible to class 'androidx.core.app.BackstackAccessor'

    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Nov 28, 2017)

    Added

    • MvpQueueingBasePresenter: This Presenter has a method onceViewAttached(ViewAction) that internally queues all ViewAction if no view is attached to this presenter and executes all queued actions once a view is attached. If a view is attached, the ViewAction executes immediately. This class is useful in MVP powered apps with backstack navigation.

    Changes

    • MvpPresenter.detachView(boolean retainInstance) is now split in two methods:
      • detachView(): Was the same as detachView(retainInstance = true)
      • destroy(): Was the same as detachView(retainInstance = false) Please note that destroy() is called when the corresponding View is also destroyed permanently. For example, if FragmentA (View) has PresenterA. Once we push a new Fragment B (with Presenter B) on top of the stack, PresenterA.detachView() is called because View of FragmentA is destroyed temporarily.

    Deprecations

    • MvpPresenter.detachView(boolean retainInstance) is deprecated now. Use detachView() and destroy().
    • MvpBasePresenter.getView() and MvpBasePresenter.isViewAttached() are deprecated. Use MvpBasePresenter.ifViewAttached(ViewAction), see #233
    Source code(tar.gz)
    Source code(zip)
  • 3.0.4(May 15, 2017)

    Minor improvement in MviBasePresenter to change the internal order how intent() and subscribeViewState() are constructing the observable stream #242

    This means internal ViewState-BehaviorSubject is constructed first and then Intent-PublishSubjects are constructed. This ensures that every intent() which emits early like Observable.just(...) is received by ViewState. However, this also means that you should not invoke an intent from view.render() (or whatever method your viewstate subscriber is) because MviBasePresenter might not be subscribed to the intent() yet.

    So if you ever face such a use case that you have to trigger an intent from view.render() please file an issue on github's issue tracker.

    Source code(tar.gz)
    Source code(zip)
  • 3.0.3(Apr 20, 2017)

  • 3.0.2(Mar 31, 2017)

  • 3.0.1(Mar 30, 2017)

    • Fixes #229: Adds View.isInEditMode() check to support Android Studio's layout editor for custom ViewGroups powered MVI or MVP. This means that there is a breaking API change in constructor of ViewGroupMviDelegateImpl, ViewGroupMvpDelegeateImpl and ViewGroupMvpViewStateDelegateImpl(constructor now requires 3 parameters).

    • Some minor javadoc improvements

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Mar 11, 2017)

    New (Public API):

    • Model-View-Intent (MVI) Module: com.hannesdorfmann.mosby3:mvi:3.0.0

    New (Internal usage only):

    • mvi-common Module (internal usage only). Common interfaces for MVI (shared with conductor Mosby plugin)
    • PresenterManager Module (internal usage only): Is used internally by MVP and MVI to keep presenters during screen orientation changes, back stack navigation etc.
    • utils-fragment Module (internal usage only): Is used internally to determine if a Fragment is on back stack or not.

    Changes:

    • Package name has been changed from com.hannesdorfmann.mosby to com.hannesdorfmann.mosby3 (note the 3 at the end). Just update your import statements to migrate to Mosby 3.0: In Android Studio do Edit -> Find -> Replace in Path ... and set find import com.hannesdorfmann.mosby replace with import com.hannesdorfmann.mosby3.
    • Moved MvpBasePresenter from mvp-common module into mvp module
    • MvpNullObjectBasePresenter has been moved into own module: com.hannesdorfmann.mosby3:mvp-nullobject-presenter:3.0.0
    • MvpNullObjectBasePresenter: getView() is has now protected visibility and uses WeakReference internally
    • Moved LCE (Loading-Content-Error) related classes into own module: com.hannesdorfmann.mosby3: mvp-lce:3.0.0
    • MvpActivity, MvpFragment, etc. no longer have methods like isRetainInstance(), setRetainInstance() and shouldInstanceBeRetained(). This functionality is now part of the corresponding delegate such as ActivityMvpDelegate, FragmentMvpDelegate etc.
    • Some Mosby internal fixes / improvements.

    Deprecations:

    • Deprecated ArrayListLceViewState and CastedArrayListLceViewState. Use ParcelableListLceViewState instead.

    Removed:

    • Removed MvpViewStateViewGroupDelegateCallback
    • Removed mvp testing module
    • Removed deprecated RetainingFragmentLceViewState (deprecated in Mosby 2.0). Use RetainingLceViewState.

    Thanks to all contributors!

    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Feb 20, 2016)

    Minor update, cleaning up some internals and updating javadocs:

    • #104 Presenter not created if Fragment has no UI
    • #107 Allow non textview errorview in LceAnimator.showErrorView
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Sep 4, 2015)

    • Kotlin support
    • Retaining Activities #64
    • Removed core-module: MosbyActivity and MosbyFragment. This means that there is no more Butterknife, Icepick and FragmentArgs integration out of the box. That is something every developer should do by it’s own. #63
    • Removed core-dagger1, mvp-dagger1 and viewstate-dagger1. So no more dagger 1 support out of the box. #63
    • Removed rx module and retrofit module #63
    • splitting isRetainingInstance() method into isRetainInstance() and shouldInstanceBeRetained() to avoid bugs.
    • Deprecated RetainingFragmentLceViewState, use RetainingLceViewState instead
    • Renamed MvpDelegateCallback to BaseMvpDelegateCallbackand introduced ActivityMvpDelegateCallback to implement retaining Activities with retaining presenters #64
    • Renamed MvpViewStateDelegateCallback to BaseMvpDelegateCallback for retaining Activities with retaining presenter and viewstate #64
    • Renamed RestoreableViewState to RestorableViewState and RestoreableParcelableViewState to RestorableParcelableViewState
    • update to support lib 23.0.1
    • updated compile SDK and target SDK to Marshmallow (API 23)
    Source code(tar.gz)
    Source code(zip)
    sample-dagger1-debug.apk(1.53 MB)
    sample-dagger2-rx-debug.apk(1.74 MB)
    sample-debug.apk(1.54 MB)
    sample-kotlin-debug.apk(1.99 MB)
    sample-mail-debug.apk(2.40 MB)
  • 1.3.1(Sep 1, 2015)

    • Bugfix: split method isRetainingInstance() into two methods: isRetainInstance() and shouldInstanceBeRetained()

    This might be the last 1.x release containing. 2.0 will be released very soon containing some serious changes with integration of third party libraries like Butterknife, FragmentArgs and IcePick.

    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Aug 27, 2015)

    • MvpNullObjectBasePresenter: Fix #77
    • MvpFragment now takes parent's activity isChangingConfiguration() into account #65
    • Removed old animation checks for SDK < 14 since minSdk is 14 #76
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jul 20, 2015)

  • 1.1.1(Jul 12, 2015)

  • 1.1.0(May 10, 2015)

    • Delegates: Renaming ViewStateSupport and ViewStateManager to MvpViewStateDelegateCallback. Introduced other delegates like ActivityMvpDeleage, FragmentMvpDelegate, ViewGroupMvpDelegate, ActivityMvpViewStateDelegate, FragmentMvpViewStateDelegate and ViewGroupMvpViewStateDelegate
    • Because of new Delegates a minor migration must be done (migrating from Mosby 1.0.0 to Mosby 1.1.0):
      • MvpViewStateFragment, MvpFragment and MvpViewStateActivity and MvpActivity have now two generic parameters: <MvpView, MvpPresenter>
      • createPresenter() method must be public (instead of protected)
    • Introducing MVP and ViewState support for ViewGroups like FrameLayout, LinearLayout, RelativeLayout etc.
    • Update to latest support v7 library 22.1.0
    • Internal changes of how RestoreableViewState works and bugfixes
    • Better support for fragments on the backstack
    • Added MvpRxPresenter class which can be used for not LCE based RxJava presenter.
    • Updated to latest FragmentArgs version 2.1.0
    Source code(tar.gz)
    Source code(zip)
    sample-dagger1.apk(1.44 MB)
    sample-dagger2-rx.apk(1.65 MB)
    sample-mail.apk(2.12 MB)
    sample.apk(1.38 MB)
  • 1.0.0(May 10, 2015)

Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development

Mobile Kotlin Model-View-ViewModel architecture components This is a Kotlin Multiplatform library that provides architecture components of Model-View-

IceRock Development 638 Jan 2, 2023
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
🧬 Android DataBinding kit for notifying data changes from Model layers to UI layers on MVVM architecture.

?? Android DataBinding kit for notifying data changes from Model layers to UI layers on MVVM architecture.

Jaewoong Eum 275 Dec 21, 2022
GraphQLTrial is a demo application based on modern Android application tech-stacks and MVVM architecture.

GraphQLTrial is a demo application based on modern Android application tech-stacks and MVVM architecture. App fetching data from the netw

Emre YILMAZ 6 Aug 19, 2022
🎯 Einsen is a prioritization app that uses Eisenhower matrix technique as workflow to prioritize a list of tasks & built to Demonstrate use of Jetpack Compose with Modern Android Architecture Components & MVVM Architecture.

?? Einsen Einsen is a prioritization app that uses Eisenhower matrix technique as workflow to prioritize a list of tasks & built to Demonstrate use of

Sanju S 840 Jan 2, 2023
📊 A Minimal Expense Tracker App built to demonstrate the use of modern android architecture component with MVVM Architecture

Expenso ?? A Simple Expense Tracker App ?? built to demonstrate the use of modern android architecture component with MVVM Architecture ?? . Made with

Sanju S 813 Dec 30, 2022
JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends.

JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends. Also, It uses some of Jetpack and popular libraries. These are Kotlin Coroutine-Flow, kotlinx.serialization, Hilt, Compose, Accompanist, Retrofit2, OkHttp3, Chucker, MockWebServer, Truth.

Tolga Bolatcan 13 Nov 2, 2022
A small demo application based on modern Android application technology stacks and MVVM architecture

Pokedex Pokedex es una pequeña aplicación de demostración basada en modernas pil

Jhonatan Iberico 0 Dec 17, 2021
A sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern.

This repository contains a sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern

Areg Petrosyan 42 Dec 23, 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
Extendable MVI framework for Kotlin Multiplatform with powerful debugging tools (logging and time travel), inspired by Badoo MVICore library

Should you have any questions or ideas please welcome to the Slack channel: #mvikotlin Inspiration This project is inspired by Badoo MVICore library.

Arkadii Ivanov 460 Dec 31, 2022
Movie app that receives popular movies and allows the user to search for the specific movie through the Rest API with help of retrofit library &MVVM architecture.

MovieClue Millions of movies, TV shows and people to discover. Explore now Movie app that recieves popular movies and allow the user to search for spe

Shubham Tomar 6 Mar 31, 2022
📝 A demo todo/notes app which demonstrates the use of MVVM architecture, Navigation Component Library, Room Database, LiveData, Coroutines

?? MyNotes A demo notes/todo app which demonstrates the use of MVVM architecture, Navigation Component Library, Room Database, LiveData, Coroutines et

Raghav Aggarwal 89 Dec 23, 2022
Repository that showcases 3 Android app architectures: "Standard Android", MVP and MVVM. The exact same app is built 3 times following the different patterns.

Archi This repository showcases and compares different architectural patterns that can be used to build Android apps. The exact same sample app is bui

Iván Carballo 3.4k Dec 21, 2022
Android Clean Architecture💎 Base Project Android with Kotlin and MVVM applying clean architecture

Android Clean Architecture?? Base Project Android with Kotlin and MVVM applying clean architecture

Mina Mikhail 103 Dec 2, 2022
Pick any of your favorite github repository and create a mini android app showing its details on an android app.

Github Browser Pick any of your favorite github repository and create a mini android app showing its details on an android app. Screens navigation gra

Prasoon 6 Oct 16, 2022
MVVM for Android

AndroidBinding MVVM for Android What's New Pre Compiled version available on root directory android-binding.gen.zip for activity/application template

Andy Tsui 350 Dec 17, 2022
A full-featured framework that allows building android applications following the principles of Clean Architecture.

EasyMVP A powerful, and very simple MVP library with annotation processing and bytecode weaving. EasyMVP eliminates the boilerplate code for dealing w

null 1.3k Nov 19, 2022