Skip to content

Commit b53f245

Browse files
authored
Merge pull request #23 from leobert-lan/feature/anno
Feature/anno
2 parents 2976aeb + 7465d20 commit b53f245

File tree

19 files changed

+730
-169
lines changed

19 files changed

+730
-169
lines changed

URI设计.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# URI设计
2+
By Leobert
3+
4+
## 为什么要有这一篇
5+
DDComponent设计的初衷应当是注重于实现组件化,得到的几位大牛也提供了非常优秀的解决方案。但是组件化的代码边界带来了一个问题:UI跳转的时候没那么方便了,以往常见的做法:
6+
7+
* 耦合非常高的直接构造Intent并启动
8+
* 将所需的参数、参数组装等都在目标Activity中进行方法封装,暴露静态方法供调用
9+
* 实现Factory进行Intent的构造、实现启动器
10+
11+
都不行了。所以DDComponent中有了Router部分,使用路由进行UI跳转(通过路由寻找组件的内容本篇略过)。而DDComponent中的UIRouter部分是比较轻量级的,本人也有幸和得到的大牛进行了一定的讨论,对router部分略尽了绵薄之力。但是当前的Router部分使用还是没那么轻松的,而本人也对这些问题进行了思考,幸有所得。鉴于接下来一段时间我都比较忙,现将设计思路记录于此,倘若有同行有兴趣提供一臂自力也是非常感激的。
12+
13+
PS:格竹子君给我开了一个anno分支,本身我命这个名字是Feature/anno 使用注解实现路由定义的功能分支。
14+
15+
## URI的基础格式
16+
> 协议://域名:port/目录a/目录b/文件c?key1=value1&key2=v2#author
17+
18+
除了这些还有query部分,author部分(URL中也有人称hash部分)
19+
而‘目录a/目录b/文件c’这段也有人称为path。
20+
21+
**在当前的实现中,参数传递暂使用Bundle,不支持使用queryString**
22+
23+
我们可以看到demo中有这样一段:
24+
25+
```
26+
UIRouter.getInstance().openUri(getActivity(), "componentdemo://share", bundle);
27+
```
28+
29+
这里使用的URI尚未经过精心设计,而且直接使用hardcode形式也是不利于维护的(当然这里只是demo,当我们将框架完善后这些问题就解决了)
30+
31+
## 设计构想
32+
### 协议部分
33+
有一些朋友提过issue:runalone时的传值问题。参考一些服务端的同事在一些非敏感接口同时兼容了query传值和表单传值的做法,我觉得Router部分兼容query传值和Intent的bundle传值是可取的。考虑到可能控制不住的场面。通过协议部分区分两种形式。
34+
35+
* dunq: DDUiNavigation-QueryString 使用queryString传值
36+
* dunb: DDUiNavigation-Bundle 使用Bundle传值
37+
38+
### host部分
39+
我们可以将Component认为是不同的主机,给定不同的域名
40+
41+
### port部分
42+
我有在项目中提过一个issue,intent的FLAG问题,当前是没有支持的,可以使用port来做一些手脚,也可以直接在Router中将方法原型扩展一下。*我还要再细想想哪种好*
43+
44+
### path部分
45+
当前的anno分支实现中,在对path提出了group的概念,可以针对group分一下Router,但是除了看起来有点噱头其实没啥大用,因为路由表都是按照注解自动生成的,最多就是路由器命名的时候贴切一些。
46+
47+
但潜意识告诉我这个group迟早会有用 233333
48+
49+
计划中会按照注解的path生成一些常量,减少hardcode。这个时候group可能会有用哦。
50+
51+
### query部分
52+
计划中需要支持使用query进行传值
53+
54+

componentlib/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ android {
2525
}
2626

2727
dependencies {
28-
compile fileTree(dir: 'libs', include: ['*.jar'])
28+
compile fileTree(include: ['*.jar'], dir: 'libs')
2929
compile 'com.android.support:appcompat-v7:26.+'
30-
3130
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
3231
exclude group: 'com.android.support', module: 'support-annotations'
3332
})
3433
testCompile 'junit:junit:4.12'
34+
compile project(':router-annotation')
3535
}
3636

