Skip to content

Commit 8a5ff55

Browse files
authored
Merge pull request #24 from wyjsonGo/develop
publish v2.2.0 1.新增withObject()方法传递自定义对象 2.新增injectCheck()方法检查required标识
2 parents 7b573b0 + f3a0d00 commit 8a5ff55

File tree

19 files changed

+311
-26
lines changed

19 files changed

+311
-26
lines changed

GoRouter-Api/src/main/java/com/wyjson/router/GoRouter.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.wyjson.router.core.ServiceCenter;
3333
import com.wyjson.router.core.interfaces.IInterceptorService;
3434
import com.wyjson.router.exception.NoFoundRouteException;
35+
import com.wyjson.router.exception.ParamException;
3536
import com.wyjson.router.exception.RouterException;
3637
import com.wyjson.router.interfaces.IApplicationModule;
3738
import com.wyjson.router.interfaces.IDegradeService;
@@ -258,27 +259,55 @@ public String getCurrentPath(Fragment fragment) {
258259
}
259260

260261
public void inject(Activity activity) {
261-
RouteCenter.inject(activity, null, null);
262+
inject(activity, null, null, false);
262263
}
263264

264265
public void inject(Activity activity, Intent intent) {
265-
RouteCenter.inject(activity, intent, null);
266+
inject(activity, intent, null, false);
266267
}
267268

268269
public void inject(Activity activity, Bundle bundle) {
269-
RouteCenter.inject(activity, null, bundle);
270+
inject(activity, null, bundle, false);
270271
}
271272

272273
public void inject(Fragment fragment) {
273-
RouteCenter.inject(fragment, null, null);
274+
inject(fragment, null, null, false);
274275
}
275276

276277
public void inject(Fragment fragment, Intent intent) {
277-
RouteCenter.inject(fragment, intent, null);
278+
inject(fragment, intent, null, false);
278279
}
279280

280281
public void inject(Fragment fragment, Bundle bundle) {
281-
RouteCenter.inject(fragment, null, bundle);
282+
inject(fragment, null, bundle, false);
283+
}
284+
285+
public void injectCheck(Activity activity) throws ParamException {
286+
inject(activity, null, null, true);
287+
}
288+
289+
public void injectCheck(Activity activity, Intent intent) throws ParamException {
290+
inject(activity, intent, null, true);
291+
}
292+
293+
public void injectCheck(Activity activity, Bundle bundle) throws ParamException {
294+
inject(activity, null, bundle, true);
295+
}
296+
297+
public void injectCheck(Fragment fragment) throws ParamException {
298+
inject(fragment, null, null, true);
299+
}
300+
301+
public void injectCheck(Fragment fragment, Intent intent) throws ParamException {
302+
inject(fragment, intent, null, true);
303+
}
304+
305+
public void injectCheck(Fragment fragment, Bundle bundle) throws ParamException {
306+
inject(fragment, null, bundle, true);
307+
}
308+
309+
private <T> void inject(T target, Intent intent, Bundle bundle, boolean isCheck) throws ParamException {
310+
RouteCenter.inject(target, intent, bundle, isCheck);
282311
}
283312

284313
@Nullable

GoRouter-Api/src/main/java/com/wyjson/router/core/RouteCenter.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
import com.wyjson.router.GoRouter;
1515
import com.wyjson.router.enums.ParamType;
1616
import com.wyjson.router.exception.NoFoundRouteException;
17+
import com.wyjson.router.exception.ParamException;
1718
import com.wyjson.router.exception.RouterException;
19+
import com.wyjson.router.interfaces.IJsonService;
1820
import com.wyjson.router.model.Card;
1921
import com.wyjson.router.model.CardMeta;
2022
import com.wyjson.router.model.ParamMeta;
@@ -27,6 +29,8 @@
2729

