mFlows;
24 |
25 | private int mIndex;
26 | private OfflinePackageInfo mPackageInfo;
27 | private boolean isForceStop;
28 | private FlowListener mFlowListener;
29 | private FlowReportParams mReportParams;
30 |
31 | public ResourceFlow(OfflinePackageInfo packageInfo) {
32 |
33 | mPackageInfo = packageInfo;
34 | mReportParams = new FlowReportParams(mPackageInfo.getBisName());
35 | }
36 |
37 | public void stop() {
38 | isForceStop = true;
39 | }
40 |
41 | public void addFlow(IFlow flow) {
42 | if (mFlows == null) {
43 | mFlows = new ArrayList<>();
44 | }
45 | mFlows.add(flow);
46 | }
47 |
48 | public void start() {
49 | if (mFlows == null || mFlows.size() == 0) {
50 | return;
51 | }
52 | mIndex = 0;
53 | process();
54 | }
55 |
56 | void process() {
57 |
58 | if (mIndex >= mFlows.size()) {
59 | OfflineWebLog.i(TAG, "done ... ...");
60 | setDone();
61 | return;
62 | }
63 |
64 | if (isForceStop) {
65 | OfflineWebLog.i(TAG, "isForceStop = " + isForceStop);
66 | return;
67 | }
68 |
69 | final IFlow iFlow = mFlows.get(mIndex++);
70 | OfflineWebManager.getInstance().getExecutor().execute(new Runnable() {
71 | @Override
72 | public void run() {
73 | try {
74 | OfflineWebLog.i(TAG, "Flow start process :" + iFlow.getClass().getSimpleName());
75 | iFlow.process();
76 | } catch (FlowException e) {
77 | e.printStackTrace();
78 | OfflineWebLog.e(TAG, e);
79 | error(e);
80 | }
81 | }
82 | });
83 | }
84 |
85 | void error(Throwable throwable) {
86 | OfflineWebLog.e(TAG, throwable);
87 | if (mFlowListener != null) {
88 | mFlowListener.error(mPackageInfo, throwable);
89 | }
90 | OfflineWebManager.getInstance().getFlowResultHandleStrategy().done(mReportParams);
91 | }
92 |
93 | public FlowReportParams getReportParams() {
94 | return this.mReportParams;
95 | }
96 |
97 | public OfflinePackageInfo getPackageInfo() {
98 | return mPackageInfo;
99 | }
100 |
101 | public void setPackageInfo(OfflinePackageInfo packageInfo) {
102 | mPackageInfo = packageInfo;
103 | }
104 |
105 | public void setFlowListener(FlowListener flowListener) {
106 |
107 | mFlowListener = flowListener;
108 | }
109 |
110 | public void setDone() {
111 | if (mFlowListener != null) {
112 | mFlowListener.done(mPackageInfo);
113 | }
114 | OfflineWebManager.getInstance().getFlowResultHandleStrategy().done(mReportParams);
115 | }
116 |
117 | public interface FlowListener {
118 | void done(OfflinePackageInfo packageInfo);
119 |
120 | void error(OfflinePackageInfo packageInfo, Throwable e);
121 | }
122 |
123 | public interface IFlow {
124 | void process() throws FlowException;
125 | }
126 |
127 | public static class FlowException extends Exception {
128 |
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/task/CheckAndUpdateTask.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.task;
2 |
3 | import com.lalamove.huolala.offline.webview.OfflineWebManager;
4 | import com.lalamove.huolala.offline.webview.info.OfflinePackageInfo;
5 | import com.lalamove.huolala.offline.webview.log.OfflineWebLog;
6 | import com.lalamove.huolala.offline.webview.resource.DownloadFlow;
7 | import com.lalamove.huolala.offline.webview.resource.FetchPackageFlow;
8 | import com.lalamove.huolala.offline.webview.resource.ParsePackageFlow;
9 | import com.lalamove.huolala.offline.webview.resource.ReplaceResFlow;
10 | import com.lalamove.huolala.offline.webview.resource.ResourceFlow;
11 | import com.lalamove.huolala.offline.webview.utils.OfflinePackageUtil;
12 |
13 | /**
14 | * @copyright:深圳依时货拉拉科技有限公司
15 | * @fileName: CheckAndUpdateTask
16 | * @author: kelvin
17 | * @date: 8/4/21
18 | * @description: 根据业务名称检查更新 离线包
19 | * @history:
20 | */
21 |
22 | public class CheckAndUpdateTask implements Runnable {
23 | private static final String TAG = CheckAndUpdateTask.class.getSimpleName();
24 | private String mBisName;
25 | private ResourceFlow.FlowListener mListener;
26 |
27 | public CheckAndUpdateTask(String bisName,final ResourceFlow.FlowListener listener) {
28 | mBisName = bisName;
29 | mListener = listener;
30 | }
31 |
32 | /**
33 | * 单线程
34 | */
35 | @Override
36 | public void run() {
37 | synchronized (CheckAndUpdateTask.class) {
38 | //当前bisName 是否在禁用列表
39 | if (OfflineWebManager.getInstance().getInterceptor().isIntercept(mBisName)) {
40 | OfflineWebLog.i(TAG, "interceptor bisName :" + mBisName);
41 | return;
42 | }
43 | //判断是否已经在更新
44 | for (ResourceFlow resourceFlow : OfflineWebManager.getInstance().getResourceFlows()) {
45 | if (mBisName.equals(resourceFlow.getPackageInfo().getBisName())) {
46 | OfflineWebLog.i(TAG, "same flow running :" + mBisName);
47 | return;
48 | }
49 | }
50 | //新建更新任务
51 | String packageVersion = OfflinePackageUtil.getPackageVersion(mBisName);
52 | OfflineWebLog.i(TAG, "checkPackage:" + mBisName + ",packageVersion:" + packageVersion);
53 | ResourceFlow resourceFlow = new ResourceFlow(new OfflinePackageInfo(mBisName, packageVersion));
54 | resourceFlow.addFlow(new FetchPackageFlow(resourceFlow));
55 | resourceFlow.addFlow(new DownloadFlow(resourceFlow));
56 | resourceFlow.addFlow(new ParsePackageFlow(resourceFlow));
57 | resourceFlow.addFlow(new ReplaceResFlow(resourceFlow));
58 | resourceFlow.setFlowListener(new ResourceFlow.FlowListener() {
59 | @Override
60 | public void done(OfflinePackageInfo packageInfo) {
61 | OfflineWebLog.i(TAG, "done :");
62 | if (mListener != null) {
63 | mListener.done(packageInfo);
64 | }
65 | doneFlow(packageInfo);
66 | }
67 |
68 | @Override
69 | public void error(OfflinePackageInfo packageInfo, Throwable throwable) {
70 | if (mListener != null) {
71 | mListener.error(packageInfo, throwable);
72 | }
73 | doneFlow(packageInfo);
74 | OfflineWebLog.i(TAG, "error");
75 |
76 | }
77 |
78 | private void doneFlow(OfflinePackageInfo packageInfo) {
79 | //移除任务
80 | for (ResourceFlow flow : OfflineWebManager.getInstance().getResourceFlows()) {
81 | if (packageInfo.equals(flow.getPackageInfo())) {
82 | OfflineWebManager.getInstance().getResourceFlows().remove(flow);
83 | break;
84 | }
85 | }
86 | }
87 | });
88 | resourceFlow.start();
89 | OfflineWebManager.getInstance().getResourceFlows().add(resourceFlow);
90 | }
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/task/CheckVersionTask.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.task;
2 |
3 | import com.lalamove.huolala.offline.webview.log.OfflineWebLog;
4 | import com.lalamove.huolala.offline.webview.utils.OfflineConstant;
5 | import com.lalamove.huolala.offline.webview.utils.OfflineFileUtils;
6 | import com.lalamove.huolala.offline.webview.utils.OfflinePackageUtil;
7 |
8 | import java.io.File;
9 | import java.io.FileFilter;
10 |
11 | /**
12 | * @copyright:深圳依时货拉拉科技有限公司
13 | * @fileName: CheckVersionTask
14 | * @author: kelvin
15 | * @date: 8/6/21
16 | * @description: 初始化之后检测新旧离线包版本 进行删除替换
17 | * @history:
18 | */
19 |
20 | public class CheckVersionTask implements Runnable {
21 |
22 | private static final String TAG = CheckVersionTask.class.getSimpleName();
23 |
24 | @Override
25 | public void run() {
26 | OfflineWebLog.i(TAG, "checkVersions");
27 | File file = new File(OfflinePackageUtil.getResDir());
28 | if (file.exists()) {
29 | File[] packageDirs = file.listFiles(new FileFilter() {
30 | @Override
31 | public boolean accept(File pathname) {
32 | return pathname.isDirectory();
33 | }
34 | });
35 | if (packageDirs != null && packageDirs.length != 0) {
36 | for (File packageDir : packageDirs) {
37 | OfflineWebLog.i(TAG, "check :" + packageDir.getName());
38 | File nowFile = new File(packageDir, OfflineConstant.NEW_DIR_NAME);
39 | File curFile = new File(packageDir, OfflineConstant.CUR_DIR_NAME);
40 | if (nowFile.exists() && curFile.exists()) {
41 | //存在 cur 和new
42 | //cur->old
43 | OfflineFileUtils.rename(curFile, OfflineConstant.OLD_DIR_NAME);
44 | //new->cur
45 | OfflineFileUtils.rename(nowFile, OfflineConstant.CUR_DIR_NAME);
46 | OfflineWebLog.i(TAG, "update replace");
47 | } else if (nowFile.exists()) {
48 | OfflineWebLog.i(TAG, "update");
49 | //new->cur
50 | OfflineFileUtils.rename(nowFile, OfflineConstant.CUR_DIR_NAME);
51 | }
52 |
53 | File oldFile = new File(packageDir, OfflineConstant.OLD_DIR_NAME);
54 |
55 | //删除old
56 | if (oldFile.exists()) {
57 | OfflineWebLog.i(TAG, "del start");
58 | OfflineFileUtils.deleteDir(oldFile);
59 | OfflineWebLog.i(TAG, "del done");
60 | }
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/task/CleanTask.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.task;
2 |
3 | import com.lalamove.huolala.offline.webview.log.OfflineWebLog;
4 | import com.lalamove.huolala.offline.webview.utils.OfflineFileUtils;
5 | import com.lalamove.huolala.offline.webview.utils.OfflinePackageUtil;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * @copyright:深圳依时货拉拉科技有限公司
11 | * @fileName: CleanTask
12 | * @author: kelvin
13 | * @date: 3/30/22
14 | * @description: 清理所有离线包
15 | * @history:
16 | */
17 |
18 | public class CleanTask implements Runnable {
19 | private static final String TAG = CleanTask.class.getSimpleName();
20 |
21 | @Override
22 | public void run() {
23 | try {
24 | OfflineFileUtils.deleteDir(new File(OfflinePackageUtil.getResDir()));
25 | } catch (Exception e) {
26 | OfflineWebLog.e(TAG, e);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/threadpool/IExecutorServiceProvider.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.threadpool;
2 |
3 | import java.util.concurrent.ExecutorService;
4 |
5 | /**
6 | * create by zhii.yang 2021/12/16
7 | * desc :
8 | */
9 | public interface IExecutorServiceProvider {
10 |
11 | /**
12 | * 获取线程池
13 | * @return 线程池
14 | */
15 | ExecutorService get();
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/threadpool/OfflineIoThreadPool.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.threadpool;
2 |
3 | import android.annotation.SuppressLint;
4 |
5 | import java.util.concurrent.LinkedBlockingDeque;
6 | import java.util.concurrent.ThreadFactory;
7 | import java.util.concurrent.ThreadPoolExecutor;
8 | import java.util.concurrent.TimeUnit;
9 | import java.util.concurrent.atomic.AtomicInteger;
10 |
11 | /**
12 | * @copyright:深圳依时货拉拉科技有限公司
13 | * @fileName: OfflineIoThreadPool
14 | * @author: muye
15 | * @date: 2021/7/7
16 | * @description: io型数据库,用于网络请求
17 | * @history:
18 | */
19 |
20 | public class OfflineIoThreadPool {
21 |
22 | private final static String TAG = "OfflineIoThreadPool";
23 |
24 | //参数初始化
25 | protected static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
26 | //线程池最大容纳线程数
27 | protected static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
28 |
29 | private static final int TIME_OUT = 60;
30 |
31 | private static final int CORE_POOL_SIZE = 5;
32 | private ThreadPoolExecutor mThreadPoolExecutor;
33 |
34 | private static OfflineIoThreadPool sCompressThreadPool;
35 |
36 | private OfflineIoThreadPool() {
37 | initThreadPool();
38 | }
39 |
40 | public static OfflineIoThreadPool getInstance() {
41 | if (null == sCompressThreadPool) {
42 | synchronized (OfflineIoThreadPool.class) {
43 | if (null == sCompressThreadPool) {
44 | sCompressThreadPool = new OfflineIoThreadPool();
45 | }
46 | }
47 | }
48 | return sCompressThreadPool;
49 | }
50 |
51 | public ThreadPoolExecutor getThreadPoolExecutor() {
52 | return mThreadPoolExecutor;
53 | }
54 |
55 | @SuppressLint("NewApi")
56 | private void initThreadPool() {
57 | final AtomicInteger mAtomicInteger = new AtomicInteger(1);
58 | SecurityManager var1 = System.getSecurityManager();
59 | final ThreadGroup group = var1 != null ? var1.getThreadGroup() : Thread.currentThread().getThreadGroup();
60 | ThreadFactory threadFactory = new ThreadFactory() {
61 | @Override
62 | public Thread newThread(Runnable runnable) {
63 | return new Thread(group, runnable, "track io-pool-thread-" + mAtomicInteger.getAndIncrement(), 0);
64 | // return new Thread(group, runnable, "track io-pool-thread-" + mAtomicInteger.getAndIncrement(), 1024 * 256);
65 | }
66 | };
67 | mThreadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, Math.max(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE),
68 | TIME_OUT, TimeUnit.SECONDS,
69 | new LinkedBlockingDeque<>(128),
70 | threadFactory);
71 | mThreadPoolExecutor.allowCoreThreadTimeOut(true);
72 | mThreadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy() {
73 | @Override
74 | public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
75 | super.rejectedExecution(r, e);
76 |
77 | }
78 | });
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/EnhWebUriUtils.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | import android.net.Uri;
4 |
5 | import com.lalamove.huolala.offline.webview.log.OfflineWebLog;
6 |
7 |
8 | /**
9 | * @author yz
10 | * @time 2021/12/22 3:38 下午
11 | */
12 | public class EnhWebUriUtils {
13 |
14 | private static final String TAG = "EnhWebUriUtils";
15 |
16 | public static String getScheme(String urlPath) {
17 | try {
18 | return Uri.parse(urlPath).getScheme();
19 | } catch (Exception e) {
20 | e.printStackTrace();
21 | }
22 | return "";
23 | }
24 |
25 | /**
26 | * 获取监控需要的url
27 | * https://aaaa.cn/path?offweb=bisName#/fragment?paramA=1¶msB=2
28 | * -> https://aaaa.cn/path#/fragment
29 | *
30 | * @param urlPath
31 | * @return
32 | */
33 | public static String getMonitorUrl(String urlPath) {
34 | try {
35 | int pathIndex = urlPath.indexOf("?");
36 | if (pathIndex != -1) {
37 | StringBuilder urlBuild = new StringBuilder();
38 | urlBuild.append(urlPath.substring(0, pathIndex));
39 |
40 | int jinIndex = urlPath.indexOf("#");
41 | if (jinIndex != -1) {
42 | //截取后边的字符串
43 | urlPath = urlPath.substring(jinIndex);
44 | if (urlPath.contains("?")) {
45 | //截取#跟? 之间的字符串
46 | String jinAndWen = urlPath.substring(0, urlPath.indexOf("?"));
47 | //过滤当前只有一个#号字符串
48 | if (!"#".equals(jinAndWen.trim())) {
49 | urlBuild.append(jinAndWen);
50 | }
51 |
52 | OfflineWebLog.d(TAG, "monitorUrl -> " + urlBuild);
53 | }
54 | }
55 | return urlBuild.toString();
56 | }
57 | } catch (Exception e) {
58 | e.printStackTrace();
59 | }
60 | return urlPath == null ? "" : urlPath;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/MemoryConstants.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | import androidx.annotation.IntDef;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * @copyright:深圳依时货拉拉科技有限公司
10 | * @fileName: MemoryConstants
11 | * @author: kelvin
12 | * @date: 7/19/21
13 | * @description: 内存大小 常量类
14 | * @history:
15 | */
16 | public final class MemoryConstants {
17 |
18 | public static final int BYTE = 1;
19 | public static final int KB = 1024;
20 | public static final int MB = 1048576;
21 | public static final int GB = 1073741824;
22 |
23 | @IntDef({BYTE, KB, MB, GB})
24 | @Retention(RetentionPolicy.SOURCE)
25 | public @interface Unit {
26 | }
27 | }
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/OfflineConstant.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | /**
4 | * @copyright:深圳依时货拉拉科技有限公司
5 | * @fileName: OfflineConstant
6 | * @author: kelvin
7 | * @date: 7/19/21
8 | * @description:
9 | * @history:
10 | */
11 |
12 | public interface OfflineConstant {
13 |
14 | String ZIP_SUFFIX = ".zip";
15 |
16 | String ROOT_DIR_NAME = "offline_web";
17 |
18 | String CONFIG_FILE_NAME = ".offweb.json";
19 |
20 | String OFFLINE_PACKAGE_INFO = "offline_package_info";
21 |
22 | String BIS_NAME = "bisName";
23 |
24 | String OFF_WEB = "offweb";
25 |
26 | String MODULE_SP_NAME = "off_web";
27 |
28 | String HTML_FILE = "index.html";
29 |
30 | String CUR_DIR_NAME = "cur";
31 |
32 | String OLD_DIR_NAME = "old";
33 |
34 | String NEW_DIR_NAME = "new";
35 |
36 | String TEMP_DIR_NAME = "temp";
37 |
38 | String PARAM_OFFWEB_HOST = "offweb_host";
39 |
40 | String PARAM_OFFLINE_ZIP_VER = "offlineZipVer";
41 |
42 | String PARAM_ENV = "env";
43 |
44 | String PARAM_CLIENT_VERSION = "clientVersion";
45 |
46 | String PARAM_OS= "os";
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/OfflineGsonUtils.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | import android.text.TextUtils;
4 | import com.google.gson.Gson;
5 | import com.google.gson.GsonBuilder;
6 | import com.google.gson.reflect.TypeToken;
7 |
8 | import java.lang.reflect.ParameterizedType;
9 | import java.lang.reflect.Type;
10 | import java.util.List;
11 |
12 | /**
13 | * @author joseph.gao
14 | *
15 | * gson工具类
16 | *
17 | * toJson
18 | * fromJson
19 | */
20 | public class OfflineGsonUtils {
21 |
22 | private static final Gson GSON;
23 |
24 | private OfflineGsonUtils() {
25 | }
26 |
27 | static {
28 | GSON = new GsonBuilder()
29 | .serializeNulls() //支持序列化null的参数
30 | .enableComplexMapKeySerialization()//支持将序列化key为object的map,默认只能序列化key为string的map
31 | .create();
32 | }
33 |
34 | public static String toJson(Object obj) {
35 | if (null == obj) {
36 | return "";
37 | }
38 | try {
39 | return GSON.toJson(obj);
40 | } catch (Exception e) {
41 | e.printStackTrace();
42 | }
43 | return "";
44 | }
45 |
46 | public static Object fromJson(String json, Type classType) {
47 | if (null == json) {
48 | return null;
49 | }
50 | try {
51 | return GSON.fromJson(json, classType);
52 | } catch (Exception e) {
53 | e.printStackTrace();
54 | }
55 | return null;
56 | }
57 |
58 | public static T fromJson(String jsonStr, Class clazz) {
59 | T jsonObj = null;
60 | if (!TextUtils.isEmpty(jsonStr)) {
61 | try {
62 | jsonObj = GSON.fromJson(jsonStr, clazz);
63 | } catch (Exception e) {
64 | e.printStackTrace();
65 | }
66 | }
67 | return jsonObj;
68 | }
69 |
70 | public static T fromJson(String jsonStr) {
71 | T jsonObj = null;
72 | if (!TextUtils.isEmpty(jsonStr)) {
73 | try {
74 | jsonObj = GSON.fromJson(jsonStr, new TypeToken() {
75 | }.getType());
76 | } catch (Exception e) {
77 | e.printStackTrace();
78 | }
79 | }
80 | return jsonObj;
81 | }
82 |
83 | public static List fromJsonToList(String jsonStr, Class clazz) {
84 | List jsonObj = null;
85 |
86 | if (!TextUtils.isEmpty(jsonStr)) {
87 | try {
88 | Type type = new ParameterizedTypeImpl(clazz);
89 | jsonObj = GSON.fromJson(jsonStr, type);
90 | } catch (Exception e) {
91 | e.printStackTrace();
92 | }
93 | }
94 | return jsonObj;
95 | }
96 |
97 |
98 | private static class ParameterizedTypeImpl implements ParameterizedType {
99 | Class clazz;
100 |
101 | public ParameterizedTypeImpl(Class clz) {
102 | clazz = clz;
103 | }
104 |
105 | @Override
106 | public Type[] getActualTypeArguments() {
107 | return new Type[]{clazz};
108 | }
109 |
110 | @Override
111 | public Type getRawType() {
112 | return List.class;
113 | }
114 |
115 | @Override
116 | public Type getOwnerType() {
117 | return null;
118 | }
119 | }
120 |
121 | }
122 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/OfflineHandlerUtils.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import com.lalamove.huolala.offline.webview.OfflineWebManager;
7 |
8 | /**
9 | * @copyright:深圳依时货拉拉科技有限公司
10 | * @fileName: OfflineHandlerUtils
11 | * @author: kelvin
12 | * @date: 7/19/21
13 | * @description: 离线包 handler
14 | * @history:
15 | */
16 | public class OfflineHandlerUtils {
17 | private static final String TAG = OfflineHandlerUtils.class.getSimpleName();
18 |
19 | private static Handler sHandler;
20 |
21 | private OfflineHandlerUtils() {
22 | }
23 |
24 | public static void runOnUiThread(Runnable action) {
25 | if (Looper.myLooper() != Looper.getMainLooper()) {
26 | if (sHandler == null) {
27 | sHandler = new Handler(Looper.getMainLooper());
28 | }
29 | sHandler.post(action);
30 | } else {
31 | try {
32 | action.run();
33 | } catch (Exception e) {
34 | OfflineWebManager.getInstance().getLogger().e(TAG, e);
35 | }
36 | }
37 | }
38 |
39 | public static void post(Runnable action) {
40 | if (sHandler == null) {
41 | sHandler = new Handler(Looper.getMainLooper());
42 | }
43 | sHandler.post(action);
44 | }
45 |
46 | public static void postDelayed(Runnable action, long delayMillis) {
47 | if (sHandler == null) {
48 | sHandler = new Handler(Looper.getMainLooper());
49 | }
50 | sHandler.postDelayed(action, delayMillis);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/OfflinePackageUtil.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.lalamove.huolala.offline.webview.info.OfflineZipPackageConfig;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * @copyright:深圳依时货拉拉科技有限公司
11 | * @fileName: OfflinePackageUtil
12 | * @author: kelvin
13 | * @date: 7/21/21
14 | * @description: 更新包文件 相关方法
15 | * @history:
16 | */
17 |
18 | public class OfflinePackageUtil {
19 |
20 | private OfflinePackageUtil() {
21 | }
22 |
23 | public static OfflineZipPackageConfig getOfflineConfig(String bisName) {
24 | String configJsonStr = OfflineFileUtils.readFile2String(getBisDir(bisName)+File.separator+OfflineConstant.CUR_DIR_NAME
25 | + File.separator + OfflineConstant.CONFIG_FILE_NAME);
26 | if (TextUtils.isEmpty(configJsonStr)) {
27 | return null;
28 | }
29 | return OfflineGsonUtils.fromJson(configJsonStr, OfflineZipPackageConfig.class);
30 | }
31 |
32 | public static String getResDir() {
33 | return OfflineFileUtils.getInternalAppDataPath() + File.separator + OfflineConstant.ROOT_DIR_NAME;
34 | }
35 |
36 | public static String getBisDir(String bisName) {
37 | return getResDir() + File.separator + bisName;
38 | }
39 |
40 |
41 | public static String getPackageVersion(String bisName) {
42 | OfflineZipPackageConfig offlineConfig = OfflinePackageUtil.getOfflineConfig(bisName);
43 | if (offlineConfig == null) {
44 | return "0";
45 | }
46 | return offlineConfig.getVer();
47 | }
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/OfflineStringUtils.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | /**
4 | * @copyright:深圳依时货拉拉科技有限公司
5 | * @fileName: OfflineStringUtils
6 | * @author: kelvin
7 | * @date: 8/12/21
8 | * @description: 字符串工具
9 | * @history:
10 | */
11 |
12 | public class OfflineStringUtils {
13 |
14 | private OfflineStringUtils() {
15 | }
16 |
17 | public static String getErrorString(Throwable t) {
18 | if (t == null) {
19 | return "UnknownError";
20 | }
21 | try {
22 | return t.getMessage();
23 | } catch (Exception e) {
24 | return "UnknownError";
25 | }
26 | }
27 |
28 | public static String appendUnsafeString(String... args) {
29 | StringBuilder stringBuilder = new StringBuilder();
30 | for (String arg : args) {
31 | stringBuilder.append(arg);
32 | }
33 | return stringBuilder.toString();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/utils/UrlParamsUtils.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.utils;
2 |
3 | import android.text.TextUtils;
4 |
5 | /**
6 | * @copyright:深圳依时货拉拉科技有限公司
7 | * @fileName: UrlParamsUtils
8 | * @author: kelvin
9 | * @date: 7/23/21
10 | * @description: url参数工具类
11 | * @history:
12 | */
13 |
14 | public class UrlParamsUtils {
15 |
16 | private UrlParamsUtils() {
17 | }
18 |
19 | /**
20 | * url后追加参数
21 | */
22 | public static String urlAppendParam(String url, String key, String value) {
23 | if (TextUtils.isEmpty(url)||url.contains(key)) {
24 | return url;
25 | }
26 | StringBuilder stringBuilder = new StringBuilder(url);
27 | if (url.contains("=")) {
28 | return stringBuilder.append("&").append(key).append("=").append(value).toString();
29 | } else {
30 | return stringBuilder.append("?").append(key).append("=").append(value).toString();
31 | }
32 |
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/widget/EnhOfflineWebView.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.webkit.WebView;
6 | import android.webkit.WebViewClient;
7 |
8 | import androidx.annotation.Nullable;
9 |
10 | import com.lalamove.huolala.offline.webview.monitor.base.IEnhWebResourceErrorAdapter;
11 | import com.lalamove.huolala.offline.webview.monitor.base.IEnhWebResourceRequestAdapter;
12 | import com.lalamove.huolala.offline.webview.monitor.base.IEnhWebResourceResponseAdapter;
13 | import com.lalamove.huolala.offline.webview.monitor.base.IWebPageStatus;
14 | import com.lalamove.huolala.offline.webview.monitor.impl.OfflineWebPageStatus;
15 | import com.lalamove.huolala.offline.webview.proxy.IOfflineWebViewProxy;
16 | import com.lalamove.huolala.offline.webview.proxy.OffWebProxyFactory;
17 |
18 | import java.util.Map;
19 |
20 | /**
21 | * @copyright:深圳依时货拉拉科技有限公司
22 | * @fileName: EnhOfflineWebView
23 | * @author: kelvin
24 | * @date: 7/22/21
25 | * @description: 增强webview
26 | * @history:
27 | */
28 | public class EnhOfflineWebView extends WebView implements ReloadOfflineWebView, IWebPageStatus {
29 |
30 | private IOfflineWebViewProxy mOfflineWebViewProxy;
31 | private IWebPageStatus mWebPageStatus;
32 | private EnhWebViewClient mEnhWebViewClient;
33 |
34 | public EnhOfflineWebView(Context context) {
35 | super(context);
36 | initProxy();
37 | }
38 |
39 | public EnhOfflineWebView(Context context, AttributeSet attrs) {
40 | super(context, attrs);
41 | initProxy();
42 | }
43 |
44 | public EnhOfflineWebView(Context context, AttributeSet attrs, int defStyleAttr) {
45 | super(context, attrs, defStyleAttr);
46 | initProxy();
47 | }
48 |
49 | public EnhOfflineWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
50 | super(context, attrs, defStyleAttr, defStyleRes);
51 | initProxy();
52 | }
53 |
54 | private void initProxy() {
55 | mOfflineWebViewProxy = OffWebProxyFactory.getProxy(this);
56 | mWebPageStatus = new OfflineWebPageStatus();
57 |
58 | mEnhWebViewClient = new EnhWebViewClient(this);
59 | super.setWebViewClient(mEnhWebViewClient);
60 | }
61 |
62 | @Override
63 | public void setWebViewClient(WebViewClient webViewClient){
64 | mEnhWebViewClient.setDelegate(webViewClient);
65 | }
66 |
67 | @Override
68 | public void loadUrl(String url) {
69 | mWebPageStatus.onLoadUrl(url);
70 | super.loadUrl(mOfflineWebViewProxy.loadUrl(url));
71 | }
72 |
73 | @Override
74 | public void loadUrl(String url, Map additionalHttpHeaders) {
75 | mWebPageStatus.onLoadUrl(url);
76 | super.loadUrl(mOfflineWebViewProxy.loadUrl(url), additionalHttpHeaders);
77 | }
78 |
79 | @Override
80 | public void reloadOfflineWeb() {
81 | // refresh this web view
82 | }
83 |
84 | @Override
85 | public void destroy() {
86 | super.destroy();
87 | mOfflineWebViewProxy.destroy();
88 | }
89 |
90 | @Override
91 | protected void onDetachedFromWindow() {
92 | super.onDetachedFromWindow();
93 | mOfflineWebViewProxy.destroy();
94 | }
95 |
96 | @Override
97 | public void onLoadError(IEnhWebResourceRequestAdapter request, IEnhWebResourceErrorAdapter error) {
98 | mWebPageStatus.onLoadError(request, error);
99 | }
100 |
101 | @Override
102 | public void onLoadError(IEnhWebResourceRequestAdapter request, IEnhWebResourceResponseAdapter errorResponse) {
103 | mWebPageStatus.onLoadError(request, errorResponse);
104 | }
105 |
106 | @Override
107 | public void onLoadError(String url, String error) {
108 | mWebPageStatus.onLoadError(url, error);
109 | }
110 |
111 | @Override
112 | public void onLoadUrl(@Nullable String url) {
113 | mWebPageStatus.onLoadUrl(url);
114 | }
115 |
116 | @Override
117 | public void onPageLoadFinish(@Nullable String url, int progress) {
118 | mWebPageStatus.onPageLoadFinish(url, progress);
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/widget/IOfflineWebView.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.widget;
2 |
3 |
4 | /**
5 | * @copyright:深圳依时货拉拉科技有限公司
6 | * @fileName: IOfflineWebView
7 | * @author: kelvin
8 | * @date: 7/19/21
9 | * @description: webview接口
10 | * @history:
11 | */
12 |
13 | public interface IOfflineWebView {
14 | /**
15 | * 销毁
16 | */
17 | void destroy();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/widget/OfflineWebView.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.webkit.WebView;
6 |
7 | import com.lalamove.huolala.offline.webview.proxy.IOfflineWebViewProxy;
8 | import com.lalamove.huolala.offline.webview.proxy.OffWebProxyFactory;
9 |
10 | import java.util.Map;
11 |
12 | /**
13 | * @copyright:深圳依时货拉拉科技有限公司
14 | * @fileName: OfflineWebView
15 | * @author: kelvin
16 | * @date: 7/22/21
17 | * @description: 基础webview
18 | * @history:
19 | */
20 | public class OfflineWebView extends WebView implements ReloadOfflineWebView {
21 |
22 | private IOfflineWebViewProxy mOfflineWebViewProxy;
23 |
24 | public OfflineWebView(Context context) {
25 | super(context);
26 | initProxy();
27 | }
28 |
29 | public OfflineWebView(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | initProxy();
32 | }
33 |
34 | public OfflineWebView(Context context, AttributeSet attrs, int defStyleAttr) {
35 | super(context, attrs, defStyleAttr);
36 | initProxy();
37 | }
38 |
39 | public OfflineWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
40 | super(context, attrs, defStyleAttr, defStyleRes);
41 | initProxy();
42 | }
43 |
44 | private void initProxy() {
45 | mOfflineWebViewProxy = OffWebProxyFactory.getProxy(this);
46 | }
47 |
48 | @Override
49 | public void loadUrl(String url) {
50 | super.loadUrl(mOfflineWebViewProxy.loadUrl(url));
51 | }
52 |
53 | @Override
54 | public void loadUrl(String url, Map additionalHttpHeaders) {
55 | super.loadUrl(mOfflineWebViewProxy.loadUrl(url), additionalHttpHeaders);
56 | }
57 |
58 | @Override
59 | public void reloadOfflineWeb() {
60 | // refresh this web view
61 | }
62 |
63 | @Override
64 | public void destroy() {
65 | super.destroy();
66 | mOfflineWebViewProxy.destroy();
67 | }
68 |
69 | @Override
70 | protected void onDetachedFromWindow() {
71 | super.onDetachedFromWindow();
72 | mOfflineWebViewProxy.destroy();
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/lib_offline_webview/src/main/java/com/lalamove/huolala/offline/webview/widget/ReloadOfflineWebView.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.offline.webview.widget;
2 |
3 | /**
4 | * @copyright:深圳依时货拉拉科技有限公司
5 | * @fileName: ReloadOfflineWebView
6 | * @author: kelvin
7 | * @date: 7/27/21
8 | * @description: 使用端 实现接口 支持reload
9 | * @history:
10 | */
11 |
12 | public interface ReloadOfflineWebView extends IOfflineWebView {
13 | /**
14 | * 重载webview ,只有下发强制重载才会执行,默认无操作,业务方自己实现
15 | */
16 | void reloadOfflineWeb();
17 | }
18 |
--------------------------------------------------------------------------------
/lib_web/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/lib_web/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java-library'
3 | }
4 |
5 | java {
6 | sourceCompatibility = JavaVersion.VERSION_1_8
7 | targetCompatibility = JavaVersion.VERSION_1_8
8 | }
9 | tasks.withType(JavaCompile) {
10 | options.encoding = "UTF-8"
11 | }
12 |
13 | jar {
14 | manifest {
15 | attributes 'Main-Class': 'com.lalamove.huolala.client.lib.HttpServerStarter'
16 | }
17 | }
18 |
19 | dependencies {
20 | implementation "com.google.guava:guava:28.1-android"
21 | implementation "com.google.code.gson:gson:2.8.5"
22 | }
--------------------------------------------------------------------------------
/lib_web/src/main/java/com/lalamove/huolala/client/lib/DownloadHandler.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.client.lib;
2 |
3 | import com.sun.net.httpserver.HttpExchange;
4 | import com.sun.net.httpserver.HttpHandler;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.File;
8 | import java.io.FileInputStream;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.InputStreamReader;
12 | import java.io.OutputStream;
13 | import java.nio.charset.StandardCharsets;
14 | import java.util.Map;
15 |
16 | /**
17 | * 下载处理器类
18 | */
19 | public class DownloadHandler implements HttpHandler {
20 |
21 | @Override
22 | public void handle(HttpExchange httpExchange) {
23 | try {
24 | System.out.println("DownloadHandler handle start");
25 | String requestParam = getRequestParam(httpExchange);
26 | Map paramMap = ParamsUtil.getParamMap(requestParam);
27 | String bisName = paramMap.get(ServerConstant.BIS_NAME);
28 | String zipVersion = paramMap.get(ServerConstant.PARAM_OFFLINE_ZIP_VER);
29 | File zipFile = null;
30 | System.out.println("download bisName = " + bisName);
31 | if (ServerConstant.NAME_ACT3.equals(bisName)) {
32 | zipFile = new File(ServerConstant.ACT3_PATH);
33 | }
34 | if (zipFile != null) {
35 | System.out.println("download path = " + zipFile.getAbsolutePath());
36 | }
37 | handleResponse(httpExchange, zipFile, bisName);
38 | } catch (Exception ex) {
39 | ex.printStackTrace();
40 | }
41 | }
42 |
43 | /**
44 | * 获取请求参数
45 | *
46 | * @param httpExchange
47 | * @return
48 | * @throws Exception
49 | */
50 | private String getRequestParam(HttpExchange httpExchange) throws Exception {
51 | String paramStr = "";
52 |
53 | if ("GET".equals(httpExchange.getRequestMethod())) {
54 | //GET请求读queryString
55 | paramStr = httpExchange.getRequestURI().getQuery();
56 | } else {
57 | //非GET请求读请求体
58 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpExchange.getRequestBody(), StandardCharsets.UTF_8));
59 | StringBuilder requestBodyContent = new StringBuilder();
60 | String line = "";
61 | while ((line = bufferedReader.readLine()) != null) {
62 | requestBodyContent.append(line);
63 | }
64 | paramStr = requestBodyContent.toString();
65 | }
66 |
67 | return paramStr;
68 | }
69 |
70 | /**
71 | * 处理响应
72 | *
73 | * @param httpExchange
74 | * @param file
75 | * @throws Exception
76 | */
77 | private void handleResponse(HttpExchange httpExchange, File file, String fileName) throws Exception {
78 | //设置响应头,必须在sendResponseHeaders方法之前设置!
79 | httpExchange.getResponseHeaders().add("Content-Type:", "application/vnd.ms-excel;charset=utf-8");
80 | httpExchange.getResponseHeaders().add("Content-Disposition", "attachment;filename=" + fileName + ".zip");
81 | // 设置响应码和响应体长度,必须在getResponseBody方法之前调用!
82 | if (file == null || !file.exists()) {
83 | httpExchange.sendResponseHeaders(200, 0);
84 | System.out.println("下载失败 文件无法找到");
85 | OutputStream out = httpExchange.getResponseBody();
86 | out.flush();
87 | out.close();
88 | return;
89 | }
90 | httpExchange.sendResponseHeaders(200, file.length());
91 | InputStream in = null;
92 | OutputStream out = null;
93 | try {
94 | //获取要下载的文件输入流
95 | in = new FileInputStream(file);
96 | int len = 0;
97 | //创建数据缓冲区
98 | byte[] buffer = new byte[1024];
99 | //通过response对象获取outputStream流
100 | out = httpExchange.getResponseBody();
101 | //将FileInputStream流写入到buffer缓冲区
102 | while ((len = in.read(buffer)) > 0) {
103 | //使用OutputStream将缓冲区的数据输出到浏览器
104 | out.write(buffer, 0, len);
105 | }
106 | out.flush();
107 | in.close();
108 | } catch (Exception e) {
109 | e.printStackTrace();
110 | } finally {
111 | if (out != null) {
112 | try {
113 | out.close();
114 | } catch (IOException e) {
115 | e.printStackTrace();
116 | }
117 | }
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib_web/src/main/java/com/lalamove/huolala/client/lib/HttpServerStarter.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.client.lib;
2 |
3 | import com.sun.net.httpserver.HttpServer;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 | import java.net.InetSocketAddress;
8 | import java.util.concurrent.Executors;
9 |
10 | public class HttpServerStarter {
11 |
12 | public static void main(String[] args) throws IOException {
13 | //创建一个HttpServer实例,并绑定到指定的IP地址和端口号
14 | File assetFile = new File(ServerConstant.ASSETS_PATH);
15 | if (!assetFile.exists()) {
16 | System.out.println("请配置asset目录 或者 设置asset路径");
17 | }
18 | System.out.println("ASSETS_PATH = " + ServerConstant.ASSETS_PATH);
19 | HttpServer httpServer = HttpServer.create(new InetSocketAddress(8888), 0);
20 | //创建一个HttpContext,将路径为/myserver请求映射到MyHttpHandler处理器
21 | httpServer.createContext("/"+ServerConstant.PATH_OFF_WEB, new OffWebHandler());
22 | httpServer.createContext("/"+ServerConstant.PAHT_PACKAGE, new DownloadHandler());
23 |
24 | //设置服务器的线程池对象
25 | httpServer.setExecutor(Executors.newFixedThreadPool(10));
26 |
27 | //启动服务器
28 | httpServer.start();
29 | }
30 | }
--------------------------------------------------------------------------------
/lib_web/src/main/java/com/lalamove/huolala/client/lib/OffWebHandler.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.client.lib;
2 |
3 | import com.google.gson.Gson;
4 | import com.sun.net.httpserver.HttpExchange;
5 | import com.sun.net.httpserver.HttpHandler;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.InputStreamReader;
9 | import java.io.OutputStream;
10 | import java.nio.charset.StandardCharsets;
11 | import java.util.Map;
12 |
13 | /**
14 | * 拉取离线包信息处理器类
15 | */
16 | public class OffWebHandler implements HttpHandler {
17 |
18 | private Gson mGson = new Gson();
19 |
20 | @Override
21 | public void handle(HttpExchange httpExchange) {
22 | try {
23 | String requestParam = getRequestParam(httpExchange);
24 | String bisName ="";
25 | String zipVersion ="";
26 | Map paramMap = ParamsUtil.getParamMap(requestParam);
27 | if (paramMap != null) {
28 | bisName = paramMap.get(ServerConstant.BIS_NAME);
29 | zipVersion = paramMap.get(ServerConstant.PARAM_OFFLINE_ZIP_VER);
30 | }
31 | String downloadUrl = null;
32 | if (ServerConstant.NAME_ACT3.equals(bisName)) {
33 | StringBuilder downloadSb = new StringBuilder();
34 | downloadSb.append(ServerConstant.LOCALHOST)
35 | .append(ServerConstant.PAHT_PACKAGE)
36 | .append("?")
37 | .append(ServerConstant.BIS_NAME)
38 | .append("=")
39 | .append(ServerConstant.NAME_ACT3);
40 | downloadUrl = downloadSb.toString();
41 | }
42 | //result==1
43 | OfflinePackageInfo offlinePackageInfo = new OfflinePackageInfo(bisName, 1, downloadUrl, 0, zipVersion + "_1");
44 |
45 | //result == 0 无需下载
46 | // OfflinePackageInfo offlinePackageInfo = new OfflinePackageInfo(bisName, 0, downloadUrl, 0, zipVersion + "_1");
47 | String s = mGson.toJson(offlinePackageInfo);
48 | handleResponse(httpExchange, s);
49 | } catch (Exception ex) {
50 | ex.printStackTrace();
51 | }
52 | }
53 |
54 | /**
55 | * 获取请求参数
56 | *
57 | * @param httpExchange
58 | * @return
59 | * @throws Exception
60 | */
61 | private String getRequestParam(HttpExchange httpExchange) throws Exception {
62 | String paramStr;
63 |
64 | if ("GET".equals(httpExchange.getRequestMethod())) {
65 | //GET请求读queryString
66 | paramStr = httpExchange.getRequestURI().getQuery();
67 | } else {
68 | //非GET请求读请求体
69 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpExchange.getRequestBody(), StandardCharsets.UTF_8));
70 | StringBuilder requestBodyContent = new StringBuilder();
71 | String line;
72 | while ((line = bufferedReader.readLine()) != null) {
73 | requestBodyContent.append(line);
74 | }
75 | paramStr = requestBodyContent.toString();
76 | }
77 |
78 | return paramStr;
79 | }
80 |
81 | /**
82 | * 处理响应
83 | *
84 | * @param httpExchange
85 | * @param responsetext
86 | * @throws Exception
87 | */
88 | private void handleResponse(HttpExchange httpExchange, String responsetext) throws Exception {
89 | System.out.println("resp:"+responsetext);
90 | byte[] responseContentByte = responsetext.getBytes(StandardCharsets.UTF_8);
91 | //设置响应头,必须在sendResponseHeaders方法之前设置!
92 | httpExchange.getResponseHeaders().add("Content-Type:", "application/json");
93 | //设置响应码和响应体长度,必须在getResponseBody方法之前调用!
94 | httpExchange.sendResponseHeaders(200, responseContentByte.length);
95 | OutputStream out = httpExchange.getResponseBody();
96 | out.write(responseContentByte);
97 | out.flush();
98 | out.close();
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/lib_web/src/main/java/com/lalamove/huolala/client/lib/OfflinePackageInfo.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.client.lib;
2 |
3 | import java.io.Serializable;
4 | import java.util.Objects;
5 |
6 | /**
7 | * @copyright:深圳依时货拉拉科技有限公司
8 | * @fileName: OfflinePackageInfo
9 | * @author: kelvin
10 | * @date: 7/21/21
11 | * @description: 离线包接口返回数据体
12 | * @history:
13 | */
14 |
15 | public class OfflinePackageInfo implements Serializable {
16 |
17 |
18 | /**
19 | * bisName : huoyunjie
20 | * result : 0
21 | * url : www.xxx.com
22 | * version : xxxxxx
23 | */
24 |
25 | private String bisName;
26 | private int result;
27 | private String url;
28 | private int refreshMode;
29 | private String version;
30 |
31 | public OfflinePackageInfo(String bisName, int result, String url, int refreshMode, String offlineZipVer) {
32 | this.bisName = bisName;
33 | this.result = result;
34 | this.url = url;
35 | this.refreshMode = refreshMode;
36 | this.version = offlineZipVer;
37 | }
38 |
39 | @Override
40 | public boolean equals(Object o) {
41 | if (this == o) {
42 | return true;
43 | }
44 | if (o == null || getClass() != o.getClass()) {
45 | return false;
46 | }
47 | OfflinePackageInfo that = (OfflinePackageInfo) o;
48 | return Objects.equals(bisName, that.bisName);
49 | }
50 |
51 | @Override
52 | public int hashCode() {
53 | return Objects.hash(bisName);
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | return "OfflinePackageInfo{" +
59 | "bisName='" + bisName + '\'' +
60 | ", result=" + result +
61 | ", url='" + url + '\'' +
62 | ", refreshMode=" + refreshMode +
63 | ", version='" + version + '\'' +
64 | '}';
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/lib_web/src/main/java/com/lalamove/huolala/client/lib/ParamsUtil.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.client.lib;
2 |
3 | import com.google.common.base.Splitter;
4 |
5 | import java.util.Map;
6 |
7 | /**
8 | * @copyright:深圳依时货拉拉科技有限公司
9 | * @fileName: ParamsUtil
10 | * @author: kelvin
11 | * @date: 3/30/22
12 | * @description: 参数拼接工具类
13 | * @history:
14 | */
15 |
16 | public class ParamsUtil {
17 |
18 |
19 | public static Map getParamMap(String url) {
20 | if (isEmpty(url)) {
21 | return null;
22 | }
23 | try {
24 | String params = url.substring(url.indexOf("?") + 1);
25 | return Splitter.on("&")
26 | .withKeyValueSeparator("=")
27 | .split(params);
28 | } catch (Exception e) {
29 | return null;
30 | }
31 |
32 | }
33 |
34 | private static boolean isEmpty(String str) {
35 | return str == null || str.length() == 0;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/lib_web/src/main/java/com/lalamove/huolala/client/lib/ServerConstant.java:
--------------------------------------------------------------------------------
1 | package com.lalamove.huolala.client.lib;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | * @copyright:深圳依时货拉拉科技有限公司
7 | * @fileName: ServerConstant
8 | * @author: kelvin
9 | * @date: 3/30/22
10 | * @description: 服务端配置
11 | * @history:
12 | */
13 |
14 | public interface ServerConstant {
15 |
16 |
17 | String LOCALHOST = "http://xxx.xxx.xxx.xxx:8888/";
18 |
19 | String BIS_NAME = "bisName";
20 |
21 | String PATH_OFF_WEB = "queryOffline";
22 |
23 | String PAHT_PACKAGE = "package";
24 |
25 | String PARAM_OFFLINE_ZIP_VER = "offlineZipVer";
26 |
27 | String ASSETS_PATH = new File("").getAbsolutePath()+File.separator+"assets";
28 |
29 | String NAME_ACT3 = "act3-2108-turntable";
30 |
31 | String PKG_ACT3 = "act3-2108-turntable.zip";
32 |
33 | String ACT3_PATH = ASSETS_PATH + File.separator + PKG_ACT3;
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':lib_web'
3 | include ':lib_offline_webview'
4 | rootProject.name = "OfflineDemo"
--------------------------------------------------------------------------------