4
\$\begingroup\$

I had the idea to have a static method on an activity which creates intents that it can use. For example if I have an activity with a webview that can load html from a resource or a URL I would have 2 methods in the activity like so.

public static Intent createURLIntent(Context context, int titleId, String URL) {
    Intent intent = new Intent(context, WebViewActivity.class);
    intent.putExtra(TITLE_ID, titleId);
    intent.putExtra(URL, URL);
    return intent;
}

public static Intent createFileIntent(Context context, int titleId, String fileName) {
    Intent intent = new Intent(context, WebViewActivity.class);
    intent.putExtra(TITLE_ID, titleId);
    intent.putExtra(FILE, fileName);
    return intent;
}

The on create would look like this..

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.webview_activity);
    int titleId = getIntent().getIntExtra(TITLE_ID, 0);
    setTitle(getString(titleId));
    if (getIntent().hasExtra(FILE)) {
        webview.loadUrl(getIntent().getStringExtra(FILE));
    } else {
        webview.loadUrl(getIntent().getStringExtra(URL));
    }
}

Then a class that wants to open that activity would use it in this way:

    Intent intent = WebViewActivity.createURLIntent(
            context, R.string.about_title, "www.google.com");
    startActivity(intent);

Is there any problems with using this approach?

\$\endgroup\$

3 Answers 3

3
\$\begingroup\$

Judging by this bit:

if (getIntent().hasExtra(FILE)) {
    webview.loadUrl(getIntent().getStringExtra(FILE));
} else {
    webview.loadUrl(getIntent().getStringExtra(URL));
}

It looks like the loadUrl method doesn't care whether the parameter you pass to it is a file path out a web address. Actually the term "url" has a general meaning that can encompass both file paths and web addresses. So I don't see the point of distinguishing these two in the intents: just use "URL", it doesn't matter if it's a path out web address. Again, this suggestion is based on the posted code.

If you really want to have two separate static method for some reason, then extract the common logic in these methods to a helper method.

private static Intent createIntent(Context context, int titleId, String key, String url) {
    Intent intent = new Intent(context, WebViewActivity.class);
    intent.putExtra(TITLE_ID, titleId);
    intent.putExtra(key, url);
    return intent;
}

public static Intent createURLIntent(Context context, int titleId, String url) {
    return createIntent(context, titleId, URL, url);
}

public static Intent createFileIntent(Context context, int titleId, String path {
    return createIntent(context, titleId, FILE, path);
}
\$\endgroup\$
1
\$\begingroup\$

Shadowed variable

You appear to have shadowed your string constant URL with an argument of the same name. Therefore, this line here is probably not going to do what you intended:

intent.putExtra(URL, URL);
\$\endgroup\$
1
  • \$\begingroup\$ true dat. Do you see any problems with the overall approach? \$\endgroup\$
    – jiduvah
    Commented Aug 19, 2015 at 9:40
1
\$\begingroup\$

I would re-write it using the builder pattern, which might eliminate repetitive code:

public class IntentBuilder {
    private Context context;
    private Intent intent;

    public IntentBuilder(Context context) {
        this.context = context;
        intent = new Intent();
    }

    public IntentBuilder titleExtra(int titleId) {
        intent.putExtra(TITLE_ID, titleId);
        return this;
    }

    public IntentBuilder fileExtra(String fileName) {
        intent.putExtra(FILE, fileName);
        return this;
    }

    public IntentBuilder urlExtra(String url) {
        intent.putExtra(URL, url);
        return this;
    }

    public IntentBuilder targetComponent(Class<?> cls) {
        intent.setClass(context, cls);
        return this;
    }

    ...

    public Intent build() {
        if (intent.getComponent() == null) {
            intent.setClass(context, WebViewActivity.class);
        }
        return intent;
    }

    public void start() {
        Intent i = build();
        context.startActivity(i);
    }
}

Now to build the intent, you have 2 options:

Intent intent = new WebViewActivity.IntentBuilder(context)
                    .titleExtra(R.string.about_title)
                    .urlExtra("www.google.com")
                    .build();
startActivity(intent);

Or

new WebViewActivity.IntentBuilder(context)
                   .titleExtra(R.string.about_title)
                   .urlExtra("www.google.com")
                   .start();
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.