Skip to content

Commit bb87404

Browse files
see 12/06 log
1 parent 0a2174c commit bb87404

20 files changed

Lines changed: 871 additions & 190 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* `19/12/06` [add] Publish api plugin v1.3.
2+
* `19/11/30` [add] Publish bus plugin v2.4. Publish api plugin v1.2.
13
* `19/11/28` [add] Publish v1.26.0.
24
* `19/11/27` [add] Shadow demo.
35
* `19/11/26` [add] MVP demo.

buildSrc/src/main/groovy/Config.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Config {
5454
// 本地第一次上传插件新的版本需设置 isApply = false, useLocal = true
5555
// 本地上传成功之后 isApply = true 即可应用插件来调试,后续版本更新无需设置 isApply = false
5656
// 发布版本的话把 isApply = false, useLocal = false,更新版本号,发布成功后 isApply = true 即可使用远程库版本
57-
plugin_api : new DepConfig(isApply: true, useLocal: false, pluginPath: "com.blankj:api-gradle-plugin:1.2", pluginId: "com.blankj.api"),
57+
plugin_api : new DepConfig(isApply: true, useLocal: false, pluginPath: "com.blankj:api-gradle-plugin:1.3", pluginId: "com.blankj.api"),
5858
plugin_bus : new DepConfig(isApply: true, useLocal: false, pluginPath: "com.blankj:bus-gradle-plugin:2.4", pluginId: "com.blankj.bus"),
5959

6060
support_appcompat_v7 : new DepConfig("com.android.support:appcompat-v7:$supportVersion"),

lib/utilcode/proguard-rules.pro

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121
@com.blankj.utilcode.util.BusUtils$Bus <methods>;
2222
}
2323

24+
-keep public class * extends com.blankj.utilcode.util.ApiUtils$BaseApi
25+
-keep,allowobfuscation @interface com.blankj.utilcode.util.ApiUtils$Api
26+
-keep @com.blankj.utilcode.util.ApiUtils$Api class *
27+
2428
-keepattributes *Annotation*

lib/utilcode/src/main/java/com/blankj/utilcode/util/ApiUtils.java

Lines changed: 93 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.blankj.utilcode.util;
22

33
import android.support.annotation.NonNull;
4+
import android.text.TextUtils;
45
import android.util.Log;
56

