Skip to content

Commit e01691c

Browse files
wintmainwosys
authored andcommitted
[wNet][feat]Add net sample
1 parent 790710f commit e01691c

File tree

141 files changed

+6303
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+6303
-3
lines changed

app-catalog/samples/wNet/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# wNet
2+
3+
这个模块是集成网络库以及其使用。
4+
5+
Original Link:https://github.com/liangjingkanji/Net
6+
7+
[回到主页](../../../README.md)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2023-2025 wintmain
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
plugins {
18+
id("com.android.library")
19+
id("org.jetbrains.kotlin.android")
20+
id("com.google.devtools.ksp")
21+
id("kotlin-kapt")
22+
}
23+
24+
android {
25+
namespace = "com.wintmain.wNet"
26+
compileSdk = 35
27+
28+
defaultConfig {
29+
// sub模块只需要指定最小的sdk即可
30+
minSdk = 26
31+
}
32+
33+
buildFeatures {
34+
dataBinding = true
35+
}
36+
37+
compileOptions {
38+
sourceCompatibility = JavaVersion.VERSION_17
39+
targetCompatibility = JavaVersion.VERSION_17
40+
}
41+
kotlinOptions {
42+
jvmTarget = "17"
43+
}
44+
45+
composeOptions {
46+
kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
47+
}
48+
}
49+
50+
dependencies {
51+
val composeBom = platform(libs.compose.bom)
52+
implementation(composeBom)
53+
androidTestImplementation(composeBom)
54+
55+
implementation(libs.casa.base)
56+
ksp(libs.casa.processor)
57+
58+
implementation(libs.hilt.android)
59+
ksp(libs.hilt.compiler)
60+
61+
implementation(libs.androidx.coreExtkt)
62+
implementation(libs.compose.foundation.foundation)
63+
implementation(libs.compose.ui.ui)
64+
implementation(libs.compose.material.material3)
65+
66+
// [customize] - 将common的依赖放到这里
67+
implementation(libs.androidx.appcompat)
68+
implementation(libs.material)
69+
70+
// Add from here
71+
implementation(libs.androidx.coreExtkt)
72+
implementation(libs.androidx.constraintlayout)
73+
implementation(libs.androidx.legacy.support.v4)
74+
implementation(libs.androidx.recyclerview)
75+
implementation(libs.material)
76+
implementation(libs.androidx.navigation.fragment.ktx)
77+
implementation(libs.androidx.navigation.ui.ktx)
78+
79+
// ------------------------------网络请求-------------------------------------
80+
implementation(project(":app-catalog:samples:wNet:libwNet"))
81+
implementation(libs.glide)
82+
// ------------------------------JSON解析-------------------------------------
83+
implementation(libs.kotlinx.serialization.json) // JSON序列化库, 首选推荐使用
84+
implementation(libs.kotlinx.serialization.protobuf) // protobuf序列化
85+
implementation("com.squareup.moshi:moshi-kotlin:1.14.0") // JSON序列化库, 强校验, JSON字段缺失会导致解析异常, 故不推荐
86+
implementation(libs.kotlin.reflect.v2021)
87+
implementation(libs.gson) // JSON序列化库, 会导致kotlin默认值无效, 故不推荐
88+
implementation("com.alibaba:fastjson:1.2.73") // JSON序列化库, 会导致kotlin默认值无效(除非引入kt-reflect), 不推荐
89+
// ------------------------------其他库-------------------------------------
90+
implementation("com.github.liangjingkanji:StatusBar:2.0.2") // 透明状态栏
91+
implementation("com.github.liangjingkanji:debugkit:1.3.0") // 开发调试窗口工具
92+
implementation("com.github.liangjingkanji:Tooltip:1.2.2") // 吐司工具
93+
implementation("com.github.liangjingkanji:Engine:0.0.74")
94+
implementation("com.github.liangjingkanji:Serialize:3.0.1")
95+
implementation("com.github.liangjingkanji:BRV:1.5.2") // 提供自动分页/缺省页/自动下拉刷新功能
96+
implementation("com.github.chuckerteam.chucker:library:3.5.2") // 通知栏监听网络日志
97+
implementation("com.squareup.okhttp3:mockwebserver:4.10.0")
98+
//debugImplementation("com.squareup.leakcanary:leakcanary-android:2.12")
99+
}

app-catalog/samples/wNet/libwNet/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
<uses-permission android:name="android.permission.INTERNET" />
2222

23-
<application android:networkSecurityConfig="@xml/network_security_config"
23+
<application
24+
android:networkSecurityConfig="@xml/network_security_config"
2425
tools:targetApi="n">
2526
<provider
2627
android:name="androidx.startup.InitializationProvider"

