Skip to content

Commit 53882da

Browse files
committed
Android:APIJSONTest 自动化单元测试解决扫描不到类,新增显示和复制 IPV4 地址,优化复制及其它体验
1 parent a5d604e commit 53882da

File tree

7 files changed

+327
-66
lines changed

7 files changed

+327
-66
lines changed

APIJSON-Android/APIJSONTest/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
android:minSdkVersion="15"
99
android:targetSdkVersion="21" />
1010

11+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
1112
<uses-permission android:name="android.permission.INTERNET" />
1213
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
1314
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package apijson.demo;
2+
3+
import android.content.Context;
4+
import android.net.wifi.WifiInfo;
5+
import android.net.wifi.WifiManager;
6+
7+
import java.net.InetAddress;
8+
import java.net.NetworkInterface;
9+
import java.net.SocketException;
10+
import java.util.Enumeration;
11+
12+
/**
13+
* =======================================================
14+
* 版权:Copyright LiYing 2015-2016. All rights reserved.
15+
* 作者:liying - [email protected]
16+
* 日期:2016/12/19 19:43
17+
* 版本:1.0
18+
* 描述:IP地址工具类
19+
* 备注:
20+
* =======================================================
21+
*/
22+
public class IPUtil {
23+
24+
/**
25+
* 获取本机IPv4地址
26+
*
27+
* @param context
28+
* @return 本机IPv4地址;null:无网络连接
29+
*/
30+
public static String getIpAddress(Context context) {
31+
// 获取WiFi服务
32+
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
33+
// 判断WiFi是否开启
34+
if (wifiManager.isWifiEnabled()) {
35+
// 已经开启了WiFi
36+
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
37+
int ipAddress = wifiInfo.getIpAddress();
38+
String ip = intToIp(ipAddress);
39+
return ip;
40+
} else {
41+
// 未开启WiFi
42+
return getIpAddress();
43+
}
44+
}
45+
46+
private static String intToIp(int ipAddress) {
47+
return (ipAddress & 0xFF) + "." +
48+
((ipAddress >> 8) & 0xFF) + "." +
49+
((ipAddress >> 16) & 0xFF) + "." +
50+
(ipAddress >> 24 & 0xFF);
51+
}
52+
53+
/**
54+
* 获取本机IPv4地址
55+
*
56+
* @return 本机IPv4地址;null:无网络连接
57+
*/
58+
private static String getIpAddress() {
59+
try {
60+
NetworkInterface networkInterface;
61+
InetAddress inetAddress;
62+
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
63+
networkInterface = en.nextElement();
64+
for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
65+
inetAddress = enumIpAddr.nextElement();
66+
if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress()) {
67+
return inetAddress.getHostAddress();
68+
}
69+
}
70+
}
71+
return null;
72+
} catch (SocketException ex) {
73+
ex.printStackTrace();
74+
return null;
75+
}
76+
}
77+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package apijson.demo;
2+
3+
import com.alibaba.fastjson.JSONObject;
4+
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.util.ArrayList;
8+
import java.util.Enumeration;
9+
import java.util.List;
10+
11+
import apijson.demo.application.DemoApplication;
12+
import dalvik.system.DexFile;
13+
14+
public class MethodUtil extends apijson.demo.server.MethodUtil {
15+
16+
static {
17+
CLASS_LOADER_CALLBACK = new ClassLoaderCallback() {
18+
19+
@Override
20+
public Class<?> loadClass(String className) {
21+
return null;
22+
}
23+
24+
@Override
25+
public List<Class<?>> loadClassList(String packageOrFileName, String className, boolean ignoreError) throws ClassNotFoundException, IOException {
26+
List<Class<?>> list = new ArrayList<Class<?>>();
27+
int index = className.indexOf("<");
28+
if (index >= 0) {
29+
className = className.substring(0, index);
30+
}
31+
32+
boolean allPackage = isEmpty(packageOrFileName, true);
33+
boolean allName = isEmpty(className, true);
34+
35+
//将包名替换成目录 TODO 应该一层层查找进去,实时判断是 package 还是 class,如果已经是 class 还有下一级,应该用 $ 隔开内部类。简单点也可以认为大驼峰是类
36+
String fileName = allPackage ? "" : separator2dot(packageOrFileName);
37+
38+
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
39+
40+
DexFile dex = new DexFile(DemoApplication.getInstance().getPackageResourcePath());
41+
Enumeration<String> entries = dex.entries();
42+
while (entries.hasMoreElements()) {
43+
String entryName = entries.nextElement();
44+
if (allPackage || entryName.startsWith(fileName)) {
45+
Class<?> entryClass = Class.forName(entryName, true, classLoader);
46+
47+
if (allName || className.equals(entryClass.getSimpleName())) {
48+
list.add(entryClass);
49+
}
50+
}
51+
}
52+
53+
return list;
54+
}
55+
};
56+
}
57+
58+
public static JSONObject listMethod(String request) {
59+
if (CLASS_LOADER_CALLBACK == null) {
60+
CLASS_LOADER_CALLBACK = new ClassLoaderCallback() {
61+
62+
@Override
63+
public Class<?> loadClass(String className) {
64+
return null;
65+
}
66+
67+
@Override
68+
public List<Class<?>> loadClassList(String packageOrFileName, String className, boolean ignoreError) throws ClassNotFoundException, IOException {
69+
List<Class<?>> list = new ArrayList<Class<?>>();
70+
int index = className.indexOf("<");
71+
if (index >= 0) {
72+
className = className.substring(0, index);
73+
}
74+
75+
boolean allPackage = isEmpty(packageOrFileName, true);
76+
boolean allName = isEmpty(className, true);
77+
78+
//将包名替换成目录 TODO 应该一层层查找进去,实时判断是 package 还是 class,如果已经是 class 还有下一级,应该用 $ 隔开内部类。简单点也可以认为大驼峰是类
79+
String fileName = allPackage ? File.separator : dot2Separator(packageOrFileName);
80+
81+
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
82+
83+
DexFile dex = new DexFile(DemoApplication.getInstance().getPackageResourcePath());
84+
Enumeration<String> entries = dex.entries();
85+
while (entries.hasMoreElements()) {
86+
String entryName = entries.nextElement();
87+
if (allPackage || entryName.startsWith(fileName)) {
88+
Class<?> entryClass = Class.forName(entryName, true, classLoader);
89+
90+
if (allName || className.equals(entryClass.getSimpleName())) {
91+
list.add(entryClass);
92+
}
93+
}
94+
}
95+
96+
return list;
97+
}
98+
};
99+
}
100+
return apijson.demo.server.MethodUtil.listMethod(request);
101+
}
102+
103+
public static void invokeMethod(String request, Object instance, Listener<JSONObject> listener) throws Exception {
104+
apijson.demo.server.MethodUtil.invokeMethod(request, instance, listener);
105+
}
106+
107+
public static void invokeMethod(JSONObject request, Object instance, Listener<JSONObject> listener) throws Exception {
108+
apijson.demo.server.MethodUtil.invokeMethod(request, instance, listener);
109+
}
110+
111+
}