7+
import java.io.IOException;
68
import java.lang.annotation.ElementType;
79
import java.lang.annotation.Retention;
810
import java.lang.annotation.RetentionPolicy;
@@ -23,21 +25,23 @@ public final class ApiUtils {
2325

2426
private static final String TAG = "ApiUtils";
2527

28+
private static final String PREFIX = "blankj.api/";
29+
2630
private Map<Class, BaseApi> mApiMap = new ConcurrentHashMap<>();
2731
private Map<Class, Class> mInjectApiImplMap = new HashMap<>();
2832

2933
private ApiUtils() {
30-
init();
3134
}
3235

33-
/**
34-
* It'll be injected the implClasses who have {@link ApiUtils.Api} annotation
35-
* by function of {@link ApiUtils#registerImpl} when execute transform task.
36-
*/
37-
private void init() {/*inject*/}
38-
3936
private void registerImpl(Class implClass) {
40-
mInjectApiImplMap.put(implClass.getSuperclass(), implClass);
37+
if (implClass == null) return;
38+
Class superclass = implClass.getSuperclass();
39+
if (superclass == null) return;
40+
mInjectApiImplMap.put(superclass, implClass);
41+
}
42+
43+
public static void register(Class implClass) {
44+
getInstance().registerImpl(implClass);
4145
}
4246

4347
/**
@@ -57,7 +61,17 @@ public static String toString_() {
5761

5862
@Override
5963
public String toString() {
60-
return "ApiUtils: " + mInjectApiImplMap;
64+
getAllApis();
65+
StringBuilder sb = new StringBuilder();
66+
sb.append("ApiUtils {");
67+
for (Map.Entry<Class, Class> entry : mInjectApiImplMap.entrySet()) {
68+
sb.append("\n ")
69+
.append(entry.getKey().getName())
70+
.append(": ")
71+
.append(entry.getValue().getName());
72+
}
73+
sb.append("\n}");
74+
return sb.toString();
6175
}
6276

6377
private static ApiUtils getInstance() {
@@ -70,17 +84,17 @@ private <Result> Result getApiInner(Class apiClass) {
7084
synchronized (this) {
7185
api = mApiMap.get(apiClass);
7286
if (api == null) {
73-
Class implClass = mInjectApiImplMap.get(apiClass);
87+
Class implClass = getApiImplClass(apiClass);
7488
if (implClass != null) {
7589
try {
7690
api = (BaseApi) implClass.newInstance();
7791
mApiMap.put(apiClass, api);
7892
} catch (Exception ignore) {
79-
Log.e(TAG, "The <" + implClass + "> has no parameterless constructor.");
93+
Log.e(TAG, "The api of <" + implClass + "> has no parameterless constructor.");
8094
return null;
8195
}
8296
} else {
83-
Log.e(TAG, "The <" + apiClass + "> doesn't implement.");
97+
Log.e(TAG, "The api of <" + apiClass + "> doesn't implement.");
8498
return null;
8599
}
86100
}
@@ -90,6 +104,73 @@ private <Result> Result getApiInner(Class apiClass) {
90104
return (Result) api;
91105
}
92106

107+
private Class getApiImplClass(Class apiClass) {
108+
Class apiImplClass = mInjectApiImplMap.get(apiClass);
109+
if (apiImplClass != null) return apiImplClass;
110+
try {
111+
String[] apiImpls = Utils.getApp().getAssets().list(PREFIX + apiClass.getName());
112+
if (apiImpls == null) {
113+
return null;
114+
}
115+
if (apiImpls.length != 1) {
116+
Log.e(TAG, "The api of <" + apiClass + "> has more than one implement.");
117+
return null;
118+
}
119+
String apiImpl = apiImpls[0];
120+
if (TextUtils.isEmpty(apiImpl)) {
121+
Log.e(TAG, "The api of <" + apiClass + ">'s name is empty.");
122+
return null;
123+
}
124+
String[] apiImpl_isMock = apiImpl.split("-");
125+
if (apiImpl_isMock.length != 2) {
126+
Log.e(TAG, "The api of <" + apiClass + ">'s implement <" + apiImpl
127+
+ "> which format of name is wrong.");
128+
return null;
129+
}
130+
String className = apiImpl_isMock[0];
131+
boolean isMock = Boolean.parseBoolean(apiImpl_isMock[1]);
132+
if (TextUtils.isEmpty(className)) {
133+
return null;
134+
}
135+
apiImplClass = Class.forName(className);
136+
Class superclass = apiImplClass.getSuperclass();
137+
if (superclass != null) {
138+
//noinspection unchecked
139+
if (apiClass.isAssignableFrom(apiImplClass)) {
140+
mInjectApiImplMap.put(apiClass, apiImplClass);
141+
return apiImplClass;
142+
} else {
143+
Log.e(TAG, "<" + apiImplClass.getName() + ">'s superClass is <"
144+
+ superclass.getName() + ">, not <" + apiClass.getName() + ">");
145+
return null;
146+
}
147+
} else {
148+
Log.e(TAG, "<" + apiImplClass.getName() + ">'s superClass is <" +
149+
"null>, not <" + apiClass.getName() + ">");
150+
return null;
151+
}
152+
} catch (Exception e) {
153+
e.printStackTrace();
154+
return null;
155+
}
156+
}
157+
158+
private void getAllApis() {
159+
try {
160+
String[] apis = Utils.getApp().getAssets().list(PREFIX);
161+
if (apis == null) return;
162+
for (String api : apis) {
163+
try {
164+
getApiImplClass(Class.forName(api));
165+
} catch (ClassNotFoundException e) {
166+
e.printStackTrace();
167+
}
168+
}
169+
} catch (IOException e) {
170+
e.printStackTrace();
171+
}
172+
}
173+
93174
private static class LazyHolder {
94175
private static final ApiUtils INSTANCE = new ApiUtils();
95176
}

lib/utilcode/src/test/java/com/blankj/utilcode/util/ApiUtilsTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@
1111
* desc :
1212
* </pre>
1313
*/
14-
public class ApiUtilsTest {
14+
public class ApiUtilsTest extends BaseTest {
1515

1616
@Before
1717
public void setUp() throws Exception {
18-
ReflectUtils.reflect(ApiUtils.class)
19-
.method("getInstance")
20-
.method("registerImpl", TestApiImpl.class);
18+
ApiUtils.register(TestApiImpl.class);
2119
}
2220

2321
@Test

plugin/api-gradle-plugin/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Change Log
22

3+
## v1.3
4+
更新注入模式为插入到 assets 文件中,不再往 ApiUtils 中插入代码,为支持 adb install-multiple 作准备
5+
36
## v1.2
47
去除 gradle 版本依赖的问题
58

plugin/api-gradle-plugin/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dependencies {
2929
implementation gradleApi()
3030
implementation localGroovy()
3131

32+
testImplementation Config.depConfig.plugin_gradle.dep
3233
testImplementation Config.depConfig.test_junit.dep
3334
}
3435

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
2+
body {
3+
margin: 0;
4+
padding: 0;
5+
font-family: sans-serif;
6+
font-size: 12pt;
7+
}
8+
9+
body, a, a:visited {
10+
color: #303030;
11+
}
12+
13+
#content {
14+
padding-left: 50px;
15+
padding-right: 50px;
16+
padding-top: 30px;
17+
padding-bottom: 30px;
18+
}
19+
20+
#content h1 {
21+
font-size: 160%;
22+
margin-bottom: 10px;
23+
}
24+
25+
#footer {
26+
margin-top: 100px;
27+
font-size: 80%;
28+
white-space: nowrap;
29+
}
30+
31+
#footer, #footer a {
32+
color: #a0a0a0;
33+
}
34+
35+
#line-wrapping-toggle {
36+
vertical-align: middle;
37+
}
38+
39+
#label-for-line-wrapping-toggle {
40+
vertical-align: middle;
41+
}
42+
43+
ul {
44+
margin-left: 0;
45+
}
46+
47+
h1, h2, h3 {
48+
white-space: nowrap;
49+
}
50+
51+
h2 {
52+
font-size: 120%;
53+
}
54+
55+
ul.tabLinks {
56+
padding-left: 0;
57+
padding-top: 10px;
58+
padding-bottom: 10px;
59+
overflow: auto;
60+
min-width: 800px;
61+
width: auto !important;
62+
width: 800px;
63+
}
64+
65+
ul.tabLinks li {
66+
float: left;
67+
height: 100%;
68+
list-style: none;
69+
padding-left: 10px;
70+
padding-right: 10px;
71+
padding-top: 5px;
72+
padding-bottom: 5px;
73+
margin-bottom: 0;
74+
-moz-border-radius: 7px;
75+
border-radius: 7px;
76+
margin-right: 25px;
77+
border: solid 1px #d4d4d4;
78+
background-color: #f0f0f0;
79+
}
80+
81+
ul.tabLinks li:hover {
82+
background-color: #fafafa;
83+
}
84+
85+
ul.tabLinks li.selected {
86+
background-color: #c5f0f5;
87+
border-color: #c5f0f5;
88+
}
89+
90+
ul.tabLinks a {
91+
font-size: 120%;
92+
display: block;
93+
outline: none;
94+
text-decoration: none;
95+
margin: 0;
96+
padding: 0;
97+
}
98+
99+
ul.tabLinks li h2 {
100+
margin: 0;
101+
padding: 0;
102+
}
103+
104+
div.tab {
105+
}
106+
107+
div.selected {
108+
display: block;
109+
}
110+
111+
div.deselected {
112+
display: none;
113+
}
114+
115+
div.tab table {
116+
min-width: 350px;
117+
width: auto !important;
118+
width: 350px;
119+
border-collapse: collapse;
120+
}
121+
122+
div.tab th, div.tab table {
123+
border-bottom: solid #d0d0d0 1px;
124+
}
125+
126+
div.tab th {
127+
text-align: left;
128+
white-space: nowrap;
129+
padding-left: 6em;
130+
}
131+
132+
div.tab th:first-child {
133+
padding-left: 0;
134+
}
135+
136+
div.tab td {
137+
white-space: nowrap;
138+
padding-left: 6em;
139+
padding-top: 5px;
140+
padding-bottom: 5px;
141+
}
142+
143+
div.tab td:first-child {
144+
padding-left: 0;
145+
}
146+
147+
div.tab td.numeric, div.tab th.numeric {
148+
text-align: right;
149+
}
150+
151+
span.code {
152+
display: inline-block;
153+
margin-top: 0em;
154+
margin-bottom: 1em;
155+
}
156+
157+
span.code pre {
158+
font-size: 11pt;
159+
padding-top: 10px;
160+
padding-bottom: 10px;
161+
padding-left: 10px;
162+
padding-right: 10px;
163+
margin: 0;
164+
background-color: #f7f7f7;
165+
border: solid 1px #d0d0d0;
166+
min-width: 700px;
167+
width: auto !important;
168+
width: 700px;
169+
}
170+
171+
span.wrapped pre {
172+
word-wrap: break-word;
173+
white-space: pre-wrap;
174+
word-break: break-all;
175+
}
176+
177+
label.hidden {
178+
display: none;
179+
}

0 commit comments

Comments
 (0)