带阿里标识的版本

This commit is contained in:
robin
2026-02-28 18:55:33 +08:00
parent 150799f41d
commit 5d0b7c7e91
477 changed files with 10813 additions and 4044 deletions

View File

@@ -21,4 +21,5 @@ class ExampleInstrumentedTest {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.alibaba.ams.emas.demo", appContext.packageName)
}
}
}

View File

@@ -11,7 +11,7 @@ object BatchResolveCacheHolder {
if (cacheData == null) {
batchResolveBothList.add("www.baidu.com")
batchResolveBothList.add("m.baidu.com")
batchResolveBothList.add("www.aliyun.com")
batchResolveBothList.add("www.Aliyun.com")
batchResolveBothList.add("www.taobao.com")
batchResolveBothList.add("www.163.com")
batchResolveBothList.add("www.sohu.com")
@@ -88,4 +88,5 @@ object BatchResolveCacheHolder {
jsonObject.put("auto", autoArray)
return jsonObject.toString()
}
}
}

View File

@@ -13,4 +13,5 @@ class HttpDnsApplication : Application() {
}
}
}

View File

@@ -34,4 +34,5 @@ object HttpDnsServiceHolder {
return dnsService
}
}
}

View File

@@ -48,4 +48,5 @@ class MainActivity : AppCompatActivity() {
}
}
}
}
}

View File

@@ -89,4 +89,5 @@ object PreResolveCacheHolder {
return jsonObject.toString()
}
}
}

View File

@@ -45,3 +45,4 @@ class SingleLiveData<T> : MutableLiveData<T>() {
value = null
}
}

View File

@@ -47,4 +47,5 @@ object TtlCacheHolder {
return jsonObject.toString()
}
}
}

View File

@@ -113,7 +113,7 @@ fun String?.toBlackList(): MutableList<String>? {
fun getAccountPreference(context: Context): SharedPreferences {
return context.getSharedPreferences(
"aliyun_httpdns_${BuildConfig.ACCOUNT_ID}",
"Aliyun_httpdns_${BuildConfig.ACCOUNT_ID}",
Context.MODE_PRIVATE
)
}
@@ -138,3 +138,4 @@ fun readStringFrom(streamReader: BufferedReader): StringBuilder {
}
return sb
}

View File

@@ -51,4 +51,5 @@ const val KEY_PRE_RESOLVE_HOST_LIST = "pre_resolve_host_list"
const val KEY_SDNS_GLOBAL_PARAMS = "sdns_global_params"
const val KEY_BATCH_RESOLVE_HOST_LIST = "batch_resolve_host_list"
const val KEY_BATCH_RESOLVE_HOST_LIST = "batch_resolve_host_list"

View File

@@ -52,7 +52,7 @@ class HttpURLConnectionRequest(private val context: Context, private val request
var ipURL: String? = null
dnsService?.let {
//替换为最新的api
//鏇挎崲涓烘渶鏂扮殑api
Log.d("HttpURLConnection", "start lookup $host via $resolveMethod")
var httpDnsResult = HTTPDNSResult("", null, null, null, false, false)
if (resolveMethod == "getHttpDnsResultForHostSync(String host, RequestIpType type)") {
@@ -83,7 +83,7 @@ class HttpURLConnectionRequest(private val context: Context, private val request
}
}
Log.d("HttpURLConnection", "httpdns $host 解析结果 $httpDnsResult")
Log.d("HttpURLConnection", "httpdns $host 瑙f瀽缁撴灉 $httpDnsResult")
val ipStackType = HttpDnsNetworkDetector.getInstance().getNetType(context)
val isV6 = ipStackType == NetType.v6 || ipStackType == NetType.both
val isV4 = ipStackType == NetType.v4 || ipStackType == NetType.both
@@ -104,9 +104,9 @@ class HttpURLConnectionRequest(private val context: Context, private val request
if (conn is HttpsURLConnection) {
val sslSocketFactory = TLSSNISocketFactory(conn)
// SNI场景创建SSLSocket
// SNI鍦烘櫙锛屽垱寤篠SLSocket
conn.sslSocketFactory = sslSocketFactory
// https场景,证书校验
// https鍦烘櫙锛岃瘉涔︽牎楠?
conn.hostnameVerifier = HostnameVerifier { _, session ->
val requestHost = conn.getRequestProperty("Host") ?:conn.getURL().host
HttpsURLConnection.getDefaultHostnameVerifier().verify(requestHost, session)
@@ -115,13 +115,13 @@ class HttpURLConnectionRequest(private val context: Context, private val request
val responseCode = conn.responseCode
if (needRedirect(responseCode)) {
//临时重定向和永久重定向location的大小写有区分
//涓存椂閲嶅畾鍚戝拰姘镐箙閲嶅畾鍚憀ocation鐨勫ぇ灏忓啓鏈夊尯鍒?
var location = conn.getHeaderField("Location")
if (location == null) {
location = conn.getHeaderField("location")
}
if (!(location!!.startsWith("http://") || location.startsWith("https://"))) {
//某些时候会省略host只返回后面的path所以需要补全url
//鏌愪簺鏃跺€欎細鐪佺暐host锛屽彧杩斿洖鍚庨潰鐨刾ath锛屾墍浠ラ渶瑕佽ˉ鍏rl
val originalUrl = URL(url)
location = (originalUrl.protocol + "://"
+ originalUrl.host + location)
@@ -135,4 +135,5 @@ class HttpURLConnectionRequest(private val context: Context, private val request
return code in 300..399
}
}
}

View File

@@ -8,4 +8,5 @@ import com.alibaba.ams.emas.demo.ui.resolve.Response
*/
interface IRequest {
fun get(url: String): Response
}
}

View File

@@ -74,7 +74,7 @@ import java.util.concurrent.TimeUnit
override fun lookup(hostname: String): List<InetAddress> {
Log.d(tag, "start lookup $hostname via $mResolveMethod")
val dnsService = HttpDnsServiceHolder.getHttpDnsService(mContext.get()!!)
//修改为最新的通俗易懂的api
//淇敼涓烘渶鏂扮殑閫氫織鏄撴噦鐨刟pi
var httpDnsResult: HTTPDNSResult? = null
val inetAddresses = mutableListOf<InetAddress>()
if (mResolveMethod == "getHttpDnsResultForHostSync(String host, RequestIpType type)") {
@@ -113,11 +113,11 @@ import java.util.concurrent.TimeUnit
}
}
Log.d(tag, "httpdns $hostname 解析结果 $httpDnsResult")
Log.d(tag, "httpdns $hostname 瑙f瀽缁撴灉 $httpDnsResult")
httpDnsResult?.let { processDnsResult(it, inetAddresses) }
if (inetAddresses.isEmpty()) {
Log.d(tag, "httpdns 未返回IPlocal dns")
Log.d(tag, "httpdns 鏈繑鍥濱P锛岃蛋local dns")
return Dns.SYSTEM.lookup(hostname)
}
return inetAddresses
@@ -147,3 +147,4 @@ import java.util.concurrent.TimeUnit
}
}
}

View File

@@ -7,4 +7,5 @@ class OkHttpLog: HttpLoggingInterceptor.Logger {
override fun log(message: String) {
Log.d("Okhttp", message)
}
}
}

View File

@@ -23,4 +23,5 @@ class OkHttpRequest constructor(
.use { response -> return Response(response.code, response.body?.string()) }
}
}
}