3737

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.mrzhang.component.componentlib.router;
2+
3+
import android.support.annotation.StringDef;
4+
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.RetentionPolicy;
7+
8+
/**
9+
* <p><b>Package:</b> com.mrzhang.component.componentlib.router </p>
10+
* <p><b>Project:</b> DDComponentForAndroid </p>
11+
* <p><b>Classname:</b> Path </p>
12+
* <p><b>Description:</b> TODO </p>
13+
* Created by leobert on 2017/9/23.
14+
*/
15+
16+
public final class UiActivityUri {
17+
18+
@Retention(RetentionPolicy.SOURCE)
19+
@StringDef({Scheme.DUNQ,Scheme.DUNB})
20+
public @interface SchemeDef {
21+
22+
}
23+
24+
public static final class Scheme {
25+
public static final String DUNQ = "dunp:";
26+
27+
public static final String DUNB = "dunb:";
28+
}
29+
30+
@SchemeDef
31+
private String scheme;
32+
33+
private final String host;
34+
35+
private final String path;
36+
37+
private String queryString;
38+
39+
public UiActivityUri(String host, String path) {
40+
this.host = host;
41+
this.path = path;
42+
}
43+
44+
45+
@SchemeDef
46+
public String getScheme() {
47+
return scheme;
48+
}
49+
50+
public void setScheme(@SchemeDef String scheme) {
51+
this.scheme = scheme;
52+
}
53+
54+
public String getHost() {
55+
return host;
56+
}
57+
58+
public String getPath() {
59+
return path;
60+
}
61+
62+
public void setQueryString(String queryString) {
63+
this.queryString = queryString;
64+
}
65+
66+
public String getQueryString() {
67+
return queryString;
68+
}
69+
70+
71+
72+
// public String getUri() {
73+
//
74+
// }
75+
76+
}

componentlib/src/main/java/com/mrzhang/component/componentlib/router/ui/UIRouter.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
import android.content.Context;
44
import android.net.Uri;
55
import android.os.Bundle;
6+
import android.support.annotation.NonNull;
67
import android.text.TextUtils;
78

9+
import com.ljsw.router.facade.Constants;
10+
import com.ljsw.router.facade.annotation.Router;
11+
12+
import java.lang.annotation.Annotation;
813
import java.util.ArrayList;
914
import java.util.HashMap;
1015
import java.util.Iterator;
1116
import java.util.List;
17+
import java.util.Map;
1218

1319
/**
1420
* Singleton implement of {@link IUIRouter}
@@ -18,6 +24,7 @@
1824
*/
1925

2026
public class UIRouter implements IUIRouter {
27+
private static Map<String, IComponentRouter> routerInstanceCache = new HashMap<>();
2128

2229
private List<IComponentRouter> uiRouters = new ArrayList<>();
2330
private HashMap<IComponentRouter, Integer> priorities = new HashMap<>();
@@ -124,4 +131,33 @@ private void removeOldUIRouter(IComponentRouter router) {
124131
}
125132
}
126133
}
134+
135+
public static IComponentRouter fetch(@NonNull Class<? extends IComponentRouter> clz) {
136+
if (!clz.isInterface())
137+
throw new IllegalArgumentException("need a interface, but this isn't a interface:" + clz.getName());
138+
139+
Router router = clz.getAnnotation(Router.class);
140+
if (router == null)
141+
throw new IllegalArgumentException("not annotated with Router:" + clz.getName());
142+
143+
String path = Constants.ROUTERIMPL_OUTPUT_PKG +
144+
Constants.DOT + router.group() + Constants.DOT + clz.getSimpleName() + "Impl";
145+
if (routerInstanceCache.containsKey(path))
146+
return routerInstanceCache.get(path);
147+
148+
try {
149+
Class cla = Class.forName(path);
150+
IComponentRouter instance = (IComponentRouter) cla.newInstance();
151+
routerInstanceCache.put(path, instance);
152+
return instance;
153+
} catch (ClassNotFoundException e) {
154+
e.printStackTrace();
155+
} catch (InstantiationException e) {
156+
e.printStackTrace();
157+
} catch (IllegalAccessException e) {
158+
e.printStackTrace();
159+
}
160+
161+
return null;
162+
}
127163
}

