8000 Fix IntentBuilder startForResult by tbruyelle · Pull Request #680 · androidannotations/androidannotations · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Conversation

@tbruyelle
Copy link
Contributor

Related to #541

In a fragment, startActivityForResult must be called on the Fragment and
not on getActivity(), or the fragment's onActivityResult will never be
hit.

Now IntentBuilder may have up to 3 constructors, depending on the
classpath content. According to the constructor chosen,
startActivityForResult() will be called on Activity, android.app.Fragment
or android.support.v4.app.Fragment.

From the AA user perspective, this fix is quite transparent, he just
have to call MyActivity_.intent(this), whatever he's in a fragment or an
activity, it will work.

Generated code in case of both android.app.Fragment and android.support.v4.Fragment are presents in the classpath (true for current AA junit environment) :

    public static ExtendingActivity_.IntentBuilder_ intent(Context context) {
        return new ExtendingActivity_.IntentBuilder_(context);
    }

    public static ExtendingActivity_.IntentBuilder_ intent(android.app.Fragment fragment) {
        return new ExtendingActivity_.IntentBuilder_(fragment);
    }

    public static ExtendingActivity_.IntentBuilder_ intent(android.support.v4.app.Fragment fragment) {
        return new ExtendingActivity_.IntentBuilder_(fragment);
    }

    public static class IntentBuilder_ {

        private Context context_;
        private final Intent intent_;
        private android.app.Fragment fragment_;
        private android.support.v4.app.Fragment fragmentSupport_;

        public IntentBuilder_(Context context) {
            context_ = context;
            intent_ = new Intent(context, ExtendingActivity_.class);
        }

        public IntentBuilder_(android.app.Fragment fragment) {
            fragment_ = fragment;
            context_ = fragment.getActivity();
            intent_ = new Intent(context_, ExtendingActivity_.class);
        }

        public IntentBuilder_(android.support.v4.app.Fragment fragment) {
            fragmentSupport_ = fragment;
            context_ = fragment.getActivity();
            intent_ = new Intent(context_, ExtendingActivity_.class);
        }

        public Intent get() {
            return intent_;
        }

        public ExtendingActivity_.IntentBuilder_ flags(int flags) {
            intent_.setFlags(flags);
            return this;
        }

        public void start() {
            context_.startActivity(intent_);
        }

        public void startForResult(int requestCode) {
            if (fragmentSupport_!= null) {
                fragmentSupport_.startActivityForResult(intent_, requestCode);
            } else {
                if (fragment_!= null) {
                    fragment_.startActivityForResult(intent_, requestCode);
                } else {
                    if (context_ instanceof Activity) {
                        ((Activity) context_).startActivityForResult(intent_, requestCode);
                    } else {
                        context_.startActivity(intent_);
                    }
                }
            }
        }

    }

Notes :

  • I didn't find proper method to test if a class is present in the classpath. so I used Class.forName(). Tell me if I miss something.
  • I tested the feature in a test project, and the generated code is well updated according to android.app.Fragment or android.support.v4.app.Fragment are present or not in the classpath. But I didn't manage to create a junit for that.
  • The only tests I wrote are compile tests with fragments class which use the new intent() methods.

In a fragment, startActivityForResult must be called on the Fragment and
not on getActivity(), or the fragment's onActivityResult will never be
hit.

Now IntentBuilder may have up to 3 constructors, depending on the
classpath content. According to the constructor chosen,
startActivityForResult will be called on Activity, android.app.Fragment
or android.support.v4.app.Fragment.

From the AA user perspective, this fix is quite transparent, he just
have to call MyActivity_.intent(this), whatever he's in a Fragment or an
Activity, it will work.
@DayS
Copy link
Contributor
DayS commented Sep 1, 2013

To check if a class is present in the classpath you can use this code snippet

Elements elementUtils = annotationHelper.getElementUtils();
if (elementUtils.getTypeElement(CanonicalNameConstants.SUPPORT_V4_FRAGMENT) != null) {
    // ...
}

@tbruyelle
Copy link
Contributor Author

Ok I will update my code

@tbruyelle
Copy link
Contributor Author

Code updated 1239f62

For review clarity I didn't squish the commits, but I can if required.

DayS added a commit that referenced this pull request Sep 20, 2013
@DayS DayS merged commit 0b88c44 into androidannotations:develop Sep 20, 2013
@DayS
Copy link
Contributor
DayS commented Sep 20, 2013

Great job 👍

@tbruyelle tbruyelle deleted the 541_FragmentStartActivityForResult branch April 15, 2014 08:28
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0