View File

@@ -80,4 +80,5 @@ class TLSSNISocketFactory(connection: HttpsURLConnection): SSLSocketFactory() {
override fun getSupportedCipherSuites(): Array<String?> {
return arrayOfNulls(0)
}
}
}

View File

@@ -175,4 +175,5 @@ class BasicSettingFragment : Fragment(), IBasicShowDialog {
_binding?.initHttpdns?.isClickable = false
})
}
}
}

View File

@@ -37,54 +37,54 @@ class BasicSettingViewModel(application: Application) : AndroidViewModel(applica
var secretKeySetByConfig = true
/**
* 是否开启鉴权模式
* 鏄惁寮€鍚壌鏉冩ā寮?
*/
var enableAuthMode = true
/**
* 是否开启加密模式
* 鏄惁寮€鍚姞瀵嗘ā寮?
*/
var enableEncryptMode = true
/**
* 是否允许过期IP
* 鏄惁鍏佽杩囨湡IP
*/
var enableExpiredIP = false
/**
* 是否开启本地缓存
* 鏄惁寮€鍚湰鍦扮紦瀛?
*/
var enableCacheIP = false
/**
* 是否允许HTTPS
* 鏄惁鍏佽HTTPS
*/
var enableHttps = false
/**
* 是否开启降级
* 鏄惁寮€鍚檷绾?
*/
var enableDegrade = false
/**
* 是否允许网络切换自动刷新
* 鏄惁鍏佽缃戠粶鍒囨崲鑷姩鍒锋柊
*/
var enableAutoRefresh = false
/**
* 是否允许打印日志
* 鏄惁鍏佽鎵撳嵃鏃ュ織
*/
var enableLog = false
/**
* 当前Region
* 褰撳墠Region
*/
var currentRegion = SingleLiveData<String>().apply {
value = ""
}
/**
* 当前超时
* 褰撳墠瓒呮椂
*/
var currentTimeout = SingleLiveData<String>().apply {
value = "2000ms"
@@ -188,7 +188,7 @@ class BasicSettingViewModel(application: Application) : AndroidViewModel(applica
}
fun setRegion() {
//弹窗选择region
//寮圭獥閫夋嫨region
showDialog?.showSelectRegionDialog()
}
@@ -253,21 +253,21 @@ class BasicSettingViewModel(application: Application) : AndroidViewModel(applica
val timeout = preferences.getInt(KEY_TIMEOUT, 2000)
val region = preferences.getString(KEY_REGION, "cn")
val enableDegradationLocalDns = preferences.getBoolean(KEY_ENABLE_DEGRADE, false);
//自定义ttl
//鑷畾涔塼tl
val ttlCacheStr = preferences.getString(KEY_TTL_CHANGER, null)
TtlCacheHolder.convertTtlCacheData(ttlCacheStr)
//IP探测
//IP鎺㈡祴
val ipRankingItemJson = preferences.getString(KEY_IP_RANKING_ITEMS, null)
//主站域名
//涓荤珯鍩熷悕
val hostListWithFixedIpJson =
preferences.getString(KEY_HOST_WITH_FIXED_IP, null)
val tagsJson = preferences.getString(KEY_TAGS, null)
//预解析
//棰勮В鏋?
val preResolveHostList = preferences.getString(KEY_PRE_RESOLVE_HOST_LIST, null)
preResolveHostList?.let { Log.d("httpdns:HttpDnsApplication", "pre resolve list: $it") }
PreResolveCacheHolder.convertPreResolveCacheData(preResolveHostList)
//批量解析
//鎵归噺瑙f瀽
val batchResolveHostList = preferences.getString(KEY_BATCH_RESOLVE_HOST_LIST, null)
BatchResolveCacheHolder.convertBatchResolveCacheData(batchResolveHostList)
@@ -358,4 +358,5 @@ class BasicSettingViewModel(application: Application) : AndroidViewModel(applica
private fun getString(resId: Int, vararg args: String): String {
return getApplication<HttpDnsApplication>().getString(resId, *args)
}
}
}

View File

@@ -14,4 +14,5 @@ interface IBasicShowDialog {
fun showAddPreResolveDialog()
fun onHttpDnsInit()
}
}

View File

@@ -91,4 +91,5 @@ class InfoFragment : Fragment() {
}
}
}

