Skip to content

Commit

Permalink
Merge pull request #39 from chenenyu/dev
Browse files Browse the repository at this point in the history
1.2.3
  • Loading branch information
chenenyu committed Jul 7, 2017
2 parents 361b067 + 0ad8b66 commit f240332
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 85 deletions.
18 changes: 2 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ buildscript {
}
dependencies {
...
classpath 'com.chenenyu.router:gradle-plugin:1.2.2'
classpath 'com.chenenyu.router:gradle-plugin:1.2.3'
}
}
Expand All @@ -43,10 +43,6 @@ current `router` version: ![Download](https://api.bintray.com/packages/chenenyu/

current `router-compiler` version: ![compiler](https://api.bintray.com/packages/chenenyu/maven/router-compiler/images/download.svg)

## Features

See [here](https://github.com/chenenyu/Router/wiki/%E7%89%B9%E6%80%A7) .

## Simple usage

`Router` uses annotation to specify the mapping relationship.
Expand All @@ -68,22 +64,12 @@ Please refer to the [wiki](https://github.com/chenenyu/Router/wiki) for more inf

## ProGuard

```Java
# Router
-keep class com.chenenyu.router.** {*;}
-keep class * implements com.chenenyu.router.RouteInterceptor {*;}
```
See [wiki](https://github.com/chenenyu/Router/wiki).

## Contact

QQ group: 271849001

## Other Libraries

[SuperAdater](https://github.com/byteam/SuperAdapter) : 实用的Adapter.

[img-optimizer-gradle-plugin](https://github.com/chenenyu/img-optimizer-gradle-plugin) : 一款用于优化png图片的gradle插件.

## License

[Apache 2.0](https://github.com/chenenyu/Router/blob/master/LICENSE)
4 changes: 0 additions & 4 deletions Sample/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ android {
buildTypes {
debug {
// 测试混淆
// minifyEnabled true
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
Expand Down
3 changes: 2 additions & 1 deletion Sample/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@

# Router
-keep class com.chenenyu.router.** {*;}
-keep class * implements com.chenenyu.router.RouteInterceptor {*;}
-keep class * implements com.chenenyu.router.ParamInjector {*;}

4 changes: 3 additions & 1 deletion Sample/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<activity
android:name=".MainActivity"
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
@Route({"test", "http://example.com/user", "router://test"})
public class TestActivity extends AppCompatActivity {
@InjectParam
String id;
String id = "0000";
@InjectParam(key = "status")
private String sts;
private String sts = "default";

@InjectParam
private short test1;
Expand All @@ -31,6 +31,9 @@ protected void onCreate(Bundle savedInstanceState) {

Router.injectParams(this);

Bundle mExtras = getIntent().getExtras();
id = mExtras.getString("id", id);

TextView text = (TextView) findViewById(R.id.text_test);
Bundle bundle = getIntent().getExtras();
if (bundle != null && !bundle.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
Expand All @@ -24,7 +25,7 @@
public class Module1Fragment extends Fragment {
// Test param inject, not been used.
@InjectParam
int test1;
int test1 = 123; // test default value
@InjectParam(key = "test22")
char[] test2;

Expand Down Expand Up @@ -53,5 +54,9 @@ public void callback(RouteResult state, Uri uri, String message) {
getActivity().finish();
}
});

Router.injectParams(Module1Fragment.this);

Log.d(Module1Fragment.class.getSimpleName(), "test1=" + test1);
}
}
6 changes: 3 additions & 3 deletions VERSION.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# router gradle plugin version
GRADLE_PLUGIN_VERSION=1.2.2
GRADLE_PLUGIN_VERSION=1.2.3
# router library version
ROUTER_VERSION=1.2.2
ROUTER_VERSION=1.2.3
# compiler library version
COMPILER_VERSION=1.2.2
COMPILER_VERSION=1.2.3
# annotation library version
ANNOTATION_VERSION=0.3.0
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class RouterPlugin implements Plugin<Project> {
}
}
} else {
String routerVersion = "1.2.2"
String compilerVersion = "1.2.2"
String routerVersion = "1.2.3"
String compilerVersion = "1.2.3"
// org.gradle.api.internal.plugins.DefaultExtraPropertiesExtension
ExtraPropertiesExtension ext = project.rootProject.ext
if (ext.has("routerVersion")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,17 @@
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;

import static com.chenenyu.router.compiler.util.Consts.ACTIVITY_FULL_NAME;
import static com.chenenyu.router.compiler.util.Consts.CLASS_JAVA_DOC;
import static com.chenenyu.router.compiler.util.Consts.DOT;
import static com.chenenyu.router.compiler.util.Consts.FRAGMENT_FULL_NAME;
import static com.chenenyu.router.compiler.util.Consts.FRAGMENT_V4_FULL_NAME;
import static com.chenenyu.router.compiler.util.Consts.INNER_CLASS_NAME;
import static com.chenenyu.router.compiler.util.Consts.METHOD_INJECT;
import static com.chenenyu.router.compiler.util.Consts.METHOD_INJECT_PARAM;
import static com.chenenyu.router.compiler.util.Consts.OPTION_MODULE_NAME;
import static com.chenenyu.router.compiler.util.Consts.PACKAGE_NAME;
import static com.chenenyu.router.compiler.util.Consts.PARAM_ANNOTATION_TYPE;
import static com.chenenyu.router.compiler.util.Consts.TARGET;

/**
* {@link InjectParam} annotation processor.
Expand Down Expand Up @@ -101,7 +97,11 @@ private void parseParams(Set<? extends Element> elements) {
}

private void generate() throws IllegalAccessException, IOException {
ParameterSpec objectParamSpec = ParameterSpec.builder(TypeName.OBJECT, METHOD_INJECT_PARAM).build();
final String TARGET = "target";
final String EXTRAS = "extras";
final String OBJ = "obj";

ParameterSpec objectParamSpec = ParameterSpec.builder(TypeName.OBJECT, OBJ).build();

for (Map.Entry<TypeElement, List<Element>> entry : mClzAndParams.entrySet()) {
TypeElement parent = entry.getKey();
Expand All @@ -123,83 +123,105 @@ private void generate() throws IllegalAccessException, IOException {
String.format("The target class %s must be Activity or Fragment.", simpleName));
}

mLogger.info(String.format("Start to process injected params in %s ...", simpleName));

// @Override
// public void inject(Object obj) {}
MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder(METHOD_INJECT)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addParameter(objectParamSpec);

// XXXActivity target = (XXXActivity) obj;
injectMethodBuilder.addStatement("$T $L = ($T) $L",
ClassName.get(parent), TARGET, ClassName.get(parent), METHOD_INJECT_PARAM);

mLogger.info(String.format("Start to process injected params in %s ...", simpleName));

TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(fileName)
.addJavadoc(CLASS_JAVA_DOC)
.addSuperinterface(ClassName.get(PACKAGE_NAME, "ParamInjector"))
.addModifiers(Modifier.PUBLIC);
ClassName.get(parent), TARGET, ClassName.get(parent), OBJ);
if (isActivity) { // Bundle extras = target.getIntent().getExtras();
injectMethodBuilder.addStatement("$T $L = $L.getIntent().getExtras()",
ClassName.get("android.os", "Bundle"), EXTRAS, TARGET);
} else { // Bundle extras = target.getArguments();
injectMethodBuilder.addStatement("$T $L = $L.getArguments()",
ClassName.get("android.os", "Bundle"), EXTRAS, TARGET);
}

for (Element param : params) {
InjectParam injectParam = param.getAnnotation(InjectParam.class);
String fieldName = param.getSimpleName().toString();
String key = isEmpty(injectParam.key()) ? fieldName : injectParam.key();

StringBuilder statement = new StringBuilder();
if (param.getModifiers().contains(Modifier.PRIVATE)) {
mLogger.warn(param, String.format(
"Found private field: %s, please remove 'private' modifier for a better performance.", fieldName));

String reflectName = "field_" + fieldName;

injectMethodBuilder.beginControlFlow("try")
.addStatement("$T $L = $T.class.getDeclaredField($S)",
ClassName.get(Field.class), reflectName, ClassName.get(parent), fieldName)
.addStatement("$L.setAccessible(true)", reflectName);
statement.append("$L.set($L, $L.");
concatStatement(isActivity, param.asType(), statement);
statement.append(")");
injectMethodBuilder.addStatement(statement.toString(), reflectName, TARGET, TARGET,
isEmpty(injectParam.key()) ? fieldName : injectParam.key())

Object[] args;
// field_xxx.set(target, extras.getXXX("key"
statement.append("$L.set($L, $L.get")
.append(getAccessorType(param.asType()))
.append("(")
.append("$S");
// , (FieldType) field_xxx.get(target)
if (supportDefaultValue(param.asType())) {
statement.append(", ($T) $L.get($L)");
args = new Object[]{reflectName, TARGET, EXTRAS, key,
ClassName.get(param.asType()), reflectName, TARGET};
} else {
args = new Object[]{reflectName, TARGET, EXTRAS, key};
}
// ))
statement.append("))");

injectMethodBuilder.addStatement(statement.toString(), args)
.nextControlFlow("catch ($T e)", Exception.class)
.addStatement("e.printStackTrace()")
.endControlFlow();
} else {
// target.field = (FieldType) target.
statement.append(TARGET).append(DOT).append(fieldName).append(" = ").append("($T) $L.");
concatStatement(isActivity, param.asType(), statement);
injectMethodBuilder.addStatement(statement.toString(), ClassName.get(param.asType()), TARGET,
isEmpty(injectParam.key()) ? fieldName : injectParam.key());
Object[] args;
// target.field = (FieldType) extras.getXXX("key"

statement.append("$L.$L = ($T) $L.get")
.append(getAccessorType(param.asType())).append("(")
.append("$S");
// , target.field
if (supportDefaultValue(param.asType())) {
statement.append(", $L.$L");
args = new Object[]{TARGET, fieldName, ClassName.get(param.asType()), EXTRAS, key, TARGET, fieldName};
} else {
args = new Object[]{TARGET, fieldName, ClassName.get(param.asType()), EXTRAS, key};
}
statement.append(")");

injectMethodBuilder.addStatement(statement.toString(), args);
}
}

typeBuilder.addMethod(injectMethodBuilder.build());
TypeSpec typeSpec = TypeSpec.classBuilder(fileName)
.addJavadoc(CLASS_JAVA_DOC)
.addSuperinterface(ClassName.get(PACKAGE_NAME, "ParamInjector"))
.addModifiers(Modifier.PUBLIC)
.addMethod(injectMethodBuilder.build())
.build();

JavaFile.builder(packageName, typeSpec).build().writeTo(processingEnv.getFiler());

JavaFile.builder(packageName, typeBuilder.build()).build().writeTo(processingEnv.getFiler());
mLogger.info(String.format("Params in class %s have been processed: %s.", simpleName, fileName));
}
}

private void concatStatement(boolean isActivity, TypeMirror type, StringBuilder statement) {
if (isActivity) {
// getIntent().getXXXExtra(key);
statement.append("getIntent().get").append(getBundleAccessor(type)).append("Extra");
if (type.getKind().isPrimitive()) {
if (type.getKind() == TypeKind.BOOLEAN) {
statement.append("($S, false)");
} else if (type.getKind() == TypeKind.BYTE) {
statement.append("($S, (byte)0)");
} else if (type.getKind() == TypeKind.SHORT) {
statement.append("($S, (short)0)");
} else if (type.getKind() == TypeKind.CHAR) {
statement.append("($S, (char)0)");
} else {
statement.append("($S, 0)");
}
} else {
statement.append("($S)");
}
} else {
// getArguments().getXXX(key);
statement.append("getArguments().get").append(getBundleAccessor(type)).append("($S)");
private boolean supportDefaultValue(TypeMirror typeMirror) {
if (typeMirror instanceof PrimitiveType) {
return true;
}
if (isSubtype(typeMirror, "java.lang.String") || isSubtype(typeMirror, "java.lang.CharSequence")) {
return true;
}
return false;
}

/**
Expand All @@ -209,7 +231,7 @@ private void concatStatement(boolean isActivity, TypeMirror type, StringBuilder
* @param typeMirror The type to access in the bundle
* @return The string to append to 'get' or 'put'
*/
private String getBundleAccessor(TypeMirror typeMirror) {
private String getAccessorType(TypeMirror typeMirror) {
if (typeMirror instanceof PrimitiveType) {
return typeMirror.toString().toUpperCase().charAt(0) + typeMirror.toString().substring(1);
} else if (typeMirror instanceof DeclaredType) {
Expand All @@ -221,10 +243,10 @@ private String getBundleAccessor(TypeMirror typeMirror) {
TypeMirror argType = typeArgs.get(0);
if (isSubtype(argType, "java.lang.Integer")) {
return "IntegerArrayList";
} else if (isSubtype(argType, "java.lang.CharSequence")) {
return "CharSequenceArrayList";
} else if (isSubtype(argType, "java.lang.String")) {
return "StringArrayList";
} else if (isSubtype(argType, "java.lang.CharSequence")) {
return "CharSequenceArrayList";
} else if (isSubtype(argType, "android.os.Parcelable")) {
return "ParcelableArrayList";
}
Expand Down Expand Up @@ -253,10 +275,10 @@ private String getBundleAccessor(TypeMirror typeMirror) {
} else if (compType instanceof DeclaredType) {
Element compElement = ((DeclaredType) compType).asElement();
if (compElement instanceof TypeElement) {
if (isSubtype(compElement, "java.lang.CharSequence")) {
return "CharSequenceArray";
} else if (isSubtype(compElement, "java.lang.String")) {
if (isSubtype(compElement, "java.lang.String")) {
return "StringArray";
} else if (isSubtype(compElement, "java.lang.CharSequence")) {
return "CharSequenceArray";
} else if (isSubtype(compElement, "android.os.Parcelable")) {
return "ParcelableArray";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ public class Consts {
public static final String TABLE_INTERCEPTORS = "TargetInterceptors";

public static final String METHOD_INJECT = "inject";
public static final String METHOD_INJECT_PARAM = "obj";
public static final String TARGET = "target";
// XXXActivity$$Router$$Params
public static final String INNER_CLASS_NAME = "$$Router$$ParamInjector";

Expand Down

0 comments on commit f240332

Please sign in to comment.