readercomponent/src/main/java/com/mrzhang/reader/ReaderFragment.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ public void onClick(View v) {
3636
final String _dto = "{\"s\":\"sss\"}";
3737
bundle.putString("bookName","testBookName");
3838
bundle.putString("testDto",_dto);
39-
UIRouter.getInstance().openUri(getActivity(), "componentdemo://share", bundle);
39+
UIRouter.getInstance().openUri(getActivity(), "dunb://shareComponent/share", bundle);
40+
// "componentdemo://share"
4041
}
4142
});
4243

router-anno-compiler/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apply plugin: 'java'
33
dependencies {
44
compile fileTree(include: ['*.jar'], dir: 'libs')
55
compile 'com.google.auto.service:auto-service:1.0-rc2'
6-
compile 'com.squareup:javapoet:1.7.0'
6+
compile 'com.squareup:javapoet:1.9.0'
77

88

99
compile 'org.apache.commons:commons-lang3:3.4'
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.ljsw.router.compiler.model;
2+
3+
import javax.lang.model.type.TypeMirror;
4+
5+
/**
6+
* <p><b>Package:</b> com.ljsw.router.compiler.model </p>
7+
* <p><b>Project:</b> DDComponentForAndroid </p>
8+
* <p><b>Classname:</b> HostInfo </p>
9+
* <p><b>Description:</b> TODO </p>
10+
* Created by leobert on 2017/9/25.
11+
*/
12+
13+
public class GroupInfo {
14+
private String host;
15+
private String outPutPath;
16+
private String interfacePath;
17+
18+
public GroupInfo(String host, String outPutPath, String interfacePath) {
19+
this.host = host;
20+
this.outPutPath = outPutPath;
21+
this.interfacePath = interfacePath;
22+
}
23+
24+
public String getHost() {
25+
return host;
26+
}
27+
28+
public String getOutPutPath() {
29+
return outPutPath;
30+
}
31+
32+
public String getInterfacePath() {
33+
return interfacePath;
34+
}
35+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2017 leobert-lan
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*
24+
*/
25+
26+
package com.ljsw.router.compiler.model;
27+
28+
import com.squareup.javapoet.ClassName;
29+
import com.squareup.javapoet.ParameterSpec;
30+
import com.squareup.javapoet.TypeName;
31+
32+
import java.util.ArrayList;
33+
import java.util.List;
34+
35+
import javax.lang.model.element.Modifier;
36+
import javax.lang.model.element.VariableElement;
37+
import javax.lang.model.type.TypeMirror;
38+
39+
/**
40+
* Description: Helper class to record method info needed by Processor
41+
*/
42+
public class MethodInfo {
43+
private String methodName;
44+
private List<Modifier> methodModifiers;
45+
private List<VariableElement> methodParameters;
46+
private TypeMirror methodReturnType;
47+
48+
public MethodInfo() {
49+
}
50+
51+
public MethodInfo setMethodName(String methodName) {
52+
this.methodName = methodName;
53+
return this;
54+
}
55+
56+
public MethodInfo setMethodModifiers(List<Modifier> methodModifiers) {
57+
this.methodModifiers = methodModifiers;
58+
return this;
59+
}
60+
61+
public MethodInfo setMethodParameters(List<VariableElement> methodParameters) {
62+
this.methodParameters = methodParameters;
63+
return this;
64+
}
65+
66+
public MethodInfo setMethodReturnType(TypeMirror methodReturnType) {
67+
this.methodReturnType = methodReturnType;
68+
return this;
69+
}
70+
71+
public String getMethodName() {
72+
return methodName;
73+
}
74+
75+
public List<Modifier> getMethodModifiers() {
76+
return methodModifiers;
77+
}
78+
79+
public List<ParameterSpec> getMethodParameters() {
80+
List<ParameterSpec> parameterSpecs = new ArrayList<>();
81+
for (VariableElement variableElement : methodParameters) {
82+
parameterSpecs.add(ParameterSpec.get(variableElement));
83+
}
84+
return parameterSpecs;
85+
}
86+
87+
public List<String> getMethodParametersSimple() {
88+
List<String> params = new ArrayList<>();
89+
for (VariableElement methodParameter : methodParameters) {
90+
params.add(methodParameter.getSimpleName().toString());
91+
}
92+
return params;
93+
}
94+
95+
public TypeName getTypeName() {
96+
return ClassName.get(methodReturnType);
97+
}
98+
}

0 commit comments

Comments
 (0)