View File

@@ -16,14 +16,14 @@ import com.aliyun.ams.httpdns.demo.R
class InfoViewModel(application: Application) : AndroidViewModel(application) {
/**
* 账户ID
* 璐︽埛ID
*/
val accountId = SingleLiveData<String>().apply {
value = ""
}
/**
* 账户secret
* 璐︽埛secret
*/
val secretKey = SingleLiveData<String?>()
@@ -59,4 +59,5 @@ class InfoViewModel(application: Application) : AndroidViewModel(application) {
}
}
}

View File

@@ -42,4 +42,5 @@ class SdnsGlobalSettingActivity: AppCompatActivity() {
}
}
}

View File

@@ -52,7 +52,7 @@ class ListActivity : AppCompatActivity(), ListAdapter.OnDeleteListener {
binding.infoListToolbar.title = title
setSupportActionBar(binding.infoListToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)//添加默认的返回图标
supportActionBar?.setDisplayHomeAsUpEnabled(true)//娣诲姞榛樿鐨勮繑鍥炲浘鏍?
supportActionBar?.setHomeButtonEnabled(true)
binding.infoListView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
@@ -170,7 +170,7 @@ class ListActivity : AppCompatActivity(), ListAdapter.OnDeleteListener {
ipTypeGroup.addView(view)
view = createIpTypeRadio(this)
view.text = "自动判断IP类型"
view.text = "鑷姩鍒ゆ柇IP绫诲瀷"
view.tag = 3
ipTypeGroup.addView(view)
@@ -214,7 +214,7 @@ class ListActivity : AppCompatActivity(), ListAdapter.OnDeleteListener {
view.tag = 2
ipTypeGroup.addView(view)
view = createIpTypeRadio(this)
view.text = "自动判断IP类型"
view.text = "鑷姩鍒ゆ柇IP绫诲瀷"
view.tag = 3
ipTypeGroup.addView(view)
val builder = AlertDialog.Builder(this)
@@ -325,7 +325,7 @@ class ListActivity : AppCompatActivity(), ListAdapter.OnDeleteListener {
}
override fun onHostWithFixedIPDeleted(position: Int) {
//只能重启生效
//鍙兘閲嶅惎鐢熸晥
viewModel.onHostWithFixedIPDeleted(position)
}
@@ -349,4 +349,5 @@ class ListActivity : AppCompatActivity(), ListAdapter.OnDeleteListener {
override fun onBatchResolveDeleted(host: String, intValue: Int) {
viewModel.onBatchResolveDeleted(host, intValue)
}
}
}

View File

@@ -109,7 +109,7 @@ class ListAdapter(private val context: Context,
0 -> "IPv4"
1 -> "IPv6"
2 -> "IPv4&IPv6"
else -> "自动判断IP类型"
else -> "鑷姩鍒ゆ柇IP绫诲瀷"
}
binding.portOrTtlIndicate.text = context.getString(R.string.ip_type)
}
@@ -121,7 +121,7 @@ class ListAdapter(private val context: Context,
0 -> "IPv4"
1 -> "IPv6"
2 -> "IPv4&IPv6"
else -> "自动判断IP类型"
else -> "鑷姩鍒ゆ柇IP绫诲瀷"
}
binding.portOrTtlIndicate.text = context.getString(R.string.ip_type)
}
@@ -147,4 +147,5 @@ class ListAdapter(private val context: Context,
fun onBatchResolveDeleted(host: String, intValue: Int)
}
}
}

View File

@@ -5,4 +5,5 @@ package com.alibaba.ams.emas.demo.ui.info.list
* @date 2023/6/5
*/
data class ListItem(var type: Int, var content: String, var intValue: Int)
data class ListItem(var type: Int, var content: String, var intValue: Int)

View File

@@ -17,4 +17,5 @@ const val kListItemTypeBlackList = 0x05
const val kListItemBatchResolve = 0x06
const val kListItemTag = 0x07
const val kListItemTag = 0x07

View File

@@ -354,7 +354,7 @@ class ListViewModel(application: Application) : AndroidViewModel(application) {
}
fun onHostWithFixedIPDeleted(position: Int) {
//只能重启生效
//鍙兘閲嶅惎鐢熸晥
val deletedHost = hostFixedIpList.removeAt(position)
saveHostWithFixedIP()
}
@@ -403,4 +403,5 @@ class ListViewModel(application: Application) : AndroidViewModel(application) {
private fun getString(resId: Int, vararg args: String): String {
return getApplication<HttpDnsApplication>().getString(resId, *args)
}
}
}

View File

@@ -64,4 +64,5 @@ class BestPracticeFragment : Fragment(), IBestPracticeShowDialog {
}
builder?.show()
}
}
}

View File

