Coder Social home page Coder Social logo

activityrouter's Introduction

# ActivityRouter

### [English README.md here](https://github.com/mzule/ActivityRouter/blob/master/README-en.md)

## 功能

支持给`Activity`定义 URL,这样可以通过 URL 跳转到`Activity`,支持在浏览器以及 app 中跳入。

![image](https://raw.githubusercontent.com/mzule/ActivityRouter/master/gif/router.gif)

![image](https://raw.githubusercontent.com/mzule/ActivityRouter/master/gif/http.gif)

## 集成

### 1. 添加引用

请根据项目的历史情况选择合适的集成方式

#### 1.1 annotaitonProcessor 方式

``` groovy
dependencies {
    compile 'com.github.mzule.activityrouter:activityrouter:1.2.2'
    annotationProcessor 'com.github.mzule.activityrouter:compiler:1.1.7'
}
```

#### 1.2 apt 方式
根目录 build.gradle

``` groovy
buildscript {
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }
}
```

项目 app/build.gradle
``` groovy
apply plugin: 'android-apt'

dependencies {
    compile 'com.github.mzule.activityrouter:activityrouter:1.2.2'
    apt 'com.github.mzule.activityrouter:compiler:1.1.7'
}

```
### 2. 集成

在`AndroidManifest.xml`配置

``` xml
<activity
    android:name="com.github.mzule.activityrouter.router.RouterActivity"
    android:theme="@android:style/Theme.NoDisplay">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="mzule" /><!--改成自己的scheme-->
    </intent-filter>
</activity>
```
在需要配置的`Activity`上添加注解

``` java
@Router("main")
public class MainActivity extends Activity {
	...
}
```
这样就可以通过`mzule://main`来打开`MainActivity`了。

## 进阶

### 支持配置多个地址

``` java
@Router({"main", "root"})
```

`mzule://main`和`mzule://root`都可以访问到同一个`Activity`


### 支持获取 url 中`?`传递的参数

``` java
@Router("main")
```
上面的配置,可以通过`mzule://main?color=0xff878798&name=you+are+best`来传递参数,在`MainActivity#onCreate`中通过`getIntent().getStringExtra("name")`的方式来获取参数,所有的参数默认为`String`类型,但是可以通过配置指定参数类型,后面会介绍。

### 支持在 path 中定义参数

``` java
@Router("main/:color")
```

通过`:color`的方式定义参数,参数名为`color`,访问`mzule://main/0xff878798`,可以在`MainActivity#onCreate`通过`getIntent().getStringExtra("color")`获取到 color 的值`0xff878798`

### 支持多级 path 参数

``` java
@Router("user/:userId/:topicId/:commentId")

@Router("user/:userId/topic/:topicId/comment/:commentId")
```

上面两种方式都是被支持的,分别定义了三个参数,`userId`,`topicId`,`commentId`


### 支持指定参数类型

``` java
@Router(value = "main/:color", intParams = "color")
```
这样指定了参数`color`的类型为`int`,在`MainActivity#onCreate`获取 color 可以通过`getIntent().getIntExtra("color", 0)`来获取。支持的参数类型有`int`,`long`,`short`,`byte`,`char`,`float`,`double`,`boolean`,默认不指定则为`String`类型。

### 支持优先适配

``` java
@Router("user/:userId")
public class UserActivity extends Activity {
	...
}

@Router("user/statistics")
public class UserStatisticsActivity extends Activity {
	...
}
```
假设有上面两个配置,

不支持优先适配的情况下,`mzule://user/statistics`可能会适配到`@Router("user/:userId")`,并且`userId=statistics`

支持优先适配,意味着,`mzule://user/statistics`会直接适配到`@Router("user/statistics")`,不会适配前一个`@Router("user/:userId")`

### 支持 Callback

``` java
public class App extends Application implements RouterCallbackProvider {
    @Override
    public RouterCallback provideRouterCallback() {
        return new SimpleRouterCallback() {
            @Override
            public boolean beforeOpen(Context context, Uri uri) {
                context.startActivity(new Intent(context, LaunchActivity.class));
                // 是否拦截,true 拦截,false 不拦截
                return false;
            }

            @Override
            public void afterOpen(Context context, Uri uri) {
            }

            @Override
            public void notFound(Context context, Uri uri) {
                context.startActivity(new Intent(context, NotFoundActivity.class));
            }
            
            @Override
            public void error(Context context, Uri uri, Throwable e) {
                context.startActivity(ErrorStackActivity.makeIntent(context, uri, e));
            }
        };
    }
}
```
在`Application`中实现`RouterCallbackProvider`接口,通过`provideRouterCallback()`方法提供`RouterCallback`,具体 API 如上。

### 支持 Http(s) 协议

``` java
@Router({"http://mzule.com/main", "main"})
```

AndroidManifest.xml

``` xml
<activity
    android:name="com.github.mzule.activityrouter.router.RouterActivity"
    android:theme="@android:style/Theme.NoDisplay">
    ...
    <intent-filter>
    	<action android:name="android.intent.action.VIEW" />
    	<category android:name="android.intent.category.DEFAULT" />
    	<category android:name="android.intent.category.BROWSABLE" />
    	<data android:scheme="http" android:host="mzule.com" />
	</intent-filter>
</activity>
```

这样,`http://mzule.com/main`和`mzule://main`都可以映射到同一个 Activity,值得注意的是,在`@Router`中声明`http`协议地址时,需要写全称。

### 支持参数 transfer

``` java
@Router(value = "item", longParams = "id", transfer = "id=>itemId")
```
这里通过`transfer = "id=>itemId"`的方式,设定了 url 中名称为`id`的参数会被改名成`itemId`放到参数`Bundle`中,类型为`long`. 值得注意的是,这里,通过`longParams = "id"`或者`longParams = "itemId"`都可以设置参数类型为`long`.

### 支持应用内调用

``` java
Routers.open(context, "mzule://main/0xff878798")
Routers.open(context, Uri.parse("mzule://main/0xff878798"))
Routers.openForResult(activity, "mzule://main/0xff878798", REQUEST_CODE);
Routers.openForResult(activity, Uri.parse("mzule://main/0xff878798"), REQUEST_CODE);
// 获取 Intent
Intent intent = Routers.resolve(context, "mzule://main/0xff878798")
```

通过`Routers.open(Context, String)`或者`Routers.open(Context, Uri)`可以直接在应用内打开对应的 Activity,不去要经过 RouterActivity 跳转,效率更高。

### 支持获取原始 url 信息

``` java
getIntent().getStringExtra(Routers.KEY_RAW_URL);
```

### 支持通过 url 调用方法

``` java
@Router("logout")
public static void logout(Context context, Bundle bundle) {
}
```

在任意参数为 Context 和 Bundle 的静态公共方法上, 通过 @Router 标记即可定义方法的 url. @Router 使用方式与上述一致。

### 支持多模块

* 每个包含 activity 的 module 都要添加 apt 依赖
* 每个 module(包含主项目) 都要添加一个 @Module(name) 的注解在任意类上面,name 是项目的名称
* 主项目要添加一个 @Modules({name0, name1, name2}) 的注解,指定所有的 module 名称集合

## 混淆配置

``` groovy
-keep class com.github.mzule.activityrouter.router.** { *; }
```

## 许可

Apache License  2.0

## 联系我

任何相关问题都可以通过以下方式联系我。

1. 提 issue
1. 新浪微博 http://weibo.com/mzule
1. 个人博客 https://mzule.github.io/
1. 邮件 "mzule".concat("4j").concat("@").concat("gmail.com")

activityrouter's People

Contributors

mzule avatar ratdream avatar simplehych avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

activityrouter's Issues

mappings为空,打不开对应的activity

尝试理解源码,并没有直接引用,本地按照你的project进行配置
这是生成的RouterMapping类
// ----------------------------------------------------------

public final class RouterMapping {
public static final void map() {
java.util.Map<String,String> transfer = null;
com.test.routerkit.router.ExtraTypes extraTypes;
transfer = null;
extraTypes = new com.test.routerkit.router.ExtraTypes();
extraTypes.setTransfer(transfer);
com.test.routerkit.router.Routers.map("main/test", MainActivity.class, extraTypes);
com.test.routerkit.router.Routers.sort();
}
}
// ----------------------------------------------------------
但是Routers.map()方法并没有调用, mappings size始终为0,无法打开对应的activity。
请问com.test.routerkit.router.Routers.map()失效的原因是什么

为什么我这么写 浏览器打不开呢

@RequiresPresenter(PayPresenter.class)
@router("main")
public class RechargePayActivity extends BaseActivity implements View.OnClickListener, IPayView {}

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data android:scheme="mzule" /><!--改成自己的scheme-->
        </intent-filter>
    </activity>

为什么我这么写 浏览器打不开呢

很酷的类,提几点建议

1.希望给出string的配置选项
如果仅仅是一个类定义了一个path,传过来的参数虽然可以得到,但是这样在代码维护性方面感觉还是略低,所以希望像int这样给出一个string的配置选项。

@Router(value = {"user_detail/"}, intExtra = {"userId"})

2.建议增加path的命名
注解默认的值是value,这可以缺省,很省事,但是如果当我怎讲了intExtra的配置后,这个value写出来后就没有很好的语义性。所以建议增加path字段来和value并存,在注解解析器中解析value如果没有就解析path,如果还没有,那么才是真正的没有。

if(value == null){
      if(path == null){.......}
}

3.建议给配置选项改名
intExtra知道是和android一致的int参数,但个人认为叫做intParam可能更加合适url的语义。

eg:intParam = {user_id}

4.最好能通过注解将intent的getExtra这些代码进行自动生成,对于每个被注解标识的类产生

XxxArgs args = XxxArgsFromRouter.getArguments(getIntent());
args.username;
args.topicId;
arg.commentId;

配合androidannotation使用的问题

因为配合这个框架使用所以它生成的类都带有一个下划线"",但是因为@router是加在原始的类上所以在使用的时候失效了.
我down下来您的代码改动了部分内容
mapMethod.addStatement("com.github.mzule.activityrouter.router.Routers.map($S,$T_.class, null, extraTypes)", format, className);
也就是生成的Activity应该是TestActivity
,而导入包还是TestActivity
这样可以生成带下划线的类了.但是我对生成这块不熟悉.没有办法import对应的类的包.
所以麻烦给点提示.找了半天没有找到相关的代码.
thx
项目很棒

RouterInit.init()

private static void initIfNeed() {
    if (!mappings.isEmpty()) {
        return;
    }
    RouterInit.init();
    sort();
}

大神请教下RouterInit.init();是做了啥操作,源码中好像方法是空的..

多个module 跳转问题

请问我有两个module A 和 B 然而我通过Routers.open();跳转到module A的act是可以跳转过去的,但是module B的act跳转不过去 一直notfound ,act都有通过@router("actA")注解 在主module的AndroidManifest.xml添加了添加了RouterActivity,每个module中也添加了(compile 'com.github.mzule.activityrouter:activityrouter:1.2.2' 和 apt 'com.github.mzule.activityrouter:compiler:1.1.7')

url参数的问题

当url中存在“/”符号时,会有解析错误的问题,觉得可以做一个过滤,提供一个encode的方法,然后回传参数的时候decode

浏览器调用

你好,在手机内置浏览器打开h5页面可以直接打开activity吗?同理,微信里面的内置浏览器可以打开app页面吗?谢谢

每次页面跳转的问题

public class App extends Application implements RouterCallbackProvider {
@OverRide
public RouterCallback provideRouterCallback() {
return new SimpleRouterCallback() {
@OverRide
public void beforeOpen(Context context, Uri uri) {
context.startActivity(new Intent(context, LaunchActivity.class));
}

        @Override
        public void afterOpen(Context context, Uri uri) {
        }

        @Override
        public void notFound(Context context, Uri uri) {
            context.startActivity(new Intent(context, NotFoundActivity.class));
        }

        @Override
        public void error(Context context, Uri uri, Throwable e) {
            context.startActivity(ErrorStackActivity.makeIntent(context, uri, e));
        }
    };
}

}

我发现,每次调用跳转的时候,都会先执行到LaunchActivity里面;
而我希望当我回退的时候不经过这个LaunchActivity;
当我尝试注释掉 beforeOpen 里面的 启动 LaunchActivity 的时候,却发现无法执行;
请问这有好的解决办法么?
我希望,每次执行跳转的时候不去执行到 LaunchActivity,或者回退的时候不经过该页面;

拦截器

不支持拦截器吗,跳转之前拦截做登录绑卡的操作等这样,我看alibaba/ARouter有加

stringParam,字符串参数如果使用的时候为空,无法跳转

String accountParam = mEtdAccount.getText().toString().trim();
// accountParam为空字符串的时候,无法跳转,我是做了一个判断加了一个为空串的时候的标识。
if (TextUtils.equals("", accountParam)){
// 帐号参数为空字符串的时候,路由的url路径无法跳转,所以设置一个空的标识来表示
accountParam = "empty";
}
Routers.openForResult(LoginActivity.this,
AppConst.MODIFY_PWD_ROUTER_URL + accountParam,
AppConst.MODIFY_PWD_REQUEST_CODE);

多工程怎么使用?

项目里很多模块是通过lib工程来实现的,这种情况怎么使用?在每个lib工程都配置会生成相同的类,如果只在主工程里配置那lib工程的Annotation又不生成代码。

Router中的stringParams参数类型忘记写传值方法了?

        addStatement(mapMethod, int.class, router.intParams());
        addStatement(mapMethod, long.class, router.longParams());
        addStatement(mapMethod, boolean.class, router.booleanParams());
        addStatement(mapMethod, short.class, router.shortParams());
        addStatement(mapMethod, float.class, router.floatParams());
        addStatement(mapMethod, double.class, router.doubleParams());
        addStatement(mapMethod, byte.class, router.byteParams());
        addStatement(mapMethod, char.class, router.charParams());

原本没有写传递stringParams类型的方法
需要加上下面这句话:
addStatement(mapMethod, String.class, router.stringParams());

ExtraTypes.class 中需要添加 stringExtra的getter和setter方法

实际参数列表和形式参数列表长度不同

Error:(13, 51) 错误: 无法将类 Routers中的方法 map应用到给定类型;
需要: String,Class<? extends Activity>,MethodInvoker,ExtraTypes
找到: String,Class,ExtraTypes
原因: 实际参数列表和形式参数列表长度不同

RouterInit这个类不存在

导入的是下面的库
compile 'com.github.mzule.activityrouter:activityrouter:1.2.1'
apt 'com.github.mzule.activityrouter:compiler:1.1.7'
RouterInit这个类不存在,看了源码中还引入了一个“stub”的字库,里面有RouterInit这个类,但是我通过gradle引入就找不到这个类!

有Library的项目可以使用吗

我项目中有Library,使用ActvityRouter之后只会有一个项目中的配置生效,我看了下几个Library生成的RouterInit和RouterMapping包名类名都是一样的,所以导致了只有一个生效结果。

Mapping类equals方法错误

 if (o == this) {
            return true;
        }
        if (o instanceof Mapping) {
            Mapping that = (Mapping) o;
              return that.format.equals(((Mapping) o).format);
        }
        return false;

return that.format.equals(((Mapping) o).format);语句有问题,永远为true

ActivityNotFoundException 子工程

按照配置,找不到Activity,为什么会加主工程的前缀?

03-01 19:17:43.365 21676-21676/com.xxx.prototype_1010_2 W/System.err: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.xxx.prototype_1010_2/com.xxx.prototype.TestActivity}; have you declared this activity in your AndroidManifest.xml?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.