Skip to content
This repository has been archived by the owner on Mar 16, 2021. It is now read-only.

Destroy TiActivity Presenter properly #35

Merged
merged 18 commits into from
Nov 8, 2016

Conversation

passsy
Copy link
Contributor

@passsy passsy commented Nov 3, 2016

I discovered that the Presenter of an Activity wasn't destroyed properly. When changing the configuration of an Activity without closing it (by calling recreate() or changing the orientation) the Presenter was accidentally destroyed although the flag isChangingConfigurations was true.

I wrote tests for all permutations (with/without savior | don't keep Activities true/false) for the usecases:

  • changing configuration,
  • move to background and back to foreground and
  • finish the Activity.

see TiActivityPresenterDestroyTest.java

To verify everything is working end to end I wrote a UI tests (for the plugin module). It's a new module because I don't want to add a TestActivity to the debug build type of the plugin module. The test was failing before the fix was included.

This PR does not include a fix for TiFragment as it was reported in #33. A separate PR will follow targeting this problem

Pascal Welsch added 10 commits October 5, 2016 17:38
After a big test session I found two bugs. Tests for all states shows the same bugs.
# Conflicts:
#	plugin/build.gradle
#	thirtyinch/src/main/java/net/grandcentrix/thirtyinch/TiFragment.java
#	thirtyinch/src/main/java/net/grandcentrix/thirtyinch/TiPresenter.java
#	thirtyinch/src/main/java/net/grandcentrix/thirtyinch/internal/TiActivityDelegate.java

move test for module plugin into a separate module plugin-test
will be part of a separate PR
!config.useStaticSaviorToRetain()
if (!destroyPresenter
&& !config.useStaticSaviorToRetain()
&& !mTiActivity.isActivityChangingConfigurations()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix itself was just this && !mTiActivity.isActivityChangingConfigurations() line.

@@ -0,0 +1,8 @@
## Test module for `plugin` module

This module contains the tests androidTests for the `plugin` module.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap androidTests into codeblock: androidTests

This reduces problems for users of the library but makes testing harder.

Also, Activities cannot be defined in the `androidTest` package.
Moving them into the `debug` buildType doesn't feel right.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line. It feels not professional to say something like

"doesn't feel right"

final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();

// start the activity for the first time
final Intent intent = new Intent(instrumentation.getTargetContext(), TestActivity.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated code. Move this into its own method and return the TestActivity

import android.widget.TextView;

/**
* only for tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this. This should be clear.

private int wakeupCalls = 0;

@Override
protected void onWakeUp() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use onAttachView(View) 🤔

private PublishSubject<Void> triggerHeavyCalculation = PublishSubject.create();

private RxTiPresenterSubscriptionHandler rxSubscriptionHelper = new RxTiPresenterSubscriptionHandler(this);
public HelloWorldPresenter() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for demonstration, right?
Otherwise we can remove it...

private RxTiPresenterSubscriptionHandler mSubscriptionHandler
= new RxTiPresenterSubscriptionHandler(this);

public SamplePresenter() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same like above, demo right?

@@ -151,6 +151,18 @@ public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGrou
@Override
public void onDestroy() {
super.onDestroy();
//FIXME handle attach/detach state
TiLog.v(TAG, "isChangingConfigurations = " + getActivity().isChangingConfigurations());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move all the Log method into it's own method like logFragmentInformation or something like that...

public class PresenterSaviorTestHelper {

/**
* helper to clear the savior without exposing this to the public api
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this info but add javadoc to the top of the class.

}
}

private class Delegate extends TiActivityDelegate<TestPresenter, TiView> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better if we move this into its own class (instead of inner class) and setup all the stuff in the constructor via a builder pattern.
These lines looks really crazy and no one knows which parameter is for what :D

@passsy passsy added this to the 0.8.0 milestone Nov 4, 2016

final TiConfiguration config = mPresenter.getConfig();

if (DEBUG) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still valid :)
Don't put all the Logs into the method. Create a own method instead which will log all the stuff.

/**
* enables debug logging during development
*/
private static final boolean DEBUG = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEBUG is a little bit confused. It sounds like "debug product flavor" or something like that.
It is more a ENABLE_LOGGING, isn't it? 🤔

@passsy
Copy link
Contributor Author

passsy commented Nov 7, 2016

The UI tests are very unstable on travis. I think I should remove them 😒

@passsy
Copy link
Contributor Author

passsy commented Nov 7, 2016

Ok, I fixed it. Ran it 3x and it works without problems

@StefMa StefMa merged commit 7e033cb into master Nov 8, 2016
@StefMa StefMa deleted the feature/destroy_presenter_properly branch November 8, 2016 09:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

Successfully merging this pull request may close these issues.

2 participants