Ablepsia 和 startActivity() 说再见

415 查看

Ablepsia 是一个可以替代 startActivity() 的框架,并且支持 activity 之间跳转的拦截和重定向,重定向保存此次跳转的存活。

ps:不支持系统 activity,不支持 forResult ,forResult 是很麻烦的

Ablepsia - git 项目地址

好吧,可能你还没有理解的很清楚,来举个栗子:现在有两个 activity ,一个是 首页,一个是 用户详情,现在的业务规则是打开 用户详情 之前必须要求是已登陆状态。so.原来的处理方式是你在打开 用户详情 之前判断是否已登陆,如果未登录就打开登录页面,好吧,你这么做我也没有意见。但是如果后续还增加了 订单列表、订单详情、...以及 N 个需要已登录才能打开的页面,那么你又要写 N 次判断。

对于上述栗子,Ablepsia 的处理姿势可谓是十分优雅,将 N 变为 1 次判断,自动重定向到登录页面,登录成功后自动跳转到 用户详情 页面。.......目前 git 上的路由框架的实现方式,一旦你重定向此次跳转,此次跳转的生命就结束了,所以无法做到登录成功后自动跳转到 用户详情 页面

Demo 在 git 上

糟糕的 GIF ,第一次未登录状态下打开 用户详情页,将会被重定向到 登录页,点击登录成功后继续跳转到用户详细页,第二次已登录状态打开 用户详情页,直接跳转到 用户详情页,并将 view 分享过去。由于第一次跳转被重定向,所以 view 分享的动画丢失了,最下面的注意事项中有说到

OK,接下来介绍使用姿势

  • 配置 gradle

    //项目的 build.gradle 添加如下
    allprojects {
        repositories {
            ...
            maven { url "https://jitpack.io" }
        }
    }
    // 模块的 build.gradle 添加如下
    dependencies {
            compile 'com.github.Xiao187:Ablepsia:v1.0.5'
    }
  • 使用

        //打开 UseInfoActivity
        Ablepsia.open(this, UseInfoActivity.class);
        //打开 UseInfoActivity 带参数,支持所有类型
        Ablepsia.kv("name","jack").open(this, UseInfoActivity.class);
        //打开 UseInfoActivity 指定 flag
        Ablepsia.flag(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .open(this, UseInfoActivity.class);
        //打开 UseInfoActivity 分享元素
        Ablepsia.options(ActivityOptionsCompat.makeSceneTransitionAnimation(this, view, "name").toBundle())
                    .open(this, UseInfoActivity.class);
  • 拦截 - 重定向

//在需要拦截或重定向的 Activity 上 使用 @Symptom 注解
@Symptom("需要登录才能打开")
public class UseInfoActivity extends AppCompatActivity {}
//自定义 Doctor 继承 Doctor
public class DemoDoctor extends Doctor {

    @Override
    protected Anagraph treatment(String symptom, Context context, Class blind) {}
    
    @Override
    protected void funeral(String symptom, Context context, Class<? extends Activity> activity) {
        //调用 Anagraph.die() 后,会回调到这里
        //默认空实现
    }
}
    // Ablepsia.open() 之前设置 Doctor,否则使用的是默认 Doctor
    Ablepsia.setDoctor(new DemoDoctor());
    //在 treatment 方法中实现拦截,不能 return null;
    @Override
    protected Anagraph treatment(String symptom, Context context, Class blind) {
        switch (symptom) {
                case "需要登录才能打开":
                    if (SignInStatus.isSign()){
                        return Anagraph.alive();// -- 继续执行
                    }else {
                        Ablepsia.open(context,SignInActivity.class);
                        return Anagraph.detained("先去登录");//  -- 拘留,直到调用 Anagraph.detainedCompleting("先去登录") 才会继续跳转
                    }
                default:
                    return Anagraph.die();// -- 终止跳转
        }
}

上述 Anagraph.detained("key"); 是指将这一次跳转拘留起来,你可以在某一时刻调用 Anagraph.detainedCompleting("key"); 就会继续执行这一次未完成的跳转,比如,你可以在 登录成功的回调 里并且在 登录页面 finish(); 之前调用 。推荐在 finish(); 之前调用的原因是画面可以更流畅,不信的话你可以试试在 finish(); 之后调用

除了上述 Anagraph.alive();Anagraph.detained("key");Anagraph.die(); 三种方式,还有一种不推荐的处理方式,使用 Chaperonage 监视:

    //默认每 500 毫秒监视一次,你可以让他更快
    //当监视到 return true; 便继续这一次未完成的跳转
    return Anagraph.detained(new Anagraph.Chaperonage(/* 500 */) {
        @Override
        public boolean Chaperonage() {
               return SignInStatus.isSign();
        }
    });

Chaperonage 原理是开启了一个子线程来监视,当条件成立时便继续执行任务,不推荐在Chaperonage() 方法中做复杂的任务,由于这种方式可能产生不必要的资源浪费,所以不推荐使用,建议用Anagraph.detained("key"); 来替换。

注意事项

  • 如过不调用 Ablepsia.setDoctor();, 将会使用默认 Doctor,默认 Anagraph.alive();

  • 如果不是 return Anagraph.alive();,将会清空此次跳转携带的 options(),也就是说,被重定向过的跳转将会失去 options();

·
·
·