2830
public class RouteCenter {
2931

32+
private static IJsonService jsonService;
33+
3034
public static Map<String, IRouteModuleGroup> getRouteGroups() {
3135
return Warehouse.routeGroups;
3236
}
@@ -132,9 +136,11 @@ public static <T> String getCurrentPath(T target) {
132136
* @param target
133137
* @param intent
134138
* @param bundle
139+
* @param isCheck 是否检查 isRequired
135140
* @param <T>
141+
* @throws ParamException
136142
*/
137-
public static <T> void inject(T target, Intent intent, Bundle bundle) {
143+
public static <T> void inject(T target, Intent intent, Bundle bundle, boolean isCheck) throws ParamException {
138144
GoRouter.logger.debug(null, "[inject] Auto Inject Start!");
139145

140146
try {
@@ -152,14 +158,27 @@ public static <T> void inject(T target, Intent intent, Bundle bundle) {
152158
CardMeta cardMeta = GoRouter.getInstance().build(path).getCardMeta();
153159
if (cardMeta != null) {
154160
Map<String, ParamMeta> paramsType = cardMeta.getParamsType();
155-
for (Map.Entry<String, ParamMeta> params : paramsType.entrySet()) {
156-
String paramName = params.getValue().getName();
161+
for (Map.Entry<String, ParamMeta> entry : paramsType.entrySet()) {
162+
String paramName = entry.getValue().getName();
157163
Object value = bundle.get(paramName);
158-
if (value == null)
164+
if (value == null) {
165+
if (isCheck && entry.getValue().isRequired()) {
166+
throw new ParamException(paramName);
167+
}
159168
continue;
169+
}
160170
GoRouter.logger.debug(null, "[inject] " + paramName + ":" + value);
161171
try {
162-
Field injectField = getDeclaredField(target.getClass(), params.getKey());
172+
Field injectField = getDeclaredField(target.getClass(), entry.getKey());
173+
if (ParamType.Object == entry.getValue().getType()) {
174+
if (jsonService == null) {
175+
jsonService = GoRouter.getInstance().getService(IJsonService.class);
176+
}
177+
if (jsonService == null) {
178+
throw new RouterException("To use withObject() method, you need to implement IJsonService");
179+
}
180+
value = jsonService.parseObject((String) value, injectField.getType());
181+
}
163182
injectField.setAccessible(true);
164183
injectField.set(target, value);
165184
} catch (Exception e) {

GoRouter-Api/src/main/java/com/wyjson/router/enums/ParamType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ public enum ParamType {
1111
Double,
1212
String,
1313
Serializable,
14-
Parcelable;
14+
Parcelable,
15+
Object;
1516
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.wyjson.router.exception;
2+
3+
import java.util.Locale;
4+
5+
public class ParamException extends RuntimeException {
6+
private String paramName;
7+
8+
public ParamException(String paramName) {
9+
super(String.format(Locale.getDefault(), "The '%s' parameter is required", paramName));
10+
this.paramName = paramName;
11+
}
12+
13+
public String getParamName() {
14+
return paramName;
15+
}
16+
17+
public void setParamName(String paramName) {
18+
this.paramName = paramName;
19+
}
20+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.wyjson.router.interfaces;
2+
3+
import java.lang.reflect.Type;
4+
5+
public interface IJsonService extends IService {
6+
7+
/**
8+
* Object to json
9+
*
10+
* @param instance obj
11+
* @return json string
12+
*/
13+
String toJson(Object instance);
14+
15+
/**
16+
* Parse json to object
17+
*
18+
* @param input json string
19+
* @param clazz object type
20+
* @return instance of object
21+
*/
22+
<T> T parseObject(String input, Type clazz);
23+
}

GoRouter-Api/src/main/java/com/wyjson/router/model/Card.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.wyjson.router.enums.RouteType;
2020
import com.wyjson.router.exception.NoFoundRouteException;
2121
import com.wyjson.router.exception.RouterException;
22+
import com.wyjson.router.interfaces.IJsonService;
2223
import com.wyjson.router.utils.TextUtils;
2324

2425
import java.io.Serializable;
@@ -32,6 +33,7 @@ public final class Card extends CardMeta {
3233
private boolean greenChannel;// 绿色通道(跳过所有的拦截器)
3334
private String action;
3435
private Context context;
36+
private IJsonService jsonService;
3537

3638
private int enterAnim = -1;// 转场动画
3739
private int exitAnim = -1;
@@ -150,6 +152,24 @@ public int getFlags() {
150152
return flags;
151153
}
152154

155+
/**
156+
* 使用 withObject 传递 List 和 Map 的实现了 Serializable 接口的实现类(ArrayList/HashMap)的时候,
157+
* 接收该对象的地方不能标注具体的实现类类型应仅标注为 List 或 Map,
158+
* 否则会影响序列化中类型的判断, 其他类似情况需要同样处理
159+
*
160+
* @param key
161+
* @param value
162+
* @return
163+
*/
164+
public Card withObject(@Nullable String key, @Nullable Object value) {
165+
jsonService = GoRouter.getInstance().getService(IJsonService.class);
166+
if (jsonService == null) {
167+
throw new RouterException("To use withObject() method, you need to implement IJsonService");
168+
}
169+
mBundle.putString(key, jsonService.toJson(value));
170+
return this;
171+
}
172+
153173
public Card withString(@Nullable String key, @Nullable String value) {
154174
mBundle.putString(key, value);
155175
return this;

GoRouter-Api/src/main/java/com/wyjson/router/model/CardMeta.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@ public CardMeta putTag(int tag) {
118118
return this;
119119
}
120120

121+
public CardMeta putObject(String key) {
122+
return put(key, null, ParamType.Object, false);
123+
}
124+
125+
public CardMeta putObject(String key, String name, boolean required) {
126+
return put(key, name, ParamType.Object, required);
127+
}
128+
121129
public CardMeta putString(String key) {
122130
return put(key, null, ParamType.String, false);
123131
}

GoRouter-Compiler/src/main/java/com/wyjson/router/compiler/processor/GenerateRouteModuleProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ private CodeBlock.Builder handleParam(CodeBlock.Builder paramCode, Element eleme
377377
} else if (types.isSubtype(typeMirror, serializableType)) {
378378
paramType = "putSerializable";
379379
} else {
380-
throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " @Param(type='" + typeMirror + "') is marked as an unsupported type");
380+
paramType = "putObject";
381+
// throw new RuntimeException(PREFIX_OF_LOGGER + moduleName + " @Param(type='" + typeMirror + "') is marked as an unsupported type");
381382
}
382383
}
383384

README.md

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
| 动态注册拦截器 | 不支持 | 支持 | ARouter只能动态注册路由,不能动态注册拦截器 |
1919
| 重写跳转URL服务 | 支持 | 不支持 | 可以在`IPretreatmentService`里实现相同功能 |
2020
| 获取元数据 | 不支持 | 支持 | 有些场景需要判断某个页面当前是否存在等需求,就需要获取页面class等信息,参见5-1 |
21-
| withObject() | 支持 | 不支持 | ARouter实现原理是转JSON后使用`withString()`方法传递 |
22-
| inject(T) | 单一 | 更多 | ARouter不能在`onNewIntent()`方法里使用,GoRouter提供了更多使用场景 |
21+
| inject(T) | 单一 | 更多 | ARouter不能在`onNewIntent()`方法里使用,也不能检查`required`,GoRouter提供了更多使用场景,参见4-2 |
2322
| 按组分类、按需初始化 | 支持 | 支持 | ARouter不允许多个module中存在相同的分组,GoRouter允许 |
2423
| 模块Application生命周期 | 不支持 | 支持 | 主动分发到业务模块,让模块无侵入的获取Application生命周期,参见6-1 |
2524
| 路由页面Event | 不支持 | 支持 | 页面事件解耦,提供更多、更方便的API,参见5-10 |
@@ -132,6 +131,7 @@ GoRouter.getInstance().build("/test/activity").go(this);
132131
GoRouter.getInstance().build("/test/fragment")
133132
.withInt("age", 35)
134133
.withString("name", "Wyjson")
134+
.withObject("test", new TestModel(123, "Jack"))
135135
.go(this);
136136
```
137137

@@ -211,7 +211,6 @@ AndroidManifest.xml
211211
```java
212212
// 为每一个参数声明一个字段,并使用 @Param 标注
213213
// URL中不能传递Parcelable类型数据,通过GoRouter api可以传递Parcelable对象
214-
// 支持父类字段自动注入
215214
@Route(path = "/param/activity")
216215
public class ParamActivity extends BaseParamActivity {
217216

@@ -222,27 +221,79 @@ public class ParamActivity extends BaseParamActivity {
222221
@Param(name = "nickname", remark = "昵称", required = true)
223222
private String name;
224223

224+
/**
225+
* 使用 withObject 传递 List 和 Map 的实现了 Serializable 接口的实现类(ArrayList/HashMap)的时候,
226+
* 接收该对象的地方不能标注具体的实现类类型应仅标注为 List 或 Map,
227+
* 否则会影响序列化中类型的判断, 其他类似情况需要同样处理
228+
*/
229+
@Param(name = "test", remark = "自定义类型", required = true)
230+
private TestModel testModel;
231+
225232
@Override
226233
protected void onCreate(Bundle savedInstanceState) {
227234
super.onCreate(savedInstanceState);
235+
236+
// inject()方法会自动对字段进行赋值,无需主动获取
228237
GoRouter.getInstance().inject(this);
229-
// GoRouter会自动对字段进行赋值,无需主动获取
238+
239+
// 或使用
240+
241+
// injectCheck()方法会自动对字段进行赋值,
242+
// 并检查标记@Param(required = true)的字段,
243+
// 检查不通过会抛出ParamException()类型的异常,
244+
// 可用过e.getParamName()获取参数名自行处理。
245+
try {
246+
GoRouter.getInstance().injectCheck(this);
247+
} catch (ParamException e) {
248+
String paramName = e.getParamName();
249+
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
250+
finish();
251+
return;
252+
}
253+
230254
Log.d("param", "base:" + base + "age:" + age + ",name:" + name);
231255
}
232256

233257
@Override
234258
protected void onNewIntent(Intent intent) {
235259
super.onNewIntent(intent);
260+
// inject()方法参数支持intent、bundle
236261
GoRouter.getInstance().inject(this, intent);
237262
}
238263
}
239264

265+
// 支持父类字段自动注入
240266
public class BaseParamActivity extends Activity {
241267
@Param(remark = "我是一个父类字段")
242268
protected int base;
243269
}
244270
```
245271

272+
如果使用`withObject()`方法,需要实现JSON服务
273+
274+
```java
275+
// 实现IJsonService接口
276+
@Service(remark = "json服务")
277+
public class JsonServiceImpl implements IJsonService {
278+
279+
@Override
280+
public void init() {
281+
282+
}
283+
284+
@Override
285+
public String toJson(Object instance) {
286+
// 这里演示使用了gson,也可以使用其他json转换工具
287+
return new Gson().toJson(instance);
288+
}
289+
290+
@Override
291+
public <T> T parseObject(String input, Type clazz) {
292+
return new Gson().fromJson(input, clazz);
293+
}
294+
}
295+
```
296+
246297
##### 3. 声明拦截器(拦截跳转过程,面向切面编程)
247298

248299
```java
@@ -429,6 +480,11 @@ GoRouter.getInstance().build("/main/activity")
429480
.withSerializable("user",new User())
430481
.go(this);
431482

483+
// 自定义对象传递
484+
GoRouter.getInstance().build("/main/activity")
485+
.withObject("test", new TestModel(123, "Jack"))
486+
.go(this);
487+
432488
// 觉得接口不够多,可以直接拿出Bundle赋值
433489
GoRouter.getInstance()
434490
.build("/main/activity")

0 commit comments

Comments
 (0)