or Call extends Foo>");
113 | }
114 | return getParameterUpperBound(0, (ParameterizedType) returnType);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/Dilutions/src/main/java/com/linhonghong/dilutions/utils/DilutionsUriBuilder.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.os.Build;
5 | import android.text.TextUtils;
6 | import android.util.Base64;
7 |
8 | import com.alibaba.fastjson.JSONObject;
9 | import com.linhonghong.dilutions.DilutionsValue;
10 |
11 | import java.io.UnsupportedEncodingException;
12 |
13 | /**
14 | * Created by Linhh on 2017/7/28.
15 | */
16 |
17 | public class DilutionsUriBuilder {
18 |
19 | /**
20 | * 构造通用的Uri 协议
21 | *
22 | * test linhonghong://dilutions/test
23 | *
24 | * @param path 如: group ,前面不要带"/"
25 | * @param param
26 | * @return
27 | */
28 | public static String buildUri(String scheme, String path, JSONObject param) {
29 | String json = "";
30 | if (param != null) {
31 | json = param.toString();
32 | }
33 |
34 | return buildUri(scheme, path, json);
35 | }
36 |
37 | /**********
38 | * 私有方法
39 | **********/
40 |
41 | public static String buildUri(String scheme, String path, String json) {
42 | String mHost = "";
43 | if(!isNull(path) && path.startsWith("/")){
44 | path = path.substring(1, path.length());
45 | }
46 | String mPath = path;
47 | if(!isNull(scheme) && scheme.endsWith("://")){
48 | scheme = scheme.substring(0, scheme.length() - 3);
49 | }
50 | String query = buildQuery(json);
51 | return scheme + ":" + "//" + mHost + "/" + mPath + "?" + query;
52 | }
53 |
54 | public static boolean isNull(String str) {
55 | try {
56 | if (str == null) {
57 | return true;
58 | } else if (str != null) {
59 | if (str.equals("") || str.equals("null") || str.equals("[]")) {
60 | return true;
61 | } else if (str.trim().equals("") || str.trim().equals("null")) {
62 | return true;
63 | } else {
64 | return false;
65 | }
66 | } else {
67 | return false;
68 | }
69 | } catch (Exception ex) {
70 | ex.printStackTrace();
71 | }
72 | return true;
73 |
74 | }
75 |
76 | /**
77 | * 获取Query,需要进行 base64 编码
78 | *
79 | * @param jsonObject
80 | * @return
81 | */
82 | private static String buildQuery(JSONObject jsonObject) {
83 | if (jsonObject == null) {
84 | return "";
85 | }
86 | return buildQuery(jsonObject.toString());
87 | }
88 |
89 | private static String buildQuery(String json) {
90 | if (TextUtils.isEmpty(json)) {
91 | return "";
92 | }
93 |
94 | return DilutionsValue.VAL_PARAMS + "=" + base64UrlEncode(json);
95 |
96 | }
97 |
98 | /**
99 | * BASE64 编码,URL_SAFE
100 | *
101 | * @param input
102 | * @return
103 | */
104 | @TargetApi(Build.VERSION_CODES.FROYO)
105 | public static String base64UrlEncode(String input) {
106 | String ENCODING = "UTF-8";
107 | String result = null;
108 | byte[] b = Base64.encode(input.getBytes(), Base64.URL_SAFE);
109 | try {
110 | result = new String(b, ENCODING);
111 | } catch (UnsupportedEncodingException e) {
112 | e.printStackTrace();
113 | }
114 | return result;
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/Dilutions/src/main/java/com/linhonghong/dilutions/utils/DilutionsUtil.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Build;
7 | import android.os.Bundle;
8 | import android.util.Base64;
9 |
10 | import com.linhonghong.dilutions.DilutionsInstrument;
11 |
12 | import org.json.JSONObject;
13 |
14 | import java.io.UnsupportedEncodingException;
15 |
16 | /**
17 | * Created by Linhh on 16/11/30.
18 | */
19 |
20 | public class DilutionsUtil {
21 |
22 | public static String ENCODING = "UTF-8";
23 |
24 | public static Object getParams(String type){
25 | if("boolean".equals(type)){
26 | return false;
27 | }
28 | if("char".equals(type)){
29 | return null;
30 | }
31 | if("short".equals(type)){
32 | return 0;
33 | }
34 | if("int".equals(type)){
35 | return 0;
36 | }
37 | if("float".equals(type)){
38 | return 0f;
39 | }
40 | if("double".equals(type)){
41 | return 0f;
42 | }
43 | if("long".equals(type)){
44 | return 0;
45 | }
46 | if("byte".equals(type)){
47 | return null;
48 | }
49 | return null;
50 | }
51 |
52 | public static Class> getParamsClass(String type) throws Exception{
53 | if("boolean".equals(type)){
54 | return boolean.class;
55 | }
56 | if("char".equals(type)){
57 | return char.class;
58 | }
59 | if("short".equals(type)){
60 | return short.class;
61 | }
62 | if("int".equals(type)){
63 | return int.class;
64 | }
65 | if("float".equals(type)){
66 | return float.class;
67 | }
68 | if("double".equals(type)){
69 | return double.class;
70 | }
71 | if("long".equals(type)){
72 | return long.class;
73 | }
74 | return Class.forName(type);
75 | }
76 |
77 | public static Object formatString(Object obj){
78 | if(obj == null){
79 | return "";
80 | }
81 | if(obj instanceof String){
82 | return String.valueOf(obj);
83 | }
84 | return obj;
85 | }
86 |
87 | /**
88 | * BASE64 解码,URL_SAFE
89 | *
90 | * @param input
91 | * @return
92 | */
93 | //TODO
94 | @TargetApi(Build.VERSION_CODES.FROYO)
95 | public static String base64UrlDecode(String input) {
96 | input = input.replace("/", "_").replace("+", "-").replace("=", "");
97 | String result = null;
98 | byte[] b = Base64.decode(input, Base64.URL_SAFE);
99 | try {
100 | result = new String(b, ENCODING);
101 | } catch (UnsupportedEncodingException e) {
102 | e.printStackTrace();
103 | }
104 | return result;
105 | }
106 |
107 | public static boolean isNull(String str) {
108 | try {
109 | if (str == null) {
110 | return true;
111 | } else if (str != null) {
112 | if (str.equals("") || str.equals("null") || str.equals("[]")) {
113 | return true;
114 | } else return str.trim().equals("") || str.trim().equals("null");
115 | } else {
116 | return false;
117 | }
118 | } catch (Exception ex) {
119 | ex.printStackTrace();
120 | }
121 | return true;
122 |
123 | }
124 |
125 | public static boolean isEqual(String src, String dest) {
126 | try {
127 | if (src == null)
128 | src = "";
129 | if (dest == null)
130 | dest = "";
131 | return src.equals(dest);
132 | } catch (Exception ex) {
133 | ex.printStackTrace();
134 | }
135 | return false;
136 | }
137 |
138 | /**
139 | * 内部放path需要的数据
140 | */
141 | public static final String PARAMS_KEY = "params";
142 |
143 | /*
144 | public static String ID = "id";
145 | public static String URL = "url";
146 | public static String COMMUNITY_CATEGORY_TAB = "community_category_tab";*/
147 |
148 |
149 | public static boolean isFromUri(Intent intent) {
150 | if (intent == null) {
151 | return false;
152 | }
153 | return isFromUri(intent.getExtras());
154 | }
155 |
156 | public static boolean isFromUri(Bundle bundle) {
157 | if (bundle == null) {
158 | return false;
159 | }
160 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM);
161 | if (isNull(json)) {
162 | return false;
163 | }
164 | return true;
165 | }
166 |
167 | public static String getValue(String name, Bundle bundle) {
168 | try {
169 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM);
170 | if (!isNull(json)) {
171 | JSONObject jsonObject = new JSONObject(json);
172 | String jsonValue = jsonObject.getString("params");
173 | if (!isNull(jsonValue)) {
174 | JSONObject job = new JSONObject(jsonValue);
175 | Object value = job.get(name);
176 | if (value != null) {
177 | if (value instanceof Integer) {
178 | return (Integer) value + "";
179 | }
180 | return value.toString();
181 | }
182 | }
183 | }
184 | } catch (Exception e) {
185 | e.printStackTrace();
186 | }
187 | return "";
188 | }
189 |
190 | private static String getValue(String name, String defValue, Bundle bundle) {
191 | try {
192 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM);
193 | if (!isNull(json)) {
194 | JSONObject jsonObject = new JSONObject(json);
195 | String jsonValue = jsonObject.optString(PARAMS_KEY);
196 | if (!isNull(jsonValue)) {
197 | JSONObject job = new JSONObject(jsonValue);
198 | Object value = job.opt(name);
199 | if (value != null) {
200 | if (value instanceof Integer) {
201 | return (Integer) value + "";
202 | }
203 | return value.toString();
204 | }
205 | }
206 | }
207 | } catch (Exception e) {
208 | e.printStackTrace();
209 | }
210 | return defValue;
211 | }
212 |
213 | public static String getParamByBundle(Bundle bundle) {
214 | try {
215 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM);
216 | if (!isNull(json)) {
217 | JSONObject jsonObject = new JSONObject(json);
218 | return jsonObject.getString(PARAMS_KEY);
219 | }
220 | } catch (Exception e) {
221 | e.printStackTrace();
222 | }
223 | return "";
224 | }
225 | /**
226 | * 获取Intent参数值
227 | *
228 | * @param name;参数名字;UriParam 提供了很多通用的参数,可以直接用;
229 | * @param intent
230 | * @return
231 | */
232 | public static String getIntentParam(String name, Intent intent) {
233 | return getValue(name, "", intent.getExtras());
234 | }
235 |
236 | public static com.alibaba.fastjson.JSONObject getUriParamsWithString(String uri_s) throws Exception {
237 | Uri uri = Uri.parse(uri_s);
238 | String params = uri.getQueryParameter("params");
239 | params = DilutionsUtil.base64UrlDecode(params);
240 | com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(params);
241 | return jsonObject;
242 | }
243 | }
244 |
--------------------------------------------------------------------------------
/Dilutions/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Dilutions
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dilutions
2 |
3 | Dilutions是一个专门用于模块间数据协议通信的解耦协议框架,提供高性能数据分析和通信功能,解耦多项目多模块间的数据通信,简化代码逻辑成本。
4 |
5 | 通过一段URI字符串就能实现所有操作。
6 |
7 | 这个框架已经在 美柚 稳定 ,2016 年就开始使用,美柚总用户突破1亿,日活接近千万,Dilutions框架经过亿万用户的测试,代码的稳定性是可以放心的。有需求或者bug可以提issues,我会尽快回复。
8 |
9 | 
10 |
11 | # 跨模块UI跳转
12 |
13 | 通过Dilutions实现跨模块间的UI跳转。
14 |
15 | ## 基本UI跳转
16 |
17 | 假设此时需要从模块1中的界面A跳转到模块2中的界面B,并且携带一些数据,由于模块1和模块2之间互不依赖,想要跨模块打开某个界面是比较困难的。
18 |
19 | Dilutions提供了跨模块间的UI跳转能力,通过定义一串共同的URI协议即可实现界面A到界面B的跳转。
20 |
21 | 假设我们约定这串跳转协议URI为:
22 |
23 | ```java
24 | String uri = "dilutions:///ui/atob"
25 | ```
26 |
27 | 那么,这时只要在界面B中加上注解:
28 |
29 | ```java
30 | @ActivityProtocol("/ui/atob")
31 | public class ActivityB extends AppCompatActivity {
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | }
36 | }
37 | ```
38 |
39 | 界面A调用如下语句即可实现UI跳转:
40 |
41 | ```java
42 | Dilutions.create().formatProtocolService(uri);
43 | ```
44 |
45 | ## 携带数据
46 |
47 | 如果这时候界面B需要接收一些参数,那么界面A如何传递呢?
48 |
49 | 我们假设界面B需要的参数如下:
50 |
51 | ```java
52 | int user_id;
53 | String user_name;
54 | ```
55 |
56 | 那么界面B只需要将界面代码改为:
57 |
58 | ```java
59 | @ActivityProtocol("/ui/atob")
60 | public class ActivityB extends AppCompatActivity {
61 | @ActivityProtocolExtra("user_id")
62 | int user_id;
63 |
64 | @ActivityProtocolExtra("user_name")
65 | String user_name;
66 |
67 | @Override
68 | protected void onCreate(Bundle savedInstanceState) {
69 | super.onCreate(savedInstanceState);
70 |
71 | Dilutions.create().register(this);//注意,一定要注册dilutions
72 |
73 | Log.i(user_id + user_name);//使用传递过来的数据
74 | }
75 | }
76 | ```
77 |
78 | 界面A通过调用如下代码即可传递参数并且实现跳转:
79 |
80 | ```java
81 | String uri = "dilutions:///ui/atob"
82 | HashMap map = new HashMap<>();
83 | map.put("user_id", 222);
84 | map.put("user_name", "二红");
85 | Dilutions.create().formatProtocolService(uri, map, null);
86 | ```
87 |
88 | ## 携带对象数据
89 |
90 | 有的时候,我们传递的不一定是基础类型,而是对象,Dilutions也可以帮你完成传递
91 |
92 | ```java
93 | @ActivityProtocol("/ui/atob")
94 | public class ActivityB extends AppCompatActivity {
95 | @ActivityProtocolExtra("test_object")
96 | TestObject test_object;
97 | }
98 | ```
99 |
100 | 界面A通过调用如下代码即可传递参数并且实现跳转:
101 |
102 | ```java
103 | String uri = "dilutions:///ui/atob"
104 | HashMap map = new HashMap<>();
105 | map.put("test_object", new TestObject);
106 | Dilutions.create().formatProtocolService(uri, map, null);
107 | ```
108 |
109 | 而界面B中可以直接拿到那个对象进行使用,但是需要注意的是传递的对象必须序列化。
110 |
111 | ## 转场动画
112 |
113 | 有时候需要动画转场来跳转界面,Dilutions也支持Activity的动画转场
114 |
115 | 只需要在对应的Activity加上注解即可
116 |
117 | ```java
118 | @ActivityProtocol({"/test","/test2"})
119 | @CustomAnimation(enter = R.anim.enter, exit = R.anim.exit)
120 | public class MainActivity extends AppCompatActivity {
121 | }
122 | ```
123 |
124 | CustomAnimation注解中的enter表示进入Activity的动画,exit为退出
125 |
126 | # 跨模块方法调用
127 |
128 | 我们上面学会了跨模块的UI跳转,下面将学到如何通过Dilutions进行跨模块的方法调用。
129 |
130 | 假设模块1想调用模块2的一个方法,模块1和模块2不互相依赖,你该怎么做呢?
131 |
132 | 再比如现在有方法A和方法B,想通过服务器决定来调用哪一个,怎么做比较好呢?
133 |
134 | Dilutions帮你解决了这个问题,使用方式和UI跳转差不多,你只需要URI协议字符串即可。
135 |
136 | ## 基础的跨模块调用方法
137 |
138 | 假设模块2中存在一个原生方法,这个方法之前是被模块2内的其他类直接使用的,现在需要支持跨模块特性。
139 |
140 | 首先模块2的方法需要加上注解:
141 |
142 | ```java
143 | @MethodProtocol("/method")
144 | public void method(){
145 | Log.d("test","method had being called.");
146 | }
147 | ```
148 |
149 | 这个方法可以在任何一个类中,任意地方,只需要注解。
150 |
151 | 接下来,你应该从UI跳转方法中学到了如何识别协议URI,没错,这个方法中的"/method"就是协议,因此协议应该长这样:
152 |
153 | ```java
154 | String uri = "dilutions:///method";
155 | ```
156 |
157 | 那么调用方依然是
158 |
159 | ```java
160 | Dilutions.create().formatProtocolService(uri);
161 | ```
162 |
163 | 这样就完成了跨模块的方法调用。
164 |
165 | 所以你可以看到入口是不变的,一个方法可以通过URI协议的不同,正确的调用实现方。
166 |
167 | ## 携带参数
168 |
169 | 那么这时候你肯定想到了,我的方法肯定不可能都是无参啊,Dilutions可以支持带参调用吗?
170 |
171 | 答案是肯定的,仍然是通过注解。
172 |
173 | 我们假设有参方法method2如下:
174 |
175 | ```java
176 | public void method2(String username, int userid, boolean open){
177 | Log.d("test","method had being called." + username + userid);
178 | }
179 | ```
180 |
181 | 那么需要添加注解,改造成如下代码:
182 |
183 | ```java
184 | @MethodProtocol("/method2")
185 | public void method2(@MethodParam("username")String username, @MethodParam("userid")int userid, @MethodParam("open")boolean open){
186 | Log.d("test","method had being called." + username + userid);
187 | }
188 | ```
189 |
190 | 调用方只需要跟带数据跳转UI的操作方式一致就可以:
191 |
192 | ```java
193 | String uri = "dilutions:///method2"
194 | HashMap map = new HashMap<>();
195 | map.put("user_id", 222);
196 | map.put("user_name", "二红");
197 | map.put("open", true);
198 | Dilutions.create().formatProtocolService(uri, map, null);
199 | ```
200 |
201 | 如果传递的数据不存在,比如没有传递open这个数据,那么对应的实现方法仍然会被执行,但是对应的入参会以默认值传入。
202 |
203 | ## 携带对象数据
204 |
205 | 跟跳转UI一样,Dilutions也可以携带对象数据跨模块调用方法。
206 |
207 | ```java
208 | @MethodProtocol("/method2")
209 | public void method2(@MethodParam("username")TestObject username){
210 | Log.d("test","method had being called.");
211 | }
212 | ```
213 |
214 | ## 方法实现方相关
215 |
216 | Dilutions对实现方的方法会进行自动映射,实现方不一定需要全部将入参标注参数,并且对注解顺序没有任何要求,比如:
217 |
218 | ```java
219 | @MethodProtocol("/method2")
220 | public void method2(@MethodParam("username")String username, int userid, @MethodParam("open")boolean open){
221 | Log.d("test","method had being called." + username + userid);
222 | }
223 | ```
224 |
225 | ## 方法返回值
226 |
227 | 那么你肯定还会提到,有的方法还有返回值,那么怎么办呢?
228 |
229 | Dilutions同样解决了这个问题。
230 |
231 | 将方法method2改为:
232 |
233 | ```java
234 | @MethodProtocol("/method2")
235 | public int method2(@MethodParam("username")String username, int userid, @MethodParam("open")boolean open){
236 | Log.d("test","method had being called." + username + userid);
237 | return 0;
238 | }
239 | ```
240 |
241 | 调用方改为
242 |
243 | ```java
244 | Dilutions.create().formatProtocolServiceWithCallback(uri,new DilutionsCallBack(){
245 | public void onDilutions(DilutionsData data){
246 | Object result = data.getResult();
247 | //result即为方法调用返回值结果
248 | }
249 | });
250 | ```
251 |
252 | ## URI协议
253 |
254 | 在Dilutions中,我们知道所有的跨模块操作都是基于协议,因此,我们通过一串URI字符串即可实现跨模块的数据交互。
255 |
256 | 这个URI协议可以是从服务器下发的,也可以是客户端直接写好的,通过这个方式可以实现动态的方法调用和界面跳转。
257 |
258 | 在Dilutions中,协议的格式如下:
259 |
260 | ```xml
261 | dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ==
262 | ```
263 |
264 | 其中dilutions:// 是协议头,这个是可以通过Dilutions自定义的,你可以给不同的app、业务设置不同的协议头,用来区分。
265 |
266 | 其中/circles/group这种,你已经知道了,他就是主要协议path,只有实现方实现了才会响应。
267 |
268 | 后面的params其实是固定样式,params=后面跟的是协议的数据参数,这个数据参数是base64过的json。
269 |
270 | 所以如果要实现动态跳转或者动态方法调用,服务器下发协议字符串需要采用这个逻辑构造。
271 |
272 | 在客户端中,Dilutions提供了一系列的工具类来帮助使用者生成,正常来说,我们只需要使用Dilutions.formatService相关方法即可,但是需求总是会变的,所以接下来会展示如何生成一个Dilutions的URI协议。
273 |
274 | ### 客户端生成URI协议
275 |
276 | ```java
277 | String uri = DilutionsUriBuilder.buildUri("dilutions://", "/testmap","{ \"path\":\"bi_information\", \"tt\" : {\"action\":1,\"floor\":2}}");
278 | Dilutions.create().formatProtocolService(uri);
279 | ```
280 |
281 | 以上代码片段是生成生成一个URI协议,然后再执行它。
282 |
283 | 你可以通过DilutionsUriBuilder这个类进行协议的生成和解析操作。
284 |
285 | ### 拦截协议
286 |
287 | 有的时候你可能需要拦截部分协议,在它们执行前进行额外的操作,那么拦截器是你的不二之选。
288 |
289 | ```java
290 | Dilutions.create().formatProtocolServiceWithInterceptor(uri, new DilutionsInterceptor(){
291 | public boolean interceptor(DilutionsData data){
292 | return false;
293 | }
294 | })
295 | ```
296 |
297 | 在拦截器的DilutionsData回调对象中存在很多获得协议信息的方法,比如执行的intent等,你可以对其进行修改,你甚至可以在里面重新定向到另一个协议实现,通过更改boolean返回值来决定(true=拦截,不继续执行原本的协议,false=继续执行)。
298 |
299 | ### 添加协议头
300 |
301 | 你可以通过动态添加协议头来决定你当前应用需要支持哪些协议。
302 |
303 | ```java
304 | Dilutions.create().getAppMap().add("dilutions2");
305 | ```
306 |
307 | ## 代理跳转UI
308 |
309 | 上面已经介绍过使用URI协议进行跳转UI,但实际上在Dilutions中,你还可以通过动态代理的方式进行跳转。
310 |
311 | 首先需要编写代理接口
312 |
313 | ```java
314 | public interface DebugService {
315 |
316 | @ProtocolPath("/test")
317 | void renderPage(@ExtraParam("test") String test, @ExtraParam("id") Object obj);
318 | }
319 | ```
320 |
321 | 其中ProtocolPath内的是协议的path,方法名随意,ExtraParam注解对应的是参数名,后面跟类型。
322 |
323 | 编写完代理接口后,通过调用代理接口即可实现协议跳转执行。
324 |
325 | ```java
326 | Dilutions.create().formatProtocolService(DebugService.class).renderPage(参数);
327 | ```
328 |
329 | PS:当前版本动态代理只能跳转UI,后续会实现跳转方法实现。
330 |
331 | ## 获取协议数据
332 |
333 | ### 注解获取
334 |
335 | 当你发起了一个协议打开一个UI的时候,你需要获得传递过来的协议数据,通过Dilutions注解可以在Activity或者Fragment中获得协议数据。
336 |
337 | 在Activity中:
338 |
339 | ```java
340 | /**
341 | * 读取test参数
342 | */
343 | @ActivityProtocolExtra("test")
344 | TestObj st;
345 |
346 | /**
347 | * 读取query参数
348 | */
349 | @ActivityProtocolExtra("query")
350 | int query;
351 |
352 | @ActivityProtocolExtra("groupID")
353 | int groupID;
354 |
355 | ```
356 |
357 |
358 | 在Fragment中:
359 |
360 | ```java
361 | /**
362 | * 读取test参数
363 | */
364 | @FragmentArg("test")
365 | TestObj st;
366 |
367 | /**
368 | * 读取query参数
369 | */
370 | @FragmentArg("query")
371 | int query;
372 |
373 | @FragmentArg("groupID")
374 | int groupID;
375 |
376 | ```
377 |
378 |
379 | 最后需要在对应的Activity或者Fragment的onCreate()方法中注册
380 |
381 | ```java
382 | Dilutions.create().register(this);
383 | ```
384 |
385 |
386 | 注册完毕后,这些数据参数就可以使用了。
387 |
388 | PS:Dilutions直接任意数据对象传递。
389 |
390 | ### 原始获取
391 |
392 | 你可以不通过注解方式获取,你可以通过getIntent来获取注解,比如上述的数据通过下面的方式也可以获取到:
393 |
394 | ```java
395 | int query = getIntent().getIntExtra("query",0);
396 | ```
397 |
398 | ### 额外参数获取
399 |
400 | 有时候你可能还想获得传递过来的完整协议,或者其他信息来处理一些业务需求,Dilutions定义了一些参数名,你可以通过注解方式也可以通过原始方式获得对应的数据。
401 |
402 | ```java
403 | class DilutionsInstrument{
404 | //协议目标class类
405 | public static final String URI_CALL_CLASS = "uri-call-clazz";
406 | //协议的path
407 | public static final String URI_CALL_PATH = "uri-call-path";
408 | //协议的参数
409 | public static final String URI_CALL_PARAM = "uri-call-param";
410 | //完整协议
411 | public static final String URI_CALL_ALL = "uri-call-all";
412 | //如何跳转的,是代理还是协议
413 | public static final String URI_FROM = "uri-from";
414 | }
415 | ```
416 |
417 | ## 初始化
418 |
419 | Dilutions需要初始化才能够被使用,只需要一次即可。
420 |
421 | ```java
422 | Dilutions.init(Context);
423 | ```
424 |
425 | ## gradle
426 |
427 | 当前最新版本1.0.8
428 |
429 |
430 | 在主工程最外层配置gradle :classpath 'linhonghong.lib:dilutions-compiler:1.0.6'
431 |
432 | ```groovy
433 | buildscript {
434 | repositories {
435 | jcenter()
436 | }
437 | dependencies {
438 | classpath 'com.android.tools.build:gradle:2.2.0'
439 | //添加这个
440 | classpath 'linhonghong.lib:dilutions-compiler:1.0.8'
441 | }
442 | }
443 | ```
444 |
445 | 在需要dilutions的地方添加:
446 |
447 | ```groovy
448 | compile 'linhonghong.lib:dilutions:1.0.8'
449 | ```
450 |
451 | Dilutions依赖阿里巴巴fastjson的json解析,因此需要在你的工程中依赖fastjson
452 |
453 | ```groovy
454 | compile 'com.alibaba:fastjson:1.1.68.android'
455 | ```
456 |
457 | 主工程apply插件
458 |
459 | ```groovy
460 | apply plugin: 'dilutions'
461 | ```
462 |
463 | Dilutions在Gradle2.x以及以上版本测试通过。
464 |
465 | ## 混淆
466 |
467 | ```xml
468 | -keep public class com.linhonghong.dilutions.inject.support.DilutionsInjectUIMetas
469 | -keep public class com.linhonghong.dilutions.inject.support.DilutionsInjectMeta
470 | ```
471 |
472 | ## Developed By
473 |
474 | * Linhonghong -
475 |
476 | ## License
477 | Copyright 2016 LinHongHong
478 |
479 | Licensed under the Apache License, Version 2.0 (the "License");
480 | you may not use this file except in compliance with the License.
481 | You may obtain a copy of the License at
482 |
483 | http://www.apache.org/licenses/LICENSE-2.0
484 |
485 | Unless required by applicable law or agreed to in writing, software
486 | distributed under the License is distributed on an "AS IS" BASIS,
487 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
488 | See the License for the specific language governing permissions and
489 | limitations under the License.
490 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'dilutions'
3 |
4 | android {
5 | compileSdkVersion 25
6 | buildToolsVersion '26.0.2'
7 | defaultConfig {
8 | applicationId "com.linhonghong.demo.dilutions"
9 | minSdkVersion 14
10 | targetSdkVersion 25
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:25.3.1'
25 | compile 'linhonghong.lib:dilutions:1.0.9'
26 | compile 'com.alibaba:fastjson:1.1.68.android'
27 | // compile project (":Dilutions")
28 | }
29 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/Linhh/Develop/Android/android-sdk-macosx/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/assets/uiInterpreter.conf:
--------------------------------------------------------------------------------
1 | DILUTIONS.SCHEME.IN='dilutions.test'
--------------------------------------------------------------------------------
/app/src/main/java/com/linhonghong/demo/dilutions/Application.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.demo.dilutions;
2 |
3 | import com.linhonghong.dilutions.Dilutions;
4 |
5 | public class Application extends android.app.Application{
6 | @Override
7 | public void onCreate() {
8 | super.onCreate();
9 | //初始化
10 | Dilutions.init(this);
11 | //添加协议头
12 | Dilutions.create().addScheme("dilutions2");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/linhonghong/demo/dilutions/DebugService.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.demo.dilutions;
2 |
3 | import com.linhonghong.dilutions.annotations.ExtraParam;
4 | import com.linhonghong.dilutions.annotations.ProtocolPath;
5 |
6 | /**
7 | * Created by Linhh on 17/3/7.
8 | */
9 |
10 | public interface DebugService {
11 |
12 | @ProtocolPath("/test")
13 | void renderPage(@ExtraParam("test") String test, @ExtraParam("id") Object obj);
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/linhonghong/demo/dilutions/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.demo.dilutions;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 | import android.view.View;
7 |
8 | import com.linhonghong.dilutions.Dilutions;
9 | import com.linhonghong.dilutions.annotations.ActivityProtocol;
10 | import com.linhonghong.dilutions.annotations.ActivityProtocolExtra;
11 | import com.linhonghong.dilutions.annotations.CustomAnimation;
12 | import com.linhonghong.dilutions.utils.DilutionsUriBuilder;
13 |
14 | import java.lang.reflect.*;
15 | import java.util.HashMap;
16 |
17 | /**
18 | * 演示UI协议跳转
19 | * 表示该Activity支持"/test","/test2"这两个协议
20 | */
21 | @ActivityProtocol({"/test","/test2"})
22 | @CustomAnimation(enter = R.anim.enter, exit = R.anim.exit)
23 | public class MainActivity extends AppCompatActivity {
24 |
25 | /**
26 | * 读取test参数
27 | */
28 | @ActivityProtocolExtra("test")
29 | TestObj st;
30 |
31 | /**
32 | * 读取query参数
33 | */
34 | @ActivityProtocolExtra("query")
35 | int query;
36 |
37 | @ActivityProtocolExtra("groupID")
38 | int groupID;
39 |
40 | // String test = "dilutions:///test?params=e2dyb3VwSUQ6Mn0=";
41 | String test = "dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ==";
42 | //dilutions:///circles/group?params={groupID:0}
43 |
44 | @Override
45 | protected void onCreate(Bundle savedInstanceState) {
46 | super.onCreate(savedInstanceState);
47 | Dilutions.init(this);
48 | //Activity注册
49 | Dilutions.create().register(this);
50 |
51 | //直接使用st参数
52 | // Log.i("test",st);
53 | setContentView(R.layout.activity_main);
54 | findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
55 |
56 | @Override
57 | public void onClick(View view) {
58 | //跳转方法
59 | if(test.equals("dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ==")){
60 | test = "dilutions:///circles/group?params=e2dyb3VwSUQ6Mn0=";
61 | }else{
62 | test = "dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ==";
63 | }
64 | String s = DilutionsUriBuilder.buildUri("dilutions://", "/testmap","{ \"path\":\"bi_information\", \"tt\" : {\"action\":1,\"floor\":2}}");
65 | Dilutions.create().formatProtocolService(s);
66 | // formatProtocolService(Test.class).renderPage();
67 | // Dilutions.create().formatProtocolService(DebugService.class).renderPage();
68 | // Dilutions.create().formatProtocolService(test);
69 | }
70 | });
71 | findViewById(R.id.btn_test1).setOnClickListener(new View.OnClickListener() {
72 | @Override
73 | public void onClick(View view) {
74 | //协议跳转
75 | Bundle bundle = new Bundle();
76 | // bundle.putString("test",new TestObj());
77 | bundle.putString("name","linhonghong");
78 | HashMap extraMap = new HashMap<>();
79 | extraMap.put("mycallback", new View.OnClickListener() {
80 | @Override
81 | public void onClick(View v) {
82 | Log.d("testmethodobj", "回调完成");
83 | }
84 | });
85 | Log.d("testmethodobj", "协议开始");
86 | Dilutions.create().formatProtocolServiceWithMap("dilutions:///obj?params=eyJ0dCI6eyJ0IjoieHh4c3NzIiwieCI6MTIyM319", null, extraMap);
87 | // Dilutions.create().formatProtocolService("dilutions","test",bundle)
88 | // Dilutions.create().setDilutionsPathInterceptor("/test", new DilutionsPathInterceptor() {
89 | // @Override
90 | // public boolean interceptor(DilutionsData data) {
91 | // return false;
92 | // }
93 | // });
94 | HashMap map = new HashMap<>();
95 | map.put("query", 222);
96 | TestObj r = new TestObj();
97 | r.t = "tttt";
98 | map.put("test", r);
99 | Dilutions.create().formatProtocolService("dilutions:///test?params=e2dyb3VwSUQ6Mn0=", map, null);
100 | // Dilutions.create().formatProtocolService("dilutions:///finish");
101 | // String te = "dilutions:///doubles?params=eyJkb3VibGVzIjoyLjIyfQ==";
102 | // Dilutions.create().formatProtocolServiceWithCallback(te, new DilutionsCallBack() {
103 | // @Override
104 | // public void onDilutions(DilutionsData data) {
105 | // Log.i("res", data.getResult().toString());
106 | // }
107 | // });
108 | }
109 | });
110 |
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/java/com/linhonghong/demo/dilutions/Method.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.demo.dilutions;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 | import android.view.View;
6 |
7 | import com.linhonghong.dilutions.DilutionsValue;
8 | import com.linhonghong.dilutions.annotations.MethodExtra;
9 | import com.linhonghong.dilutions.annotations.MethodParam;
10 | import com.linhonghong.dilutions.annotations.MethodProtocol;
11 |
12 | import java.util.HashMap;
13 |
14 | /**
15 | * 演示方法协议调用
16 | * Created by Linhh on 2017/6/26.
17 | */
18 |
19 | public class Method {
20 |
21 | @MethodProtocol("/obj")
22 | public void obj(@MethodParam("tt") TestObj k, @MethodParam("mycallback") View.OnClickListener object){
23 | Log.d("testmethodobj", "obj is called:" + object);
24 | object.onClick(null);
25 | }
26 |
27 | @MethodProtocol("/testmap")
28 | public void obj(@MethodParam("tt") HashMap k){
29 | Log.d("testmethodobj", "obj is called.");
30 | }
31 |
32 | /**
33 | * 通过协议/finish可以直接跑到这里,无参的
34 | */
35 | @MethodProtocol("/finish")
36 | public void finish(){
37 | Log.d("finish","this Activity is finishing.");
38 | }
39 |
40 | @MethodProtocol("/doubles")
41 | public double dilutionsDouble(@MethodParam("doubles") double s){
42 | Log.d("dilutionsDouble","dilutionsDouble is call." + s);
43 | return 10.3;
44 | }
45 |
46 | /**
47 | * 通过"/circles/group"协议
48 | * @param l 读取协议的groupID参数
49 | * @param b
50 | * @param a
51 | * @param t 读取协议的test参数
52 | */
53 | @MethodProtocol("/circles/group")
54 | public void test1(@MethodParam("groupID") int l,
55 | Bundle b,
56 | int a,
57 | @MethodParam("test") String t){
58 | Log.i("dilutions_test","n:" + l + ",t:" + t);
59 | }
60 |
61 | /**
62 | * 通过协议twapro2
63 | * @param a
64 | */
65 | @MethodProtocol("twapro2")
66 | public void test1(int a){
67 | Log.d("test","test1 had called.");
68 | }
69 |
70 | /**
71 | * 通过协议twapro3
72 | * @param t 参数tree
73 | */
74 | @MethodProtocol("twapro3")
75 | public void test2(@MethodParam("tree") String t, @MethodExtra(DilutionsValue.DILUTIONS_METHOD_EXTRA) Object object){
76 | Log.d("test","twapro3 had called.");
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/com/linhonghong/demo/dilutions/Test.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.demo.dilutions;
2 |
3 | /**
4 | * Created by Linhh on 2017/7/19.
5 | */
6 |
7 | public interface Test {
8 | @TestAno("tst")
9 | void renderPage();
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/linhonghong/demo/dilutions/TestAno.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.demo.dilutions;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.METHOD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | @Documented
11 | @Target(METHOD)
12 | @Retention(RUNTIME)
13 | public @interface TestAno {
14 | String value() default "";
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/linhonghong/demo/dilutions/TestObj.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.demo.dilutions;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by Linhh on 2017/7/6.
7 | */
8 |
9 | public class TestObj implements Serializable{
10 | public String t = "sssfs";
11 | public int x = 2;
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DilutionsProject
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | mavenCentral()
7 |
8 | maven {
9 | url uri('./repo')
10 | }
11 | }
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:2.3.2'
14 | // //添加Dilutions插件
15 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
16 | classpath 'linhonghong.lib:dilutions-compiler:1.0.9'
17 | // NOTE: Do not place your application dependencies here; they belong
18 | // in the individual module build.gradle files
19 | }
20 | }
21 |
22 | allprojects {
23 | repositories {
24 | jcenter()
25 | }
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/dilutionsPlugin/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/dilutionsPlugin/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'groovy'
2 | apply plugin: 'maven'
3 | apply from: 'p.gradle'
4 |
5 | dependencies {
6 | compile gradleApi()
7 | compile localGroovy()
8 | compile 'com.android.tools.build:gradle:2.2.2'
9 | compile 'org.ow2.asm:asm:5.0.3'
10 | compile 'org.ow2.asm:asm-commons:5.0.3'
11 | }
12 |
13 | repositories {
14 | mavenCentral()
15 | }
16 |
17 | //发布到jcentr请参照:https://github.com/HomHomLin/GradlePublishing
18 |
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/gradle.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/dilutionsPlugin/gradle.properties
--------------------------------------------------------------------------------
/dilutionsPlugin/p.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.jfrog.bintray'
2 | apply plugin: 'maven-publish'
3 |
4 | group = GROUP_ID
5 | version = DEPLOY_VERSION
6 | project.archivesBaseName = POM_ARTIFACT_ID
7 |
8 | task sourcesJar(type: Jar) {
9 | from sourceSets.main.java.srcDirs
10 | classifier = 'sources'
11 | }
12 | //task javadoc(type: Javadoc) {
13 | // source = sourceSets.main.java.srcDirs
14 | // classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
15 | //}
16 | task javadocJar(type: Jar, dependsOn: javadoc) {
17 | classifier = 'javadoc'
18 | from javadoc.destinationDir
19 | }
20 | artifacts {
21 | archives javadocJar
22 | archives sourcesJar
23 | }
24 |
25 | def pomConfig = {
26 | licenses {
27 | license {
28 | name "The Apache Software License, Version 2.0"
29 | url "http://www.apache.org/licenses/LICENSE-2.0.txt"
30 | distribution "repo"
31 | }
32 | }
33 | developers {
34 | developer {
35 | id DEVELOPER_ID
36 | name DEVELOPER_NAME
37 | email DEVELOPER_EMAIL
38 | }
39 | }
40 |
41 | scm {
42 | url PROJ_WEBSITEURL
43 | }
44 | }
45 |
46 | javadoc {
47 | options{
48 | encoding "UTF-8"
49 | charSet 'UTF-8'
50 | author true
51 | version true
52 | links "http://docs.oracle.com/javase/7/docs/api"
53 | title POM_ARTIFACT_ID
54 | }
55 | }
56 |
57 | //afterEvaluate {
58 | // publishing.publications.mavenJava.artifact(packageReleaseJar)
59 | //}
60 | //afterEvaluate {
61 | // publishing.publications.aar.artifact(bundleRelease)
62 | // publishing.publications.jar.artifact(packageReleaseJar)
63 | //}
64 |
65 | publishing {
66 | publications {
67 | mavenJava(MavenPublication) {
68 | artifact javadocJar
69 | artifact sourcesJar
70 | groupId GROUP_ID
71 | artifactId POM_ARTIFACT_ID
72 | version DEPLOY_VERSION
73 | pom{
74 | packaging 'jar'
75 | }
76 | pom.withXml {
77 | def root = asNode()
78 | root.children().last() + pomConfig
79 | }
80 | }
81 | }
82 | }
83 |
84 | Properties properties = new Properties()
85 | InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream() ;
86 | properties.load( inputStream )
87 |
88 | def BINTRAY_U = properties.getProperty( 'BINTRAY_USER' )
89 | def BINTRAY_KEY = properties.getProperty( 'BINTRAY_KEY' ) ;
90 |
91 | bintray {
92 |
93 | user = BINTRAY_U
94 | key = BINTRAY_KEY
95 |
96 | configurations = ['archives']
97 | publications = ['mavenJava']
98 |
99 | dryRun = false
100 | publish = true
101 |
102 | pkg {
103 | repo = 'maven'
104 | name = POM_ARTIFACT_ID
105 | licenses = ['Apache-2.0']
106 | vcsUrl = PROJ_VCSURL
107 | websiteUrl = PROJ_WEBSITEURL
108 | issueTrackerUrl = PROJ_ISSUETRACKERURL
109 | publicDownloadNumbers = true
110 | version {
111 | name = DEPLOY_VERSION
112 | desc = PROJ_DESCRIPTION
113 | vcsTag = DEPLOY_VERSION
114 |
115 | gpg {
116 | sign = true
117 | }
118 | }
119 | }
120 | }
121 |
122 |
--------------------------------------------------------------------------------
/dilutionsPlugin/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/Linhh/Develop/Android/android-sdk-macosx/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/groovy/com.linhonghong.dilutions.plugin/PluginImpl.groovy:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.plugin
2 |
3 | import com.android.build.api.transform.*
4 | import com.android.build.gradle.AppExtension
5 | import com.android.build.gradle.internal.pipeline.TransformManager
6 | import com.linhonghong.dilutions.BlackhandClassVisitor
7 | import com.linhonghong.dilutions.BlackhandMethodInfo
8 | import com.linhonghong.dilutions.DilutionsMetasWriter
9 | import com.linhonghong.dilutions.MethodAnnotationsInfo
10 | import org.apache.commons.codec.digest.DigestUtils
11 | import org.apache.commons.io.FileUtils
12 | import org.apache.commons.io.IOUtils
13 | import org.gradle.api.Plugin
14 | import org.gradle.api.Project
15 | import org.objectweb.asm.ClassReader
16 | import org.objectweb.asm.ClassWriter
17 | import org.objectweb.asm.Opcodes
18 | import org.objectweb.asm.tree.AnnotationNode
19 |
20 | import java.util.jar.JarEntry
21 | import java.util.jar.JarFile
22 | import java.util.jar.JarOutputStream
23 | import java.util.zip.ZipEntry
24 |
25 | import static org.objectweb.asm.ClassReader.EXPAND_FRAMES
26 |
27 | /**
28 | * Created by Linhh on 17/5/31.
29 | */
30 |
31 | public class PluginImpl extends Transform implements Plugin ,Opcodes{
32 | //Method metas
33 | private HashMap> mMetas = new HashMap<>();
34 |
35 | //UI metas
36 | private HashMap> mUIMetas = new HashMap<>();
37 |
38 |
39 | void apply(Project project) {
40 | def android = project.extensions.getByType(AppExtension);
41 | android.registerTransform(this)
42 | }
43 |
44 |
45 | @Override
46 | public String getName() {
47 | return "Dilutions-plugin";
48 | }
49 |
50 | @Override
51 | public Set getInputTypes() {
52 | return TransformManager.CONTENT_CLASS;
53 | }
54 |
55 | @Override
56 | public Set getScopes() {
57 | // return TransformManager.SCOPE_FULL_PROJECT;
58 | // QualifiedContent.Scope.PROJECT,
59 | // QualifiedContent.Scope.PROJECT_LOCAL_DEPS,
60 | // QualifiedContent.Scope.SUB_PROJECTS,
61 | // QualifiedContent.Scope.SUB_PROJECTS_LOCAL_DEPS,
62 | // QualifiedContent.Scope.EXTERNAL_LIBRARIES
63 | return TransformManager.SCOPE_FULL_PROJECT
64 | }
65 |
66 |
67 |
68 | @Override
69 | public boolean isIncremental() {
70 | return false;
71 | }
72 |
73 | @Override
74 | void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
75 | super.transform(transformInvocation)
76 | }
77 |
78 | void processMetas( BlackhandClassVisitor cv){
79 | if(cv.mActivityProtocolNode != null){
80 | //UI跳转
81 | if(cv.mActivityProtocolNode.values != null
82 | && cv.mActivityProtocolNode.values.size() > 1){
83 | String protocol_name = cv.mActivityProtocolNode.values.get(1);
84 | protocol_name = protocol_name.substring(1, protocol_name.length() - 1)
85 | if(!protocol_name.empty){
86 | //动画添加
87 | String enterAnim = "0";
88 | String exitAnim = "0";
89 | if(cv.mAnimActivityProtocolNode != null && cv.mAnimActivityProtocolNode.values != null
90 | && cv.mAnimActivityProtocolNode.values.size() > 1){
91 | try{
92 | //进入动画设置
93 | enterAnim = cv.mAnimActivityProtocolNode.values.get(1);
94 | }catch (Exception e){
95 |
96 | }
97 |
98 | try{
99 | //进入动画设置
100 | exitAnim = cv.mAnimActivityProtocolNode.values.get(3);
101 | }catch (Exception e){
102 |
103 | }
104 |
105 | println "找到针对"+protocol_name+"的UI动画Enter:" + enterAnim+ ",exit:"+exitAnim
106 | }
107 | String[] protocols = protocol_name.split(",")
108 | for(String s : protocols){
109 | ArrayList strings = new ArrayList<>();
110 | //添加对应的跳转类index=0
111 | strings.add(cv.mClazzName)
112 | //添加对应的enter动画index=1
113 | strings.add(enterAnim)
114 | //添加对应的exit动画index = 2
115 | strings.add(exitAnim)
116 | //将序列放入metas
117 | mUIMetas.put(s.trim(), strings)
118 | }
119 | }
120 |
121 | println "找到UI协议:" + protocol_name
122 | }
123 | // mUIMetas.put()
124 | }
125 | if(cv.mProtocols != null){
126 | //类名
127 | String clazz = cv.mClazzName;
128 | println clazz
129 | for (Map.Entry entry : cv.mProtocols.entrySet()) {
130 | //协议
131 | String protocol_name = "";
132 | if(entry.key.values != null && entry.key.values.size() > 1){
133 | protocol_name = entry.key.values.get(1);
134 | println "找到协议:" + protocol_name
135 | }else{
136 | println "没有找到协议,这有问题!"
137 | continue
138 | }
139 | ArrayList strings = new ArrayList<>();
140 | strings.add(clazz)
141 | //方法名
142 | String medhodname = entry.value.getMethodName()
143 | println medhodname;
144 | strings.add(medhodname)
145 | //方法参数类型
146 | String javaMethodParams = entry.value.getJavaMethodParams()
147 | println javaMethodParams
148 | strings.add(javaMethodParams)
149 | //参数以及其index
150 | for(MethodAnnotationsInfo info : entry.value.mMethodAnnotations){
151 | strings.add(info.getIndex() + "=" + info.getParamName())
152 | println info.getIndex() + "=" + info.getParamName()
153 | }
154 | mMetas.put(protocol_name, strings)
155 | }
156 | }
157 | }
158 |
159 | @Override
160 | void transform(Context context, Collection inputs, Collection referencedInputs,
161 | TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
162 | println '==================Dilutions transform start=================='
163 | //删除之前的输出
164 | if(outputProvider!=null)
165 | outputProvider.deleteAll()
166 | //遍历inputs里的TransformInput
167 | inputs.each { TransformInput input ->
168 | //遍历input里边的DirectoryInput
169 | input.directoryInputs.each {
170 | DirectoryInput directoryInput ->
171 | //是否是目录
172 | if (directoryInput.file.isDirectory()) {
173 | //遍历目录
174 | directoryInput.file.eachFileRecurse {
175 | File file ->
176 | def filename = file.name;
177 | def name = file.name
178 | //这里进行我们的处理 TODO
179 | if (name.endsWith(".class")) {
180 | //类处理
181 | ClassReader classReader = new ClassReader(file.bytes)
182 | ClassWriter classWriter = new ClassWriter(classReader,ClassWriter.COMPUTE_MAXS)
183 | BlackhandClassVisitor cv = new BlackhandClassVisitor(Opcodes.ASM5,classWriter)
184 | classReader.accept(cv, EXPAND_FRAMES)
185 |
186 | //处理类数据
187 | // println cv.mClazzName + ";" + cv.mSuperName
188 | processMetas(cv)
189 | // processMetas(cv, classWriter);
190 | //写入
191 | byte[] code = classWriter.toByteArray()
192 | FileOutputStream fos = new FileOutputStream(
193 | file.parentFile.absolutePath + File.separator + name)
194 | fos.write(code)
195 | fos.close()
196 | // println 'Dilutions-----> inject file:' + file.getAbsolutePath()
197 | }
198 | // println 'Dilutions-----> find file:' + file.getAbsolutePath()
199 | //project.logger.
200 | }
201 | }
202 | //处理完输入文件之后,要把输出给下一个任务
203 | def dest = outputProvider.getContentLocation(directoryInput.name,
204 | directoryInput.contentTypes, directoryInput.scopes,
205 | Format.DIRECTORY)
206 | FileUtils.copyDirectory(directoryInput.file, dest)
207 | }
208 |
209 |
210 | input.jarInputs.each { JarInput jarInput ->
211 | /**
212 | * 重名名输出文件,因为可能同名,会覆盖
213 | */
214 | def jarName = jarInput.name
215 | println "Dilutions jarName:" + jarName + "; "+ jarInput.file.absolutePath
216 | def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath())
217 | if (jarName.endsWith(".jar")) {
218 |
219 | jarName = jarName.substring(0, jarName.length() - 4)
220 | }
221 |
222 | File tmpFile = null;
223 | if (jarInput.file.getAbsolutePath().endsWith(".jar")) {
224 | JarFile jarFile = new JarFile(jarInput.file);
225 | Enumeration enumeration = jarFile.entries();
226 | tmpFile = new File(jarInput.file.getParent() + File.separator + "classes_anna.jar");
227 | //避免上次的缓存被重复插入
228 | if(tmpFile.exists()) {
229 | tmpFile.delete();
230 | }
231 | JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(tmpFile));
232 | //用于保存
233 | ArrayList processorList = new ArrayList<>();
234 | while (enumeration.hasMoreElements()) {
235 | JarEntry jarEntry = (JarEntry) enumeration.nextElement();
236 | String entryName = jarEntry.getName();
237 | ZipEntry zipEntry = new ZipEntry(entryName);
238 |
239 | InputStream inputStream = jarFile.getInputStream(jarEntry);
240 | //如果是inject文件就跳过
241 | //anna插桩class
242 | if (entryName.endsWith(".class")) {
243 | //class文件处理
244 | // println "entryName anna:" + entryName
245 | jarOutputStream.putNextEntry(zipEntry);
246 | ClassReader classReader = new ClassReader(IOUtils.toByteArray(inputStream))
247 | ClassWriter classWriter = new ClassWriter(classReader,ClassWriter.COMPUTE_MAXS)
248 | BlackhandClassVisitor cv = new BlackhandClassVisitor(Opcodes.ASM5,classWriter)
249 | classReader.accept(cv, EXPAND_FRAMES)
250 | //处理类数据
251 | processMetas(cv)
252 | // processMetas(cv, classWriter);
253 |
254 | byte[] code = classWriter.toByteArray()
255 | jarOutputStream.write(code);
256 | } else if(entryName.contains("META-INF/services/javax.annotation.processing.Processor")){
257 | if(!processorList.contains(entryName)){
258 | // println "entryName no anna:" + entryName
259 | processorList.add(entryName)
260 | jarOutputStream.putNextEntry(zipEntry);
261 | jarOutputStream.write(IOUtils.toByteArray(inputStream));
262 | }else{
263 | println "duplicate entry:" + entryName
264 | }
265 | }else {
266 | // println "entryName no anna:" + entryName
267 | jarOutputStream.putNextEntry(zipEntry);
268 | jarOutputStream.write(IOUtils.toByteArray(inputStream));
269 | }
270 | jarOutputStream.closeEntry();
271 | }
272 | //结束
273 | jarOutputStream.close();
274 | jarFile.close();
275 | // jarInput.file.delete();
276 | // tmpFile.renameTo(jarInput.file);
277 | }
278 | // println 'Assassin-----> find Jar:' + jarInput.getFile().getAbsolutePath()
279 |
280 | //处理jar进行字节码注入处理 TODO
281 |
282 | def dest = outputProvider.getContentLocation(jarName + md5Name,
283 | jarInput.contentTypes, jarInput.scopes, Format.JAR)
284 | // println 'Blackhand-----> copy to Jar:' + dest.absolutePath
285 | if(tmpFile == null) {
286 | FileUtils.copyFile(jarInput.file, dest)
287 | }else{
288 | FileUtils.copyFile(tmpFile, dest)
289 | tmpFile.delete()
290 | }
291 | }
292 | }
293 |
294 | //创建meta数据
295 | File meta_file = outputProvider.getContentLocation("dilutions_inject_metas", getOutputTypes(), getScopes(),
296 | Format.JAR);
297 | if(!meta_file.getParentFile().exists()){
298 | meta_file.getParentFile().mkdirs();
299 | }
300 | if(meta_file.exists()){
301 | meta_file.delete();
302 | }
303 | DilutionsMetasWriter metasWriter = new DilutionsMetasWriter();
304 |
305 | // JarFile jarFile = new JarFile(meta_file);
306 | JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(meta_file));
307 | ZipEntry addEntry = null;
308 |
309 | addEntry = new ZipEntry("com/linhonghong/dilutions/inject/support/DilutionsInjectMetas.class");
310 | jarOutputStream.putNextEntry(addEntry);
311 | jarOutputStream.write(metasWriter.makeMetas("com/linhonghong/dilutions/inject/support/DilutionsInjectMetas",mMetas));
312 | jarOutputStream.closeEntry();
313 |
314 | addEntry = new ZipEntry("com/linhonghong/dilutions/inject/support/DilutionsInjectUIMetas.class");
315 | jarOutputStream.putNextEntry(addEntry);
316 | jarOutputStream.write(metasWriter.makeMetas("com/linhonghong/dilutions/inject/support/DilutionsInjectUIMetas",mUIMetas));
317 | jarOutputStream.closeEntry();
318 | //结束
319 | jarOutputStream.close();
320 | // jarFile.close();
321 |
322 | println '==================Dilutions transform end=================='
323 |
324 | }
325 | }
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/BlackhandClassVisitor.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions;
2 |
3 |
4 | import com.linhonghong.dilutions.annotations.ActivityProtocol;
5 | import com.linhonghong.dilutions.annotations.CustomAnimation;
6 | import com.linhonghong.dilutions.annotations.MethodExtra;
7 | import com.linhonghong.dilutions.annotations.MethodParam;
8 | import com.linhonghong.dilutions.annotations.MethodProtocol;
9 |
10 | import org.objectweb.asm.AnnotationVisitor;
11 | import org.objectweb.asm.ClassVisitor;
12 | import org.objectweb.asm.FieldVisitor;
13 | import org.objectweb.asm.MethodVisitor;
14 | import org.objectweb.asm.Opcodes;
15 | import org.objectweb.asm.Type;
16 | import org.objectweb.asm.commons.AdviceAdapter;
17 | import org.objectweb.asm.tree.AnnotationNode;
18 |
19 | import java.util.ArrayList;
20 | import java.util.HashMap;
21 | import java.util.List;
22 |
23 | /**
24 | * Created by Linhh on 17/6/8.
25 | */
26 |
27 | public class BlackhandClassVisitor extends ClassVisitor {
28 |
29 | public String mSuperName;
30 | public String mClazzName;
31 | public String[] mInterfaces;
32 | public ArrayList mMethods;
33 | public int mVersion;
34 | public int mAccess;
35 | public String mSignature;
36 | public String mName;
37 | public HashMap mProtocols;
38 | public AnnotationNode mActivityProtocolNode;
39 | public AnnotationNode mAnimActivityProtocolNode;
40 |
41 |
42 | public BlackhandClassVisitor(int api, ClassVisitor cv) {
43 | super(api, cv);
44 | }
45 |
46 | @Override
47 | public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
48 | super.visit(version, access, name, signature, superName, interfaces);
49 | mClazzName = name.replace("/",".");
50 | mName = name;
51 | mSuperName = superName.replace("/",".");
52 | mInterfaces = interfaces;
53 | mVersion = version;
54 | mAccess = access;
55 | mSignature = signature;
56 | }
57 |
58 | @Override
59 | public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
60 | return super.visitField(access, name, desc, signature, value);
61 | }
62 |
63 | @Override
64 | public org.objectweb.asm.AnnotationVisitor visitAnnotation(String desc, boolean visible) {
65 | if (Type.getDescriptor(ActivityProtocol.class).equals(desc)) {
66 | //协议
67 | mActivityProtocolNode = new AnnotationNode(desc);
68 | return mActivityProtocolNode;
69 | }else if(Type.getDescriptor(CustomAnimation.class).equals(desc)){
70 | mAnimActivityProtocolNode = new AnnotationNode(desc);
71 | return mAnimActivityProtocolNode;
72 | }
73 | return super.visitAnnotation(desc, visible);
74 | }
75 |
76 | @Override
77 | public void visitEnd() {
78 | super.visitEnd();
79 | }
80 |
81 | @Override
82 | public MethodVisitor visitMethod(int access, String name, String desc, String signature,
83 | String[] exceptions) {
84 | MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, signature, exceptions);
85 | methodVisitor = new AdviceAdapter(Opcodes.ASM5, methodVisitor, access, name, desc) {
86 |
87 |
88 | public BlackhandMethodInfo methodInfo = new BlackhandMethodInfo();
89 | public String mProtocolName;
90 | public AnnotationNode mProtocolNode;
91 |
92 | @Override
93 | public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
94 | AnnotationNode an = new AnnotationNode(desc);
95 | if (Type.getDescriptor(MethodProtocol.class).equals(desc)) {
96 | mProtocolNode = an;
97 | return an;
98 | }
99 | return super.visitAnnotation(desc, visible);
100 | }
101 |
102 | @Override
103 | public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
104 | AnnotationNode an = new AnnotationNode(desc);
105 | if (Type.getDescriptor(MethodParam.class).equals(desc)
106 | || Type.getDescriptor(MethodExtra.class).equals(desc)) {
107 | MethodAnnotationsInfo methodAnnotationsInfo = new MethodAnnotationsInfo(parameter, desc, visible, an);
108 | methodInfo.mMethodAnnotations.add(methodAnnotationsInfo);
109 | return an;
110 | }
111 | return super.visitParameterAnnotation(parameter, desc, visible);
112 |
113 | }
114 |
115 | @Override
116 | public void visitEnd() {
117 | super.visitEnd();
118 | if(mMethods == null){
119 | mMethods = new ArrayList<>();
120 | }
121 | mMethods.add(methodInfo);
122 | if(mProtocolNode != null){
123 | // mProtocolName = (String)mProtocolNode.values.get(1);
124 | if(mProtocols == null){
125 | mProtocols = new HashMap<>();
126 | }
127 | mProtocols.put(mProtocolNode, methodInfo);
128 | }
129 | }
130 |
131 | @Override
132 | public void visitCode() {
133 | super.visitCode();
134 |
135 | List paramsTypeClass = new ArrayList();
136 | Type[] argsType = Type.getArgumentTypes(desc);
137 | for (Type type : argsType) {
138 | paramsTypeClass.add(type);
139 | }
140 | methodInfo.mMethodName = name;
141 | methodInfo.mMethodParms = paramsTypeClass;
142 | methodInfo.mDesc = desc;
143 |
144 | }
145 | };
146 | return methodVisitor;
147 |
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/BlackhandMethodInfo.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import org.objectweb.asm.Type;
6 |
7 | /**
8 | * Created by Linhh on 17/6/15.
9 | */
10 |
11 | public class BlackhandMethodInfo {
12 | public ArrayList mMethodAnnotations = new ArrayList<>();
13 | public String mMethodName;
14 | public List mMethodParms;
15 | public String mDesc;
16 | public BlackhandMethodInfo(){
17 |
18 | }
19 | public BlackhandMethodInfo(String methodName ,List methodParms,String desc){
20 | mMethodName = methodName;
21 | mMethodParms = methodParms;
22 | mDesc = desc;
23 | }
24 |
25 | public String getDesc(){
26 | return mDesc;
27 | }
28 |
29 | public String getMethodName(){
30 | return mMethodName;
31 | }
32 |
33 | public String getJavaMethodParams(){
34 | String result = "";
35 | for(int i = 0; i < mMethodParms.size(); i ++){
36 | result = result + mMethodParms.get(i).getClassName();
37 |
38 | // result = result + DilutionsUtils.getType(mMethodParms.get(i).toString());
39 | if(i != (mMethodParms.size() - 1)){
40 | //最后一个
41 | result = result + "#";
42 | }
43 | }
44 | return result;
45 | }
46 |
47 | public String getMethodParms(){
48 | String stype = "(";
49 | for(Type type : mMethodParms){
50 | stype = stype + type.toString();
51 | }
52 | stype = stype + ")";
53 | return stype;
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | String stype = "";
59 | for(Type type : mMethodParms){
60 | stype = stype + type.toString() + "---";
61 | }
62 | for(MethodAnnotationsInfo type : mMethodAnnotations){
63 | stype = stype + type.toString() + "---";
64 | }
65 | return mMethodName + ":" + stype + "[:]" + mDesc;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/DilutionsMetasWriter.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions;
2 |
3 | import org.objectweb.asm.ClassWriter;
4 | import org.objectweb.asm.FieldVisitor;
5 | import org.objectweb.asm.MethodVisitor;
6 | import org.objectweb.asm.Opcodes;
7 |
8 | import java.util.ArrayList;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | /**
13 | * Created by Linhh on 17/6/23.
14 | */
15 |
16 | public class DilutionsMetasWriter implements Opcodes{
17 | public byte[] makeMetas(String pkg, HashMap> metas){
18 | ClassWriter cw = new ClassWriter(0);
19 | FieldVisitor fv;
20 | MethodVisitor mv;
21 |
22 | cw.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, pkg, null, "java/lang/Object", null);
23 |
24 |
25 | fv = cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "map", "Ljava/util/HashMap;", "Ljava/util/HashMap;>;", null);
26 | fv.visitEnd();
27 |
28 |
29 | mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null);
30 | mv.visitCode();
31 | mv.visitVarInsn(Opcodes.ALOAD, 0);
32 | mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false);
33 | mv.visitInsn(Opcodes.RETURN);
34 | mv.visitMaxs(1, 1);
35 | mv.visitEnd();
36 |
37 |
38 | mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getMap", "()Ljava/util/HashMap;", "()Ljava/util/HashMap;>;", null);
39 | mv.visitCode();
40 | mv.visitFieldInsn(Opcodes.GETSTATIC, pkg, "map", "Ljava/util/HashMap;");
41 | mv.visitInsn(Opcodes.ARETURN);
42 | mv.visitMaxs(1, 1);
43 | mv.visitEnd();
44 |
45 | mv = cw.visitMethod(Opcodes.ACC_STATIC, "", "()V", null, null);
46 | mv.visitCode();
47 | mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
48 | mv.visitInsn(Opcodes.DUP);
49 | mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "", "()V", false);
50 | mv.visitFieldInsn(Opcodes.PUTSTATIC, pkg, "map", "Ljava/util/HashMap;");
51 |
52 |
53 | for(Map.Entry> entrySet: metas.entrySet()){
54 | String key = entrySet.getKey();
55 | ArrayList v = entrySet.getValue();
56 | //创建一个list
57 | mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
58 | mv.visitInsn(Opcodes.DUP);
59 | mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "", "()V", false);
60 | mv.visitVarInsn(Opcodes.ASTORE, 0);
61 | for(String s : v){
62 | mv.visitVarInsn(Opcodes.ALOAD, 0);
63 | mv.visitLdcInsn(s);
64 | mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "add", "(Ljava/lang/Object;)Z", false);
65 | mv.visitInsn(Opcodes.POP);
66 | }
67 | mv.visitFieldInsn(Opcodes.GETSTATIC, pkg, "map", "Ljava/util/HashMap;");
68 | mv.visitLdcInsn(key);
69 | mv.visitVarInsn(Opcodes.ALOAD, 0);
70 | mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", false);
71 | mv.visitInsn(Opcodes.POP);
72 | }
73 |
74 |
75 | mv.visitInsn(Opcodes.RETURN);
76 | mv.visitMaxs(3, 1);
77 | mv.visitEnd();
78 |
79 | cw.visitEnd();
80 |
81 | return cw.toByteArray();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/DilutionsUtils.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions;
2 |
3 | /**
4 | * Created by Linhh on 2017/6/26.
5 | */
6 |
7 | public class DilutionsUtils {
8 | public static final String DILUTIONS_METHOD_EXTRA = "dilutions_method_params_extra";
9 | public static String getType(String typeS){
10 | if("Z".equals(typeS)){
11 | return "Boolean";
12 | }
13 | if("B".equals(typeS)){
14 | return "Boolean";
15 | }
16 | if("C".equals(typeS)){
17 | return "Char";
18 | }
19 | if("S".equals(typeS)){
20 | return "Short";
21 | }
22 | if("I".equals(typeS)){
23 | return "Integer";
24 | }
25 | if("F".equals(typeS)){
26 | return "Float";
27 | }
28 | if("D".equals(typeS)){
29 | return "Double";
30 | }
31 | if("J".equals(typeS)){
32 | return "Long";
33 | }
34 |
35 | if("Ljava/lang/String".equals(typeS)){
36 | return "String";
37 | }
38 | return "Object";
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/MethodAnnotationsInfo.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions;
2 |
3 | import org.objectweb.asm.tree.AnnotationNode;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * Created by Linhh on 17/6/22.
10 | */
11 |
12 | public class MethodAnnotationsInfo {
13 | public int mParameter;
14 | public String mDesc;
15 | public boolean mVisible;
16 | public AnnotationNode mNode;
17 | public MethodAnnotationsInfo(int parameter, String desc, boolean visible, AnnotationNode node){
18 | mParameter = parameter;
19 | mDesc = desc;
20 | mVisible = visible;
21 | mNode = node;
22 | }
23 |
24 | public int getIndex(){
25 | return mParameter;
26 | }
27 |
28 | public String getParamName(){
29 | List vl = mNode.values;
30 | if (vl != null) {
31 | //vl.get(0).toString() 属性名字
32 | return (String)vl.get(1);
33 | }
34 | return "";
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | List vl = mNode.values;
40 | String node = "";
41 | if (vl != null) {
42 | //vl.get(0).toString() 属性名字
43 | node = vl.get(0).toString() + "=" + vl.get(1) + ";" + node;
44 | }
45 | return mParameter + ";" + node;
46 | // return mParameter + ";" + mDesc + ";" + mVisible + ";" + node;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/ActivityExtra.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.FIELD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/9/2.
12 | */
13 | @Documented
14 | @Target(FIELD)
15 | @Retention(RUNTIME)
16 | public @interface ActivityExtra {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/ActivityProtocol.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.Target;
7 |
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/12/1.
12 | */
13 | @Documented
14 | @Retention(RUNTIME)
15 | @Target(ElementType.TYPE)
16 | public @interface ActivityProtocol {
17 | String[] value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/ActivityProtocolExtra.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.FIELD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/11/30.
12 | */
13 | @Documented
14 | @Target(FIELD)
15 | @Retention(RUNTIME)
16 | public @interface ActivityProtocolExtra {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/ActivityProtocolPath.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.FIELD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/11/30.
12 | */
13 | @Documented
14 | @Target(FIELD)
15 | @Retention(RUNTIME)
16 | public @interface ActivityProtocolPath {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/CustomAnimation.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.Target;
7 |
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/12/1.
12 | */
13 | @Documented
14 | @Retention(RUNTIME)
15 | @Target(ElementType.TYPE)
16 | public @interface CustomAnimation {
17 | int enter() default 0;
18 | int exit() default 0;
19 | }
20 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/ExtraParam.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.PARAMETER;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/11/29.
12 | */
13 | @Documented
14 | @Target(PARAMETER)
15 | @Retention(RUNTIME)
16 | public @interface ExtraParam {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/FragmentArg.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.FIELD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/9/2.
12 | */
13 | @Documented
14 | @Target(FIELD)
15 | @Retention(RUNTIME)
16 | public @interface FragmentArg {
17 | String value() default "";
18 | }
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/MethodExtra.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import com.linhonghong.dilutions.DilutionsUtils;
4 |
5 | import java.lang.annotation.Documented;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.Target;
8 |
9 | import static java.lang.annotation.ElementType.PARAMETER;
10 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
11 |
12 | /**
13 | * Created by Linhh on 09/02/2018.
14 | */
15 | @Documented
16 | @Target(PARAMETER)
17 | @Retention(RUNTIME)
18 | public @interface MethodExtra {
19 | String value() default DilutionsUtils.DILUTIONS_METHOD_EXTRA;
20 | }
21 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/MethodParam.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.PARAMETER;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 2017/7/19.
12 | */
13 | @Documented
14 | @Target(PARAMETER)
15 | @Retention(RUNTIME)
16 | public @interface MethodParam {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/MethodProtocol.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.METHOD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 17/6/22.
12 | */
13 |
14 | @Documented
15 | @Target(METHOD)
16 | @Retention(RUNTIME)
17 | public @interface MethodProtocol {
18 | String value() default "";
19 | }
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/Param.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.PARAMETER;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 17/6/22.
12 | */
13 |
14 | @Documented
15 | @Target(PARAMETER)
16 | @Retention(RUNTIME)
17 | public @interface Param {
18 | String value() default "";
19 | }
20 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/PassNull.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.PARAMETER;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/11/30.
12 | */
13 | @Documented
14 | @Target(PARAMETER)
15 | @Retention(RUNTIME)
16 | public @interface PassNull {
17 | }
18 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/ProtocolFrom.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.FIELD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/12/23.
12 | */
13 | @Documented
14 | @Target(FIELD)
15 | @Retention(RUNTIME)
16 | public @interface ProtocolFrom {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/java/com/linhonghong/dilutions/annotations/ProtocolPath.java:
--------------------------------------------------------------------------------
1 | package com.linhonghong.dilutions.annotations;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.METHOD;
8 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
9 |
10 | /**
11 | * Created by Linhh on 16/11/29.
12 | */
13 | @Documented
14 | @Target(METHOD)
15 | @Retention(RUNTIME)
16 | public @interface ProtocolPath {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/dilutionsPlugin/src/main/resources/META-INF/gradle-plugins/dilutions.properties:
--------------------------------------------------------------------------------
1 | implementation-class=com.linhonghong.dilutions.plugin.PluginImpl
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | GROUP_ID=linhonghong.lib
2 | #POM_ARTIFACT_ID=dilutions-compiler
3 | POM_ARTIFACT_ID=dilutions
4 | DEPLOY_VERSION=1.0.9
5 | PROJ_VCSURL=https://github.com/HomHomLin/Dilutions.git
6 | PROJ_WEBSITEURL=https://github.com/HomHomLin/Dilutions
7 | PROJ_ISSUETRACKERURL=
8 | PROJ_DESCRIPTION=/Dilutions
9 |
10 | DEVELOPER_ID=homhomlin
11 | DEVELOPER_NAME=linhonghong
12 | DEVELOPER_EMAIL=linhh90@163.com
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jan 22 10:48:24 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/pic.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':Dilutions', ':dilutionsPlugin'
2 |
--------------------------------------------------------------------------------