@@ -10,7 +10,7 @@ import com.alibaba.ams.emas.demo.readStringFrom
import com.alibaba.sdk.android.httpdns.NetType
import com.alibaba.sdk.android.httpdns.RequestIpType
import com.alibaba.sdk.android.httpdns.net.HttpDnsNetworkDetector
import com.alibaba.sdk.android.tool.NetworkUtils
import com.Alibaba.sdk.android.tool.NetworkUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -56,7 +56,7 @@ class BestPracticeViewModel(application: Application) : AndroidViewModel(applica
val dnsService = HttpDnsServiceHolder.getHttpDnsService(getApplication())
dnsService?.let {
val httpDnsResult = dnsService.getIpsByHostAsync(host, RequestIpType.both)
Log.d("httpdns", "$host 解析结果 $httpDnsResult")
Log.d("httpdns", "$host 瑙f瀽缁撴灉 $httpDnsResult")
val ipStackType = HttpDnsNetworkDetector.getInstance().getNetType(getApplication())
val isV6 = ipStackType == NetType.v6 || ipStackType == NetType.both
val isV4 = ipStackType == NetType.v4 || ipStackType == NetType.both
@@ -75,9 +75,9 @@ class BestPracticeViewModel(application: Application) : AndroidViewModel(applica
conn.readTimeout = 30000
conn.instanceFollowRedirects = false
//设置SNI
//璁剧疆SNI
val sslSocketFactory = TLSSNISocketFactory(conn)
// SNI场景创建SSLSocket
// SNI鍦烘櫙锛屽垱寤篠SLSocket
conn.sslSocketFactory = sslSocketFactory
conn.hostnameVerifier = HostnameVerifier { _, session ->
val requestHost = conn.getRequestProperty("Host") ?: conn.url.host
@@ -85,13 +85,13 @@ class BestPracticeViewModel(application: Application) : AndroidViewModel(applica
}
val code = conn.responseCode
if (needRedirect(code)) {
//临时重定向和永久重定向location的大小写有区分
//涓存椂閲嶅畾鍚戝拰姘镐箙閲嶅畾鍚憀ocation鐨勫ぇ灏忓啓鏈夊尯鍒?
var location = conn.getHeaderField("Location")
if (location == null) {
location = conn.getHeaderField("location")
}
if (!(location!!.startsWith("http://") || location.startsWith("https://"))) {
//某些时候会省略host只返回后面的path所以需要补全url
//鏌愪簺鏃跺€欎細鐪佺暐host锛屽彧杩斿洖鍚庨潰鐨刾ath锛屾墍浠ラ渶瑕佽ˉ鍏rl
val originalUrl = URL(url)
location = (originalUrl.protocol + "://"
+ originalUrl.host + location)
@@ -123,4 +123,5 @@ class BestPracticeViewModel(application: Application) : AndroidViewModel(applica
return code in 300..399
}
}
}

View File

@@ -26,7 +26,7 @@ class HttpDnsWebviewGetActivity : AppCompatActivity() {
binding.webviewToolbar.title = getString(R.string.httpdns_webview_best_practice)
setSupportActionBar(binding.webviewToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)//添加默认的返回图标
supportActionBar?.setDisplayHomeAsUpEnabled(true)//娣诲姞榛樿鐨勮繑鍥炲浘鏍?
supportActionBar?.setHomeButtonEnabled(true)
binding.httpdnsWebview.webViewClient = object : WebViewClient() {
@@ -55,7 +55,7 @@ class HttpDnsWebviewGetActivity : AppCompatActivity() {
val contentType = urlConnection.contentType
val mimeType = contentType?.split(";")?.get(0)
if (TextUtils.isEmpty(mimeType)) {
//无mimeType得请求不拦截
//鏃爉imeType寰楄姹備笉鎷︽埅
return super.shouldInterceptRequest(view, request)
}
val charset = getCharset(contentType)
@@ -79,7 +79,7 @@ class HttpDnsWebviewGetActivity : AppCompatActivity() {
resourceResponse.setStatusCodeAndReasonPhrase(statusCode, response)
val responseHeader: MutableMap<String?, String> = HashMap()
for ((key) in headerFields) {
// HttpUrlConnection可能包含key为null的报头指向该http请求状态码
// HttpUrlConnection鍙兘鍖呭惈key涓簄ull鐨勬姤澶达紝鎸囧悜璇ttp璇锋眰鐘舵€佺爜
responseHeader[key] = httpURLConnection.getHeaderField(key)
}
resourceResponse.responseHeaders = responseHeader
@@ -156,7 +156,7 @@ class HttpDnsWebviewGetActivity : AppCompatActivity() {
return if (location != null) {
if (!(location.startsWith("http://") || location.startsWith("https://"))) {
//某些时候会省略host只返回后面的path所以需要补全url
//鏌愪簺鏃跺€欎細鐪佺暐host锛屽彧杩斿洖鍚庨潰鐨刾ath锛屾墍浠ラ渶瑕佽ˉ鍏rl
val originalUrl = URL(path)
location = (originalUrl.protocol + "://" + originalUrl.host + location)
}

View File

@@ -8,4 +8,5 @@ interface IBestPracticeShowDialog {
fun showResponseDialog( message: String)
fun showNoNetworkDialog()
}
}

View File

@@ -79,3 +79,4 @@ class SNISocketFactory(private val conn: HttpsURLConnection) : SSLSocketFactory(
}
}

View File

@@ -14,4 +14,5 @@ interface IResolveShowDialog {
fun showResolveMethodDialog()
fun showRequestNumberDialog()
}
}

View File

@@ -8,4 +8,5 @@ enum class NetRequestType {
OKHTTP,
HTTP_URL_CONNECTION
}
}

View File

@@ -68,14 +68,14 @@ class ResolveFragment : Fragment(), IResolveShowDialog {
binding.startResolve.setOnClickListener {
binding.resolveHostInputLayout.error = ""
//1. 校验域名是否填写
//1. 鏍¢獙鍩熷悕鏄惁濉啓
val host = binding.resolveHostInputLayout.editText?.text.toString()
if (TextUtils.isEmpty(host)) {
binding.resolveHostInputLayout.error = getString(R.string.resolve_host_empty)
return@setOnClickListener
}
var sdnsParams: MutableMap<String, String>? = null
//2. 校验sdns参数
//2. 鏍¢獙sdns鍙傛暟
if (viewModel.isSdns.value!!) {
val sdnsParamsStr = binding.sdnsParamsInputLayout.editText?.text.toString()
if (!TextUtils.isEmpty(sdnsParamsStr)) {
@@ -177,7 +177,7 @@ class ResolveFragment : Fragment(), IResolveShowDialog {
val builder = activity?.let { act -> AlertDialog.Builder(act) }
builder?.apply {
setTitle(R.string.select_resolve_method)
val items = arrayOf("同步方法", "异步方法", "同步非阻塞方法")
val items = arrayOf("鍚屾鏂规硶", "寮傛鏂规硶", "鍚屾闈為樆濉炴柟娉?)
val preferences = activity?.let { getAccountPreference(it) }
var resolvedMethod = preferences?.getString(KEY_RESOLVE_METHOD, "getHttpDnsResultForHostSync(String host, RequestIpType type)").toString()
@@ -229,4 +229,5 @@ class ResolveFragment : Fragment(), IResolveShowDialog {
}
builder?.show()
}
}
}

View File

@@ -149,4 +149,5 @@ class ResolveViewModel(application: Application) : AndroidViewModel(application)
}
}
}

View File

@@ -5,3 +5,4 @@ package com.alibaba.ams.emas.demo.ui.resolve
* @date 2023/6/14
*/
data class Response(val code: Int, val body: String?)

View File

@@ -8,4 +8,5 @@ enum class SchemaType {
HTTPS,
HTTP
}
}

View File

@@ -37,18 +37,18 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
/**
* 初始化方法
* 鍒濆鍖栨柟娉?
*
* @param context
* @param attrs
* @param defStyleAttr
*/
private fun init(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {
//创建辅助对象
//鍒涘缓杈呭姪瀵硅薄
val viewConfiguration = ViewConfiguration.get(context)
scaledTouchSlop = viewConfiguration.scaledTouchSlop
scroller = Scroller(context)
//1、获取配置的属性值
//1銆佽幏鍙栭厤缃殑灞炴€у€?
val typedArray = context.theme
.obtainStyledAttributes(attrs, R.styleable.SwipeLayout, defStyleAttr, 0)
try {
@@ -77,7 +77,7 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
//获取childView的个数
//鑾峰彇childView鐨勪釜鏁?
isClickable = true
var count = childCount
val measureMatchParentChildren =
@@ -173,7 +173,7 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
contentView!!.isClickable = true
}
}
//布局contentView
//甯冨眬contentView
val cRight: Int
if (contentView != null) {
contentViewLayoutParam = contentView!!.layoutParams as MarginLayoutParams?
@@ -227,7 +227,7 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
return@run
}
scrollBy(distanceX.toInt(), 0)
//越界修正
//瓒婄晫淇
if (scrollX < 0) {
scrollTo(0, 0)
} else if (scrollX > 0) {
@@ -238,7 +238,7 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
)
}
}
//当处于水平滑动时,禁止父类拦截
//褰撳浜庢按骞虫粦鍔ㄦ椂锛岀姝㈢埗绫绘嫤鎴?
if (abs(distanceX) > scaledTouchSlop) {
parent.requestDisallowInterceptTouchEvent(true)
}
@@ -261,13 +261,13 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
when (event.action) {
MotionEvent.ACTION_DOWN -> {}
MotionEvent.ACTION_MOVE -> {
//滑动时拦截点击时间
//婊戝姩鏃舵嫤鎴偣鍑绘椂闂?
if (abs(finalDistanceX) > scaledTouchSlop) {
return true
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
//滑动后不触发contentView的点击事件
//婊戝姩鍚庝笉瑙﹀彂contentView鐨勭偣鍑讳簨浠?
if (isSwiping) {
isSwiping = false
finalDistanceX = 0f
@@ -279,7 +279,7 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
}
/**
* 自动设置状态
* 鑷姩璁剧疆鐘舵€?
*
* @param result
*/
@@ -302,7 +302,7 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
}
override fun computeScroll() {
//判断Scroller是否执行完毕:
//鍒ゆ柇Scroller鏄惁鎵ц瀹屾瘯锛?
if (scroller!!.computeScrollOffset()) {
scrollTo(scroller!!.currX, scroller!!.currY)
invalidate()
@@ -310,7 +310,7 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
}
/**
* 根据当前的scrollX的值判断松开手后应处于何种状态
* 鏍规嵁褰撳墠鐨剆crollX鐨勫€煎垽鏂澗寮€鎵嬪悗搴斿浜庝綍绉嶇姸鎬?
*
* @param
* @param scrollX
@@ -321,12 +321,12 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
return mStateCache
}
if (finalDistanceX < 0) {
//关闭右边
//鍏抽棴鍙宠竟
if (scrollX > 0 && menuView != null) {
return State.CLOSE
}
} else if (finalDistanceX > 0) {
//开启右边
//寮€鍚彸杈?
if (scrollX > 0 && menuView != null) {
if (abs(menuView!!.width * fraction) < abs(scrollX)) {
return State.RIGHT_OPEN
@@ -360,4 +360,5 @@ class SwipeLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
enum class State {
RIGHT_OPEN, CLOSE
}
}
}

View File

@@ -1,138 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">阿里云HttpDNS官方Demo</string>
<string name="title_basic">基础设置</string>
<string name="title_resolve">HttpDNS解析</string>
<string name="title_best_practice">最佳实践</string>
<string name="title_info">信息</string>
<string name="app_name">闃块噷浜慔ttpDNS瀹樻柟Demo</string>
<string name="title_basic">鍩虹璁剧疆</string>
<string name="title_resolve">HttpDNS瑙f瀽</string>
<string name="title_best_practice">鏈€浣冲疄璺?/string>
<string name="title_info">淇℃伅</string>
<string name="enable_auth_mode">开启鉴权模式</string>
<string name="secret_key_location">SecretKey通过config配置</string>
<string name="enable_encrypt_mode">开启加密模式</string>
<string name="enable_expired_ip">允许过期IP</string>
<string name="enable_local_cache">开启持久化缓存IP</string>
<string name="cache_expire_time">缓存过期时间</string>
<string name="cache_expire_time_unit">缓存过期时间的单位是天.</string>
<string name="enable_https">开启HTTPS</string>
<string name="enable_downgrade">允许降级</string>
<string name="enable_network_changed_pre_resolve">网络切换自动刷新</string>
<string name="enable_httpdns_log">允许SDK打印日志</string>
<string name="timeout">超时时间</string>
<string name="init_tip">请先初始化HttpDns</string>
<string name="inited_httpdns">已经初始化</string>
<string name="enable_auth_mode">寮€鍚壌鏉冩ā寮?/string>
<string name="secret_key_location">SecretKey閫氳繃config閰嶇疆</string>
<string name="enable_encrypt_mode">寮€鍚姞瀵嗘ā寮?/string>
<string name="enable_expired_ip">鍏佽杩囨湡IP</string>
<string name="enable_local_cache">寮€鍚寔涔呭寲缂撳瓨IP</string>
<string name="cache_expire_time">缂撳瓨杩囨湡鏃堕棿</string>
<string name="cache_expire_time_unit">缂撳瓨杩囨湡鏃堕棿鐨勫崟浣嶆槸澶?</string>
<string name="enable_https">寮€鍚疕TTPS</string>
<string name="enable_downgrade">鍏佽闄嶇骇</string>
<string name="enable_network_changed_pre_resolve">缃戠粶鍒囨崲鑷姩鍒锋柊</string>
<string name="enable_httpdns_log">鍏佽SDK鎵撳嵃鏃ュ織</string>
<string name="timeout">瓒呮椂鏃堕棿</string>
<string name="init_tip">璇峰厛鍒濆鍖朒ttpDns</string>
<string name="inited_httpdns">宸茬粡鍒濆鍖?/string>
<string name="china">中国</string>
<string name="china_hk">中国香港</string>
<string name="singapore">新加坡</string>
<string name="germany">德国</string>
<string name="america">美国</string>
<string name="pre">预发</string>
<string name="china">涓浗</string>
<string name="china_hk">涓浗棣欐腐</string>
<string name="singapore">鏂板姞鍧?/string>
<string name="germany">寰峰浗</string>
<string name="america">缇庡浗</string>
<string name="pre">棰勫彂</string>
<string name="select_region">选择Region</string>
<string name="confirm">确认</string>
<string name="cancel">取消</string>
<string name="timeout_hint">请输入超时时间,毫秒为单位</string>
<string name="set_timeout">设置超时</string>
<string name="timeout_empty">超时时间为空</string>
<string name="select_region">閫夋嫨Region</string>
<string name="confirm">纭</string>
<string name="cancel">鍙栨秷</string>
<string name="timeout_hint">璇疯緭鍏ヨ秴鏃舵椂闂达紝姣涓哄崟浣?/string>
<string name="set_timeout">璁剧疆瓒呮椂</string>
<string name="timeout_empty">瓒呮椂鏃堕棿涓虹┖</string>
<string name="ip_probe_list">探测IP列表</string>
<string name="ttl_cache_list">自定义TTL缓存列表</string>
<string name="host_fixed_ip_list">主站域名列表</string>
<string name="host_black_list">域名黑名单列表</string>
<string name="sdns_global_params">自定义解析全局参数</string>
<string name="batch_resolve">批量解析域名</string>
<string name="ip_probe_list">鎺㈡祴IP鍒楄〃</string>
<string name="ttl_cache_list">鑷畾涔塗TL缂撳瓨鍒楄〃</string>
<string name="host_fixed_ip_list">涓荤珯鍩熷悕鍒楄〃</string>
<string name="host_black_list">鍩熷悕榛戝悕鍗曞垪琛?/string>
<string name="sdns_global_params">鑷畾涔夎В鏋愬叏灞€鍙傛暟</string>
<string name="batch_resolve">鎵归噺瑙f瀽鍩熷悕</string>
<string name="httpdns_sdk_version">HttpDNS版本号</string>
<string name="unknown">未知</string>
<string name="ip_stack">当前所连接网络的网络栈类型</string>
<string name="clear_host_cache">清空指定域名缓存</string>
<string name="clear_cache_hint">请输入要清空缓存的域名</string>
<string name="network_request_type">网络请求类型</string>
<string name="async_resolve">异步解析获取IP</string>
<string name="sdns_resolve">自定义域名解析</string>
<string name="ip_type">要解析的IP类型</string>
<string name="resolve_method">使用的解析方法</string>
<string name="request_num">并发请求次数</string>
<string name="httpdns_sdk_version">HttpDNS鐗堟湰鍙?/string>
<string name="unknown">鏈煡</string>
<string name="ip_stack">褰撳墠鎵€杩炴帴缃戠粶鐨勭綉缁滄爤绫诲瀷</string>
<string name="clear_host_cache">娓呯┖鎸囧畾鍩熷悕缂撳瓨</string>
<string name="clear_cache_hint">璇疯緭鍏ヨ娓呯┖缂撳瓨鐨勫煙鍚?/string>
<string name="network_request_type">缃戠粶璇锋眰绫诲瀷</string>
<string name="async_resolve">寮傛瑙f瀽鑾峰彇IP</string>
<string name="sdns_resolve">鑷畾涔夊煙鍚嶈В鏋?/string>
<string name="ip_type">瑕佽В鏋愮殑IP绫诲瀷</string>
<string name="resolve_method">浣跨敤鐨勮В鏋愭柟娉?/string>
<string name="request_num">骞跺彂璇锋眰娆℃暟</string>
<string name="select_resolve_ip_type">选择IP类型</string>
<string name="select_resolve_method">选择解析方法</string>
<string name="select_request_num">选择并发请求次数</string>
<string name="auto_get_ip_type">自动判断IP类型</string>
<string name="add_pre_resolve">添加预解析域名</string>
<string name="add_pre_resolve_hint">请输入要预解析的域名</string>
<string name="pre_resolve_list">预解析域名列表</string>
<string name="add_tag">添加Tag</string>
<string name="pre_resolve_host_duplicate">%s域名已经被添加至预解析列表,请勿重复添加</string>
<string name="init_httpdns">初始化HttpDns</string>
<string name="batch_resolve_list">批量解析域名列表</string>
<string name="add_batch_resolve_hint">请输入要批量解析的域名</string>
<string name="add_batch_resolve">请输入要批量解析的域名</string>
<string name="batch_resolve_host_duplicate">%s域名已经被添加至批量解析列表,请勿重复添加</string>
<string name="select_resolve_ip_type">閫夋嫨IP绫诲瀷</string>
<string name="select_resolve_method">閫夋嫨瑙f瀽鏂规硶</string>
<string name="select_request_num">閫夋嫨骞跺彂璇锋眰娆℃暟</string>
<string name="auto_get_ip_type">鑷姩鍒ゆ柇IP绫诲瀷</string>
<string name="add_pre_resolve">娣诲姞棰勮В鏋愬煙鍚?/string>
<string name="add_pre_resolve_hint">璇疯緭鍏ヨ棰勮В鏋愮殑鍩熷悕</string>
<string name="pre_resolve_list">棰勮В鏋愬煙鍚嶅垪琛?/string>
<string name="add_tag">娣诲姞Tag</string>
<string name="pre_resolve_host_duplicate">%s鍩熷悕宸茬粡琚坊鍔犺嚦棰勮В鏋愬垪琛紝璇峰嬁閲嶅娣诲姞</string>
<string name="init_httpdns">鍒濆鍖朒ttpDns</string>
<string name="batch_resolve_list">鎵归噺瑙f瀽鍩熷悕鍒楄〃</string>
<string name="add_batch_resolve_hint">璇疯緭鍏ヨ鎵归噺瑙f瀽鐨勫煙鍚?/string>
<string name="add_batch_resolve">璇疯緭鍏ヨ鎵归噺瑙f瀽鐨勫煙鍚?/string>
<string name="batch_resolve_host_duplicate">%s鍩熷悕宸茬粡琚坊鍔犺嚦鎵归噺瑙f瀽鍒楄〃锛岃鍕块噸澶嶆坊鍔?/string>
<string name="host">域名:</string>
<string name="port">端口:</string>
<string name="ttl">TTL时长: </string>
<string name="host">鍩熷悕锛?/string>
<string name="port">绔彛锛?/string>
<string name="ttl">TTL鏃堕暱: </string>
<string name="add_host_fixed_ip_hint">请输入主站域名</string>
<string name="add_host_fixed_ip">添加主站域名</string>
<string name="host_fixed_ip_empty">主站域名为空</string>
<string name="host_fixed_ip_duplicate">%s主站域名已经被添加,请勿重复添加</string>
<string name="add_host_fixed_ip_hint">璇疯緭鍏ヤ富绔欏煙鍚?/string>
<string name="add_host_fixed_ip">娣诲姞涓荤珯鍩熷悕</string>
<string name="host_fixed_ip_empty">涓荤珯鍩熷悕涓虹┖</string>
<string name="host_fixed_ip_duplicate">%s涓荤珯鍩熷悕宸茬粡琚坊鍔狅紝璇峰嬁閲嶅娣诲姞</string>
<string name="add_tag_hint">请输入标签</string>
<string name="add_tag_hint">璇疯緭鍏ユ爣绛?/string>
<string name="add_host_to_black_list_hint">请输入不使用HttpDns解析的域名</string>
<string name="add_host_to_black_list">添加不使用HttpDns的域名</string>
<string name="host_to_black_list_empty">域名为空</string>
<string name="host_black_list_duplicate">%s域名已经在黑名单中,请勿重复添加</string>
<string name="add_host_to_black_list_hint">璇疯緭鍏ヤ笉浣跨敤HttpDns瑙瀽鐨勫煙鍚?/string>
<string name="add_host_to_black_list">娣诲姞涓嶄娇鐢℉ttpDns鐨勫煙鍚?/string>
<string name="host_to_black_list_empty">鍩熷悕涓虹┖</string>
<string name="host_black_list_duplicate">%s鍩熷悕宸茬粡鍦ㄩ粦鍚嶅崟涓紝璇峰嬁閲嶅娣诲姞</string>
<string name="add_ip_probe_host_hint">请输入探测IP的域名</string>
<string name="add_ip_probe_port_hint">请输入探测IP的端口</string>
<string name="add_ip_probe">添加IP探测</string>
<string name="port_is_empty">端口号为空</string>
<string name="ip_probe_item_duplicate">%s:%s已经被添加至IP探测列表请勿重复添加</string>
<string name="add_ip_probe_host_hint">璇疯緭鍏ユ帰娴婭P鐨勫煙鍚?/string>
<string name="add_ip_probe_port_hint">璇疯緭鍏ユ帰娴婭P鐨勭鍙?/string>
<string name="add_ip_probe">娣诲姞IP鎺㈡祴</string>
<string name="port_is_empty">绔彛鍙蜂负绌?/string>
<string name="ip_probe_item_duplicate">%s:%s宸茬粡琚坊鍔犺嚦IP鎺㈡祴鍒楄〃锛岃鍕块噸澶嶆坊鍔?/string>
<string name="host_is_empty">域名为空</string>
<string name="pre_resolve_host_is_empty">预解析的域名为空</string>
<string name="batch_resolve_host_is_empty">批量解析的域名为空</string>
<string name="host_is_empty">鍩熷悕涓虹┖</string>
<string name="pre_resolve_host_is_empty">棰勮В鏋愮殑鍩熷悕涓虹┖</string>
<string name="batch_resolve_host_is_empty">鎵归噺瑙f瀽鐨勫煙鍚嶄负绌?/string>
<string name="add_ttl_host_hint">请输入缓存的域名</string>
<string name="add_ttl_ttl_hint">请输入缓存的ttl时间单位</string>
<string name="add_custom_ttl">添加自定义TTL</string>
<string name="ttl_is_empty">TTL时间为空</string>
<string name="ttl_is_not_number">请输入正确格式的TTL时长</string>
<string name="add_ttl_host_hint">璇疯緭鍏ョ紦瀛樼殑鍩熷悕</string>
<string name="add_ttl_ttl_hint">璇疯緭鍏ョ紦瀛樼殑ttl鏃堕棿锛屽崟浣嶏細绉?/string>
<string name="add_custom_ttl">娣诲姞鑷畾涔塗TL</string>
<string name="ttl_is_empty">TTL鏃堕棿涓虹┖</string>
<string name="ttl_is_not_number">璇疯緭鍏ユ纭牸寮忕殑TTL鏃堕暱</string>
<string name="delete">删除</string>
<string name="clear_all_cache">清除所有HttpDNS配置缓存</string>
<string name="all_cache_cleared">所有HttpDNS配置缓存都已清除</string>
<string name="clear_dns_cache">清空Dns缓存500次</string>
<string name="delete">鍒犻櫎</string>
<string name="clear_all_cache">娓呴櫎鎵€鏈塇ttpDNS閰嶇疆缂撳瓨</string>
<string name="all_cache_cleared">鎵€鏈塇ttpDNS閰嶇疆缂撳瓨閮藉凡娓呴櫎</string>
<string name="clear_dns_cache">娓呯┖Dns缂撳瓨锛?00娆★級</string>
<string name="input_the_sdns_params">自定义解析的参数</string>
<string name="input_the_sdns_params_help_text">json对象格式</string>
<string name="input_the_sdns_params_error">自定义解析的参数必须是json对象</string>
<string name="input_the_sdns_params">鑷畾涔夎В鏋愮殑鍙傛暟</string>
<string name="input_the_sdns_params_help_text">json瀵硅薄鏍煎紡</string>
<string name="input_the_sdns_params_error">鑷畾涔夎В鏋愮殑鍙傛暟蹇呴』鏄痡son瀵硅薄</string>
<string name="input_the_sdns_cache_key">自定义解析的cache key</string>
<string name="input_the_sdns_cache_key_help_text">Cache key用于唯一标识缓存中的解析结果</string>
<string name="input_the_sdns_cache_key">鑷畾涔夎В鏋愮殑cache key</string>
<string name="input_the_sdns_cache_key_help_text">Cache key鐢ㄤ簬鍞竴鏍囪瘑缂撳瓨涓殑瑙f瀽缁撴灉</string>
<string name="input_the_resolve_host">要解析的域名</string>
<string name="input_the_resolve_host_help_text">例如help.aliyun.com</string>
<string name="input_the_request_api">要请求的接口</string>
<string name="input_the_request_api_help_text">例如: /document_detail/434554.html</string>
<string name="input_the_resolve_host">瑕佽В鏋愮殑鍩熷悕</string>
<string name="input_the_resolve_host_help_text">渚嬪锛歨elp.aliyun.com</string>
<string name="input_the_request_api">瑕佽姹傜殑鎺ュ彛</string>
<string name="input_the_request_api_help_text">渚嬪: /document_detail/434554.html</string>
<string name="resolve_and_request">解析并请求</string>
<string name="resolve_host_empty">域名不能为空</string>
<string name="host_is_ip">域名不能是IP地址</string>
<string name="host_illegal">请输入正确格式的域名</string>
<string name="schema_type">Schema类型</string>
<string name="httpdns_webview_best_practice">HttpDNS WebView 拦截GET请求</string>
<string name="httpdns_webview_post_best_practice">HttpDNS WebView POST请求通过Native发送</string>
<string name="httpdns_sni">HttpDNS IP直连方案</string>
<string name="resolve_and_request">瑙f瀽骞惰姹?/string>
<string name="resolve_host_empty">鍩熷悕涓嶈兘涓虹┖</string>
<string name="host_is_ip">鍩熷悕涓嶈兘鏄疘P鍦板潃</string>
<string name="host_illegal">璇疯緭鍏ユ纭牸寮忕殑鍩熷悕</string>
<string name="schema_type">Schema绫诲瀷</string>
<string name="httpdns_webview_best_practice">HttpDNS WebView 鎷︽埅GET璇锋眰</string>
<string name="httpdns_webview_post_best_practice">HttpDNS WebView POST璇锋眰閫氳繃Native鍙戦€?/string>
<string name="httpdns_sni">HttpDNS IP鐩磋繛鏂规</string>
<string name="ok">好的</string>
<string name="response_title">请求结果</string>
<string name="body_large_see_log">Body请通过日志查看关键字为httpdns</string>
<string name="sni_request">IP直连方案</string>
<string name="ok">濂界殑</string>
<string name="response_title">璇锋眰缁撴灉</string>
<string name="body_large_see_log">Body璇烽€氳繃鏃ュ織鏌ョ湅锛屽叧閿瓧涓篽ttpdns</string>
<string name="sni_request">IP鐩磋繛鏂规</string>
<string name="tips">提示</string>
<string name="network_not_connect">网络未连接,请检查网络</string>
<string name="request_exception">请求异常: %s</string>
<string name="tips">鎻愮ず</string>
<string name="network_not_connect">缃戠粶鏈繛鎺ワ紝璇锋鏌ョ綉缁?/string>
<string name="request_exception">璇锋眰寮傚父: %s</string>
</resources>

View File

@@ -14,4 +14,5 @@ class ExampleUnitTest {
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
}