APIJSON-Android/APIJSONTest/app/src/main/java/apijson/demo/server/MethodUtil.java

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package apijson.demo.server;
22

3-
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
4-
import static java.lang.annotation.ElementType.CONSTRUCTOR;
5-
import static java.lang.annotation.ElementType.FIELD;
6-
import static java.lang.annotation.ElementType.METHOD;
7-
import static java.lang.annotation.ElementType.PARAMETER;
8-
import static java.lang.annotation.RetentionPolicy.RUNTIME;
3+
import android.content.Context;
4+
5+
import com.alibaba.fastjson.JSON;
6+
import com.alibaba.fastjson.JSONArray;
7+
import com.alibaba.fastjson.JSONObject;
8+
import com.alibaba.fastjson.annotation.JSONField;
9+
import com.alibaba.fastjson.parser.Feature;
10+
import com.alibaba.fastjson.parser.ParserConfig;
11+
import com.alibaba.fastjson.util.TypeUtils;
912

1013
import java.io.File;
14+
import java.io.IOException;
1115
import java.lang.annotation.Documented;
1216
import java.lang.annotation.Retention;
1317
import java.lang.annotation.Target;
@@ -20,6 +24,7 @@
2024
import java.lang.reflect.Type;
2125
import java.util.ArrayList;
2226
import java.util.Collection;
27+
import java.util.Enumeration;
2328
import java.util.HashMap;
2429
import java.util.HashSet;
2530
import java.util.List;
@@ -28,18 +33,20 @@
2833
import java.util.Objects;
2934
import java.util.Set;
3035

31-
import com.alibaba.fastjson.JSON;
32-
import com.alibaba.fastjson.JSONArray;
33-
import com.alibaba.fastjson.JSONObject;
34-
import com.alibaba.fastjson.annotation.JSONField;
35-
import com.alibaba.fastjson.parser.Feature;
36-
import com.alibaba.fastjson.parser.ParserConfig;
37-
import com.alibaba.fastjson.util.TypeUtils;
38-
36+
import dalvik.system.DexFile;
37+
import dalvik.system.PathClassLoader;
3938
import zuo.biao.apijson.StringUtil;
4039