app-catalog/samples/wNet/libwNet/src/main/java/lib/wintmain/libwNet/cookie/PersistentCookieJar.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package lib.wintmain.libwNet.cookie
1818

19+
import android.annotation.SuppressLint
1920
import android.content.ContentValues
2021
import android.content.Context
2122
import android.database.sqlite.SQLiteDatabase
@@ -62,6 +63,7 @@ class PersistentCookieJar(
6263
/**
6364
* 获取指定域名下的所有Cookie
6465
*/
66+
@SuppressLint("Range")
6567
fun getAll(url: HttpUrl): List<Cookie> {
6668
val db = sqlHelper.writableDatabase
6769
db.rawQuery("SELECT * FROM cookies WHERE url = ?", arrayOf(url.host)).use { cursor ->

app-catalog/samples/wNet/libwNet/src/main/java/lib/wintmain/libwNet/utils/NetUtils.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,22 @@
1616

1717
package lib.wintmain.libwNet.utils
1818

19+
import android.Manifest.permission
1920
import android.content.Context
2021
import android.net.ConnectivityManager
2122
import android.net.NetworkCapabilities
22-
import android.os.Build
23+
import android.os.Build.VERSION
24+
import android.os.Build.VERSION_CODES
25+
import androidx.annotation.RequiresPermission
2326

2427
/**
2528
* 是否处于联网中
2629
*/
30+
@RequiresPermission(permission.ACCESS_NETWORK_STATE)
2731
fun Context.isNetworking(): Boolean {
2832
val connectivityManager =
2933
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
30-
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
34+
return if (VERSION.SDK_INT >= VERSION_CODES.M) {
3135
val networkCapabilities = connectivityManager.activeNetwork ?: return false
3236
val actNw = connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
3337
when {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<!--
4+
~ Copyright 2023-2025 wintmain
5+
~
6+
~ Licensed under the Apache License, Version 2.0 (the "License");
7+
~ you may not use this file except in compliance with the License.
8+
~ You may obtain a copy of the License at
9+
~
10+
~ https://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
19+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
20+
package="com.wintmain.wNet">
21+
22+
<queries>
23+
<intent>
24+
<action android:name="android.intent.action.PICK" />
25+
<data android:mimeType="image/*" />
26+
</intent>
27+
</queries>
28+
<application>
29+
<activity
30+
android:name=".WNetMainActivity"
31+
android:exported="true"
32+
android:theme="@style/Theme.AppCompat.DayNight" />
33+
<activity
34+
android:name=".ui.activity.MainActivity"
35+
android:exported="true"
36+
android:theme="@style/Theme.AppCompat.DayNight" />
37+
</application>
38+
</manifest>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright 2023-2025 wintmain
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.wintmain.wNet
18+
19+
import android.content.Intent
20+
import android.os.Bundle
21+
import androidx.appcompat.app.AppCompatActivity
22+
import com.chuckerteam.chucker.api.ChuckerCollector
23+
import com.chuckerteam.chucker.api.ChuckerInterceptor
24+
import com.drake.brv.utils.BRV
25+
import com.drake.statelayout.StateConfig
26+
import com.drake.tooltip.dialog.BubbleDialog
27+
import com.google.android.catalog.framework.annotations.Sample
28+
import com.scwang.smart.refresh.footer.ClassicsFooter
29+
import com.scwang.smart.refresh.header.MaterialHeader
30+
import com.scwang.smart.refresh.layout.SmartRefreshLayout
31+
import com.wintmain.wNet.converter.SerializationConverter
32+
import com.wintmain.wNet.interceptor.GlobalHeaderInterceptor
33+
import com.wintmain.wNet.mock.MockDispatcher
34+
import lib.wintmain.libwNet.NetConfig
35+
import lib.wintmain.libwNet.cookie.PersistentCookieJar
36+
import lib.wintmain.libwNet.interceptor.LogRecordInterceptor
37+
import lib.wintmain.libwNet.okhttp.setConverter
38+
import lib.wintmain.libwNet.okhttp.setDebug
39+
import lib.wintmain.libwNet.okhttp.setDialogFactory
40+
import lib.wintmain.libwNet.okhttp.setRequestInterceptor
41+
import okhttp3.Cache
42+
import java.util.concurrent.TimeUnit
43+
44+
@Sample(
45+
name = "wNet",
46+
description = "网络库例子",
47+
documentation = "",
48+
tags = ["A-Self_demos", "wNet"]
49+
)
50+
class WNetMainActivity : AppCompatActivity() {
51+
override fun onCreate(savedInstanceState: Bundle?) {
52+
super.onCreate(savedInstanceState)
53+
54+
NetConfig.initialize(com.wintmain.wNet.constants.Api.HOST, this) {
55+
56+
// 超时设置
57+
connectTimeout(30, TimeUnit.SECONDS)
58+
readTimeout(30, TimeUnit.SECONDS)
59+
writeTimeout(30, TimeUnit.SECONDS)
60+
61+
// 本框架支持Http缓存协议和强制缓存模式
62+
cache(Cache(cacheDir, 1024 * 1024 * 128)) // 缓存设置, 当超过maxSize最大值会根据最近最少使用算法清除缓存来限制缓存大小
63+
64+
// LogCat是否输出异常日志, 异常日志可以快速定位网络请求错误
65+
setDebug(true)
66+
67+
// AndroidStudio OkHttp Profiler 插件输出网络日志
68+
addInterceptor(LogRecordInterceptor(true))
69+
70+
// 添加持久化Cookie管理
71+
cookieJar(PersistentCookieJar(applicationContext))
72+
73+
// 仅开发模式启用通知栏监听网络日志, 该框架存在下载大文件时内存溢出崩溃请等待官方修复 https://github.com/ChuckerTeam/chucker/issues/1068
74+
addInterceptor(
75+
ChuckerInterceptor.Builder(applicationContext)
76+
.collector(ChuckerCollector(applicationContext))
77+
.maxContentLength(250000L)
78+
.redactHeaders(emptySet())
79+
.alwaysReadResponseBody(false)
80+
.build()
81+
)
82+
83+
// 添加请求拦截器, 可配置全局/动态参数
84+
setRequestInterceptor(GlobalHeaderInterceptor())
85+
86+
// 数据转换器
87+
setConverter(SerializationConverter())
88+
89+
// 自定义全局加载对话框
90+
setDialogFactory {
91+
BubbleDialog(it, "加载中....")
92+
}
93+
}
94+
95+
MockDispatcher.initialize()
96+
97+
initializeView()
98+
}
99+
100+
/** 初始化第三方依赖库库 */
101+
private fun initializeView() {
102+
103+
// 全局缺省页配置 [https://github.com/liangjingkanji/StateLayout]
104+
StateConfig.apply {
105+
emptyLayout = R.layout.layout_empty
106+
loadingLayout = R.layout.layout_loading
107+
errorLayout = R.layout.layout_error
108+
setRetryIds(R.id.iv)
109+
}
110+
111+
// 初始化SmartRefreshLayout, 这是自动下拉刷新和上拉加载采用的第三方库 [https://github.com/scwang90/SmartRefreshLayout/tree/master] V2版本
112+
SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, _ ->
113+
MaterialHeader(context)
114+
}
115+
116+
SmartRefreshLayout.setDefaultRefreshFooterCreator { context, _ ->
117+
ClassicsFooter(context)
118+
}
119+
120+
BRV.modelId = BR.m
121+
122+
val intent = Intent().apply {
123+
setClassName("com.wintmain.catalog.app", "com.wintmain.wNet.ui.activity.MainActivity")
124+
}
125+
startActivity(intent)
126+
}
127+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2023-2025 wintmain
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.wintmain.wNet.constants
18+
19+
/*
20+
建议请求路径都写在一个单例类中, 方便查找和替换
21+
*/
22+
object Api {
23+
const val HOST = "http://127.0.0.1:8091"
24+
25+
const val TEXT = "/text"
26+
const val DELAY = "/delay"
27+
const val UPLOAD = "/upload"
28+
const val GAME = "/game"
29+
const val DATA = "/data"
30+
const val ARRAY = "/array"
31+
const val CONFIG = "/config"
32+
const val USER_INFO = "/userInfo"
33+
const val TIME = "/time"
34+
const val Token = "/token"
35+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2023-2025 wintmain
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.wintmain.wNet.constants
18+
19+
import com.drake.serialize.serialize.annotation.SerializeConfig
20+
import com.drake.serialize.serialize.serialLazy
21+
22+
/**
23+
* 本单例类使用 https://github.com/liangjingkanji/Serialize 为字段提供持久化存储
24+
*/
25+
@SerializeConfig(mmapID = "user_config")
26+
object UserConfig {
27+
28+
var token by serialLazy(default = "6cad0ff06f5a214b9cfdf2a4a7c432339")
29+
30+
var isLogin by serialLazy(default = false)
31+
}

0 commit comments

Comments
 (0)