Builder Pattern In Android

看到一篇个人感觉不错的文章,分享出来。(希望对大家有帮助)

When I started with android, I almost always asked Google how to do the smallest things. I want to highlight the examples I found for starting an activity.

Intent intent = new Intent(this, SomeOtherActivity.class);
startActivity(intent);

I always wondered why many examples used a variable called intent. You could easily create the Intent on-the-fly in the startActivity() parameter. Maybe it looks better, if you need to add some parameters to the intent like this?

Intent intent = new Intent(this, SomeOtherActivity.class);
intent.putExtra("param1", extraInfo1);
intent.putExtra("param2", extraInfo2);
startActivity(intent);

But then again, the method putExtra() returns an Intent. As described in the example for method-chaining, such chaining can be relatively useful. Androids call to startActivity() could be rewritten to this:

startActivity(new Intent(this, SomeOtherActivity.class)
       .putExtra("param1", extraInfo1)
       .putExtra("param2", extraInfo2));

Since this doesn’t need a variable, I like that approach more. In Android, this pattern is used quite often. The so called builder-pattern is used with AlertDialog for example. When built, you use the create() method in order to show the dialog itself (equals the build() method of the builder-pattern). To create URIs one can use the buildUpon() method to get a Uri.Builder. There are tons of other examples where Android uses such builders. Intents seem to be an exception, since there is no startActivity() function or similar to it. Returning the object itself was not even done consequently, to make chaining of some methods impossible. Examples for these are setSourceBounds() or setExtrasClassLoader().

I see two options to address these problems:

  • Creation of a sub-class of Intent, which provides a startAsActivity() function. It needs to return its own type in every putExtra() method, to preserve the startAsActivity() method. This class could look like this:
public class BuilderIntent extends Intent {
    private final Context context;
 
    public BuilderIntent(Context ctx, Class<?> cls) {
        super(ctx, cls);
        this.context = ctx;
    }
 
    @Override
    public BuilderIntent putExtra(String name, String value) {
        super.putExtra(name, value);
        return this;
    }
 
    // ... more putExtra-methods ...
 
    public void startAsActivity() {
        context.startActivity(this);
    }
}
 
// Usage:
new BuilderIntent(this, SomeOtherActivity.class)
        .putExtra("param1", "info1")
        .putExtra("param2", "info2")
        .startAsActivity();

The problem with this class is, that methods like public void setExtrasClassLoader() cannot be changed to return the BuilderIntent type.

  • An alternative would be the usage of an external builder, which uses its own Intent internally. Take all functions you want to provide and change them for your requirements, somehow similar to the Decorator-Pattern.
public static class ActivityBuilder {
    private final Context context;
    private final Intent intent;
 
    private ActivityBuilder(Context context, Class<? extends Activity> activity) {
        this.context = context;
        intent = new Intent(context, activity);
    }
 
    public ActivityBuilder put(String param, Long x) {
        intent.putExtra(param, x);
        return this;
    }
 
    // ... more required methods ...
 
    public void start() {
        context.startActivity(intent);
    }
}

The advantage is that you can setup a public ActivityBuilder setExtrasClassLoader() method without hassle. The problem is, that you cannot use methods from Intent at all. With the first option, that would be cumbersome but at least possible.

What I wanted to say is that a method like startAsActivity() seems to be missing. However, you can create your own builders around existing classes.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值