40+
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
41+
import static java.lang.annotation.ElementType.CONSTRUCTOR;
42+
import static java.lang.annotation.ElementType.FIELD;
43+
import static java.lang.annotation.ElementType.METHOD;
44+
import static java.lang.annotation.ElementType.PARAMETER;
45+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
46+
4147
public class MethodUtil {
4248

49+
4350
/**非null注解
4451
* javax.validation.constraints.NotNull不在JDK里面,为了减少第三方库引用就在这里实现了一个替代品
4552
* @author Lemon
@@ -63,6 +70,12 @@ public interface Callback {
6370
JSONObject newErrorResult(Exception e);
6471
}
6572

73+
74+
public interface ClassLoaderCallback {
75+
List<Class<?>> loadClassList(String packageOrFileName, String className, boolean ignoreError) throws ClassNotFoundException, IOException;
76+
Class<?> loadClass(String className) throws ClassNotFoundException;
77+
}
78+
6679
public static String KEY_CODE = "code";
6780
public static String KEY_MSG = "msg";
6881

@@ -88,31 +101,36 @@ public interface Callback {
88101
public static String KEY_CALL_MAP = "call(){}";
89102

90103

91-
public static Callback CALLBACK = new Callback() {
92-
93-
@Override
94-
public JSONObject newSuccessResult() {
95-
JSONObject result = new JSONObject(true);
96-
result.put(KEY_CODE, CODE_SUCCESS);
97-
result.put(KEY_MSG, MSG_SUCCESS);
98-
return result;
99-
}
100-
101-
@Override
102-
public JSONObject newErrorResult(Exception e) {
103-
JSONObject result = new JSONObject(true);
104-
result.put(KEY_CODE, CODE_SERVER_ERROR);
105-
result.put(KEY_MSG, e.getMessage());
106-
return result;
107-
}
108-
};
104+
public static ClassLoaderCallback CLASS_LOADER_CALLBACK;
105+
public static Callback CALLBACK;
109106

110107
// Map<class, <constructorArgs, instance>>
111108
public static final Map<Class<?>, Map<Object, Object>> INSTANCE_MAP;
112109
public static final Map<String, Class<?>> PRIMITIVE_CLASS_MAP;
113110
public static final Map<String, Class<?>> BASE_CLASS_MAP;
114111
public static final Map<String, Class<?>> CLASS_MAP;
115112
static {
113+
CLASS_LOADER_CALLBACK = null;
114+
CALLBACK = new Callback() {
115+
116+
@Override
117+
public JSONObject newSuccessResult() {
118+
JSONObject result = new JSONObject(true);
119+
result.put(KEY_CODE, CODE_SUCCESS);
120+
result.put(KEY_MSG, MSG_SUCCESS);
121+
return result;
122+
}
123+
124+
@Override
125+
public JSONObject newErrorResult(Exception e) {
126+
JSONObject result = new JSONObject(true);
127+
result.put(KEY_CODE, CODE_SERVER_ERROR);
128+
result.put(KEY_MSG, e.getMessage());
129+
return result;
130+
}
131+
};
132+
133+
116134
INSTANCE_MAP = new HashMap<>();
117135

118136
PRIMITIVE_CLASS_MAP = new HashMap<String, Class<?>>();
@@ -582,12 +600,12 @@ public static JSONArray getMethodListGroupByClass(String pkgName, String clsName
582600

583601
boolean allMethod = isEmpty(methodName, true);
584602

585-
List<Class<?>> classlist = findClassList(pkgName, clsName, true);
603+
List<Class<?>> classList = findClassList(pkgName, clsName, true);
586604
JSONArray list = null;
587-
if (classlist != null) {
588-
list = new JSONArray(classlist.size());
605+
if (classList != null) {
606+
list = new JSONArray(classList.size());
589607

590-
for (Class<?> cls : classlist) {
608+
for (Class<?> cls : classList) {
591609
if (cls == null) {
592610
continue;
593611
}
@@ -637,6 +655,10 @@ public static String dot2Separator(String name) {
637655
return name == null ? null : name.replaceAll("\\.", File.separator);
638656
}
639657

658+
public static String separator2dot(String name) {
659+
return name == null ? null : name.replaceAll(File.separator, ".");
660+
}
661+
640662
// private void initTypesAndValues(JSONArray methodArgs, Class<?>[] types, Object[] args)
641663
// throws IllegalArgumentException, ClassNotFoundException, IOException {
642664
// initTypesAndValues(methodArgs, types, args, false);
@@ -876,7 +898,11 @@ public static Class<?> findClass(String packageOrFileName, String className, boo
876898
* @return
877899
* @throws ClassNotFoundException
878900
*/
879-
public static List<Class<?>> findClassList(String packageOrFileName, String className, boolean ignoreError) throws ClassNotFoundException {
901+
public static List<Class<?>> findClassList(String packageOrFileName, String className, boolean ignoreError) throws ClassNotFoundException, IOException {
902+
if (CLASS_LOADER_CALLBACK != null) {
903+
return CLASS_LOADER_CALLBACK.loadClassList(packageOrFileName, className, ignoreError);
904+
}
905+
880906
List<Class<?>> list = new ArrayList<>();
881907

882908
int index = className.indexOf("<");

APIJSON-Android/APIJSONTest/app/src/main/java/apijson/demo/ui/SelectActivity.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import apijson.demo.R;
3333
import apijson.demo.RequestUtil;
3434
import apijson.demo.StringUtil;
35-
import apijson.demo.application.DemoApplication;
3635
import zuo.biao.apijson.JSON;
3736

3837
/**选择Activity
@@ -116,8 +115,8 @@ public boolean onLongClick(View v) {
116115
});
117116
}
118117

119-
DemoApplication.getInstance().onUIAutoActivityCreate(this);
120-
DemoApplication.getInstance().record();
118+
// DemoApplication.getInstance().onUIAutoActivityCreate(this);
119+
// DemoApplication.getInstance().record();
121120

122121
}
123122

0 commit comments

Comments
 (0)