Merge remote-tracking branch 'origin/master'
# Conflicts: # .idea/vcs.xml
This commit is contained in:
6
.idea/compiler.xml
generated
Normal file
6
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="1.8" />
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/gradle.xml
generated
2
.idea/gradle.xml
generated
@@ -13,10 +13,12 @@
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/foudations" />
|
||||
<option value="$PROJECT_DIR$/foudations/mogo-httpdns" />
|
||||
<option value="$PROJECT_DIR$/foudations/mogo-passport" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
36
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
36
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,36 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="TOP_LEVEL_CLASS_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="INNER_CLASS_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="METHOD_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="FIELD_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="IGNORE_DEPRECATED" value="false" />
|
||||
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
|
||||
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
|
||||
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
|
||||
<option name="myAdditionalJavadocTags" value="date" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -4,7 +4,7 @@
|
||||
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
|
||||
<groovy codeStyle="LEGACY" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
||||
135
.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]/shelved.patch
generated
Normal file
135
.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]/shelved.patch
generated
Normal file
@@ -0,0 +1,135 @@
|
||||
Index: build.gradle
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
|
||||
<+>// Top-level build file where you can add configuration options common to all sub-projects/modules.\napply from: \"config.gradle\"\n\nbuildscript {\n repositories {\n maven {\n url 'http://maven.aliyun.com/nexus/content/groups/public/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-releases/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-public/'\n }\n google()\n jcenter()\n }\n dependencies {\n classpath \"com.android.tools.build:gradle:4.0.2\"\n\n // NOTE: Do not place your application dependencies here; they belong\n // in the individual module build.gradle files\n }\n}\n\nallprojects {\n repositories {\n maven {\n url 'http://maven.aliyun.com/nexus/content/groups/public/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-releases/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-public/'\n }\n google()\n jcenter()\n }\n}\n\ntask clean(type: Delete) {\n delete rootProject.buildDir\n}
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
--- build.gradle (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff)
|
||||
+++ build.gradle (date 1611052524000)
|
||||
@@ -2,6 +2,7 @@
|
||||
apply from: "config.gradle"
|
||||
|
||||
buildscript {
|
||||
+ ext.kotlin_version = "1.3.72"
|
||||
repositories {
|
||||
maven {
|
||||
url 'http://maven.aliyun.com/nexus/content/groups/public/'
|
||||
@@ -17,6 +18,7 @@
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:4.0.2"
|
||||
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
Index: .idea/inspectionProfiles/Project_Default.xml
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
--- .idea/inspectionProfiles/Project_Default.xml (date 1611044633000)
|
||||
+++ .idea/inspectionProfiles/Project_Default.xml (date 1611044633000)
|
||||
@@ -0,0 +1,36 @@
|
||||
+<component name="InspectionProjectProfileManager">
|
||||
+ <profile version="1.0">
|
||||
+ <option name="myName" value="Project Default" />
|
||||
+ <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
+ <option name="TOP_LEVEL_CLASS_OPTIONS">
|
||||
+ <value>
|
||||
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
+ <option name="REQUIRED_TAGS" value="" />
|
||||
+ </value>
|
||||
+ </option>
|
||||
+ <option name="INNER_CLASS_OPTIONS">
|
||||
+ <value>
|
||||
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
+ <option name="REQUIRED_TAGS" value="" />
|
||||
+ </value>
|
||||
+ </option>
|
||||
+ <option name="METHOD_OPTIONS">
|
||||
+ <value>
|
||||
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
+ <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
|
||||
+ </value>
|
||||
+ </option>
|
||||
+ <option name="FIELD_OPTIONS">
|
||||
+ <value>
|
||||
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
+ <option name="REQUIRED_TAGS" value="" />
|
||||
+ </value>
|
||||
+ </option>
|
||||
+ <option name="IGNORE_DEPRECATED" value="false" />
|
||||
+ <option name="IGNORE_JAVADOC_PERIOD" value="true" />
|
||||
+ <option name="IGNORE_DUPLICATED_THROWS" value="false" />
|
||||
+ <option name="IGNORE_POINT_TO_ITSELF" value="false" />
|
||||
+ <option name="myAdditionalJavadocTags" value="date" />
|
||||
+ </inspection_tool>
|
||||
+ </profile>
|
||||
+</component>
|
||||
\ No newline at end of file
|
||||
Index: .idea/misc.xml
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
|
||||
<+><?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ASMPluginConfiguration\">\n <asm skipDebug=\"false\" skipFrames=\"false\" skipCode=\"false\" expandFrames=\"false\" />\n <groovy codeStyle=\"LEGACY\" />\n </component>\n <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_7\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\">\n <output url=\"file://$PROJECT_DIR$/build/classes\" />\n </component>\n <component name=\"ProjectType\">\n <option name=\"id\" value=\"Android\" />\n </component>\n</project>
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
--- .idea/misc.xml (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff)
|
||||
+++ .idea/misc.xml (date 1611045041000)
|
||||
@@ -4,7 +4,7 @@
|
||||
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
|
||||
<groovy codeStyle="LEGACY" />
|
||||
</component>
|
||||
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
Index: .idea/vcs.xml
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
--- .idea/vcs.xml (date 1611044633000)
|
||||
+++ .idea/vcs.xml (date 1611044633000)
|
||||
@@ -0,0 +1,6 @@
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<project version="4">
|
||||
+ <component name="VcsDirectoryMappings">
|
||||
+ <mapping directory="" vcs="Git" />
|
||||
+ </component>
|
||||
+</project>
|
||||
\ No newline at end of file
|
||||
Index: .idea/compiler.xml
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
--- .idea/compiler.xml (date 1611045041000)
|
||||
+++ .idea/compiler.xml (date 1611045041000)
|
||||
@@ -0,0 +1,6 @@
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<project version="4">
|
||||
+ <component name="CompilerConfiguration">
|
||||
+ <bytecodeTargetLevel target="1.8" />
|
||||
+ </component>
|
||||
+</project>
|
||||
\ No newline at end of file
|
||||
Index: .idea/gradle.xml
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
|
||||
<+><?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"GradleMigrationSettings\" migrationVersion=\"1\" />\n <component name=\"GradleSettings\">\n <option name=\"linkedExternalProjectsSettings\">\n <GradleProjectSettings>\n <option name=\"testRunner\" value=\"PLATFORM\" />\n <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n <option name=\"gradleJvm\" value=\"1.8\" />\n <option name=\"modules\">\n <set>\n <option value=\"$PROJECT_DIR$\" />\n <option value=\"$PROJECT_DIR$/app\" />\n <option value=\"$PROJECT_DIR$/foudations\" />\n <option value=\"$PROJECT_DIR$/foudations/mogo-passport\" />\n </set>\n </option>\n <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n </GradleProjectSettings>\n </option>\n </component>\n</project>
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
--- .idea/gradle.xml (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff)
|
||||
+++ .idea/gradle.xml (date 1611044633000)
|
||||
@@ -17,6 +17,7 @@
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
+ <option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
4
.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM__Default_Changelist_.xml
generated
Normal file
4
.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM__Default_Changelist_.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<changelist name="Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]" date="1611052761316" recycled="true" deleted="true">
|
||||
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]/shelved.patch" />
|
||||
<option name="DESCRIPTION" value="Uncommitted changes before Update at 1/19/21 6:39 PM [Default Changelist]" />
|
||||
</changelist>
|
||||
@@ -2,6 +2,7 @@
|
||||
apply from: "config.gradle"
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = "1.3.72"
|
||||
repositories {
|
||||
maven {
|
||||
url 'http://maven.aliyun.com/nexus/content/groups/public/'
|
||||
@@ -17,6 +18,7 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:4.0.2"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
1
foudations/mogo-httpdns/.gitignore
vendored
Normal file
1
foudations/mogo-httpdns/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
46
foudations/mogo-httpdns/build.gradle
Normal file
46
foudations/mogo-httpdns/build.gradle
Normal file
@@ -0,0 +1,46 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'kotlin-android'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.2"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles "consumer-rules.pro"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation 'androidx.core:core-ktx:1.3.2'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
testImplementation 'junit:junit:4.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
}
|
||||
|
||||
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()
|
||||
0
foudations/mogo-httpdns/consumer-rules.pro
Normal file
0
foudations/mogo-httpdns/consumer-rules.pro
Normal file
4
foudations/mogo-httpdns/gradle.properties
Normal file
4
foudations/mogo-httpdns/gradle.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
GROUP=com.mogo.httpdns
|
||||
POM_ARTIFACT_ID=httpdns-helper
|
||||
VERSION_CODE=1
|
||||
VERSION_NAME=1.0.18
|
||||
21
foudations/mogo-httpdns/proguard-rules.pro
vendored
Normal file
21
foudations/mogo-httpdns/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.mogo.cloud.httpdns
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.mogo.cloud.httpdns.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
7
foudations/mogo-httpdns/src/main/AndroidManifest.xml
Normal file
7
foudations/mogo-httpdns/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mogo.cloud.httpdns">
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
||||
@@ -0,0 +1,191 @@
|
||||
package com.mogo.cloud.httpdns
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.Message
|
||||
import android.util.ArrayMap
|
||||
import com.mogo.cloud.httpdns.listener.IMogoHttpDns
|
||||
import com.mogo.cloud.httpdns.listener.OnAddressChangedListener
|
||||
import com.mogo.cloud.httpdns.util.ApiManager
|
||||
import com.mogo.cloud.httpdns.util.L
|
||||
import com.mogo.cloud.httpdns.util.NetWorkUtil
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/**
|
||||
* 1. 本地每15min查询一次
|
||||
* 2. 网络状态发生变化时候,重置15min轮询,并查询一次
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
internal class HttpDnsHelper(private val builder: MogoHttpDnsConfig) : Handler.Callback,IMogoHttpDns {
|
||||
companion object {
|
||||
const val HTTP_DNS_TYPE_HTTP = 0
|
||||
const val HTTP_DNS_TYPE_WS = 1
|
||||
const val HTTP_DNS_TYPE_IM = 2
|
||||
|
||||
private const val MSG_REQUEST_IP_PORT = 1001
|
||||
|
||||
private const val TAG = "HttpDnsHelper"
|
||||
}
|
||||
|
||||
private val netWorkUtil = NetWorkUtil()
|
||||
private var localConnectStateCache = false
|
||||
private val workThread = HandlerThread("mogo-http-dns-work-thread")
|
||||
private val handler: Handler
|
||||
private var addressMap: Map<String, String>? = null
|
||||
|
||||
var addressChangedListener: OnAddressChangedListener? = null
|
||||
|
||||
private val apiManager: ApiManager
|
||||
private var isInit = false
|
||||
|
||||
private var defaultUrl: String? = null
|
||||
|
||||
init {
|
||||
L.isDebug = builder.showDebugLog()
|
||||
defaultUrl = builder.getDefaultUrl()
|
||||
L.d(TAG, "init===")
|
||||
checkParams()
|
||||
isInit = true
|
||||
L.d(TAG, "params available, prepare to start check net status")
|
||||
workThread.start()
|
||||
handler = Handler(workThread.looper, this)
|
||||
apiManager = ApiManager(builder.getSn()!!, builder.getEnv(), builder.getAppKey())
|
||||
handler.sendEmptyMessageDelayed(MSG_REQUEST_IP_PORT, builder.getLoopCheckDelay())
|
||||
netWorkUtil.registerStatusCallback(builder.getContext()!!) {
|
||||
if (it && !localConnectStateCache) {
|
||||
// 网络状态可用,且本地记录的连接状态为false,开始请求
|
||||
handler.removeMessages(MSG_REQUEST_IP_PORT)
|
||||
// 立即执行
|
||||
handler.sendEmptyMessage(MSG_REQUEST_IP_PORT)
|
||||
}
|
||||
localConnectStateCache = it
|
||||
}
|
||||
}
|
||||
|
||||
private fun getHttpDnsAddressFromNet() {
|
||||
|
||||
val nAddress = apiManager.requestHttpDns(builder.getCurrentLocation()!!)
|
||||
if (addressChangedListener == null) {
|
||||
L.d(TAG, "addressChangeList is null")
|
||||
}
|
||||
if (addressMap == null) {
|
||||
addressMap = nAddress
|
||||
addressChangedListener?.onAddressChanged(addressMap)
|
||||
} else if (nAddress != null) {
|
||||
addressChangedListener?.onAddressChanged(mapDiff(nAddress, addressMap!!))
|
||||
addressMap = nAddress
|
||||
}
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var isRequest = false
|
||||
|
||||
private val requestCache = ArrayList<String>()
|
||||
|
||||
private val requestLock = Any()
|
||||
|
||||
override fun getHttpDnsAddress(type: Int, _host: String): String? {
|
||||
val host = _host.toLowerCase(Locale.getDefault())
|
||||
if (isInit) {
|
||||
requestCache.add("$type-$host")
|
||||
synchronized(requestLock) {
|
||||
L.d(TAG, "getHttpDnsAddress: $type-$host \n thread: ${Thread.currentThread().name} isRequest: $isRequest")
|
||||
if (!isRequest) {
|
||||
isRequest = true
|
||||
L.d(TAG, "prepare to get http dns from net thread: ${Thread.currentThread().name}")
|
||||
getHttpDnsAddressFromNet()
|
||||
}
|
||||
}
|
||||
addressMap?.let {
|
||||
val builder = StringBuilder()
|
||||
for (key in it.keys) {
|
||||
builder.append(key).append(" : ").append(it[key]).append("\n")
|
||||
}
|
||||
L.d(TAG, "getHttpDnsAddress over $type-$host ${builder.toString()}")
|
||||
requestCache.remove("$type-$host")
|
||||
L.d(TAG, "requestCache.size: ${requestCache.size}")
|
||||
if (requestCache.isEmpty()) {
|
||||
isRequest = false
|
||||
}
|
||||
return if (it["$type-$host"] == null) {
|
||||
defaultUrl ?: host
|
||||
} else {
|
||||
it["$type-$host"]
|
||||
}
|
||||
}
|
||||
L.d(TAG, "getHttpDnsAddress over addressMap is null")
|
||||
} else {
|
||||
L.d(TAG, "not init over")
|
||||
throw IllegalStateException("Http dns not init")
|
||||
|
||||
}
|
||||
return defaultUrl ?: host
|
||||
}
|
||||
|
||||
override fun getHttpDnsCachedAddress(type: Int, _host: String): String? {
|
||||
val host = _host.toLowerCase(Locale.getDefault())
|
||||
L.d(TAG, "getHttpDnsCachedAddress: $type-$host")
|
||||
return addressMap?.get("$type-$host")
|
||||
}
|
||||
|
||||
override fun getAllAddress(): Map<String, String>? {
|
||||
return addressMap
|
||||
}
|
||||
|
||||
override fun handleMessage(msg: Message): Boolean {
|
||||
if (msg.what == MSG_REQUEST_IP_PORT) {
|
||||
L.d(TAG, "http dns loop check")
|
||||
if (isInit) {
|
||||
// 网络接口请求
|
||||
getHttpDnsAddressFromNet()
|
||||
handler.sendEmptyMessageDelayed(MSG_REQUEST_IP_PORT, builder.getLoopCheckDelay())
|
||||
} else {
|
||||
L.d(TAG, "not init over")
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
netWorkUtil.release()
|
||||
}
|
||||
|
||||
private fun mapDiff(new: Map<String, String>, old: Map<String, String>): Map<String, String> {
|
||||
val diff = ArrayMap<String, String>()
|
||||
for (key in new.keys) {
|
||||
if (old[key] == null) {
|
||||
diff[key] = new[key]
|
||||
} else if (old[key] != new[key]) {
|
||||
diff[key] = new[key]
|
||||
}
|
||||
}
|
||||
for (key in old.keys) {
|
||||
if (!new.containsKey(key)) {
|
||||
diff[key] = null
|
||||
}
|
||||
}
|
||||
for (i in diff.keys) {
|
||||
L.d(TAG, "diff key: $i")
|
||||
}
|
||||
return diff
|
||||
}
|
||||
|
||||
private fun checkParams(): Boolean {
|
||||
if (builder.getContext() == null) {
|
||||
L.e(TAG, "no context")
|
||||
throw IllegalArgumentException("can not find context in builder")
|
||||
}
|
||||
if (builder.getSn() == null) {
|
||||
L.e(TAG, "no sn")
|
||||
throw IllegalArgumentException("can not find sn in builder")
|
||||
}
|
||||
if (builder.getCurrentLocation() == null) {
|
||||
L.e(TAG, "no current location")
|
||||
throw IllegalArgumentException("can not find currentLocation in builder")
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.mogo.cloud.httpdns
|
||||
|
||||
import com.mogo.cloud.httpdns.listener.IMogoHttpDns
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
|
||||
object MogoHttpDnsClient : IMogoHttpDns {
|
||||
private var httpDnsHelper:HttpDnsHelper? = null
|
||||
|
||||
fun init(config: MogoHttpDnsConfig) {
|
||||
if(httpDnsHelper == null) {
|
||||
httpDnsHelper = HttpDnsHelper(config)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 先从本地缓存中根据type和host获取ip:port,如果本地缓存中没有,再通过网络获取
|
||||
*/
|
||||
fun getHttpDnsAddressUseCacheIfNecessary(type: Int, _host: String):String?{
|
||||
return getHttpDnsCachedAddress(type, _host) ?: return getHttpDnsAddress(type, _host)
|
||||
}
|
||||
|
||||
override fun getHttpDnsAddress(type: Int, _host: String): String? {
|
||||
if (httpDnsHelper == null) {
|
||||
throw IllegalStateException("MogoHttpDnsClient init error")
|
||||
}
|
||||
return httpDnsHelper!!.getHttpDnsAddress(type,_host)
|
||||
}
|
||||
|
||||
override fun getHttpDnsCachedAddress(type: Int, _host: String): String? {
|
||||
if (httpDnsHelper == null) {
|
||||
throw IllegalStateException("MogoHttpDnsClient init error")
|
||||
}
|
||||
return httpDnsHelper!!.getHttpDnsCachedAddress(type, _host)
|
||||
}
|
||||
|
||||
override fun getAllAddress(): Map<String, String>? {
|
||||
if (httpDnsHelper == null) {
|
||||
throw IllegalStateException("MogoHttpDnsClient init error")
|
||||
}
|
||||
return httpDnsHelper!!.getAllAddress()
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
if (httpDnsHelper == null) {
|
||||
throw IllegalStateException("MogoHttpDnsClient init error")
|
||||
}
|
||||
httpDnsHelper!!.release()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.mogo.cloud.httpdns
|
||||
|
||||
import android.content.Context
|
||||
import com.mogo.cloud.httpdns.listener.IHttpDnsCurrentLocation
|
||||
|
||||
class MogoHttpDnsConfig {
|
||||
|
||||
companion object{
|
||||
/**
|
||||
* 研发环境
|
||||
*/
|
||||
const val HTTP_DNS_ENV_DEV = 1
|
||||
|
||||
/**
|
||||
* 测试环境
|
||||
*/
|
||||
const val HTTP_DNS_ENV_QA = 2
|
||||
|
||||
/**
|
||||
* 演示环境
|
||||
*/
|
||||
const val HTTP_DNS_ENV_DEMO = 4
|
||||
|
||||
/**
|
||||
* 线上环境
|
||||
*/
|
||||
const val HTTP_DNS_ENV_RELEASE = 3
|
||||
}
|
||||
private var mSn: String? = null
|
||||
private var mCurrentLocation: IHttpDnsCurrentLocation? = null
|
||||
private var mShowDebugLog: Boolean = false
|
||||
private var mLoopCheckDelay: Long = 15 * 60 * 1000
|
||||
private var mContext: Context? = null
|
||||
private var mEnv = HTTP_DNS_ENV_RELEASE
|
||||
private var mDefaultUrl:String? = null
|
||||
|
||||
private var mAppKey:String? = null
|
||||
|
||||
fun setContext(context: Context): MogoHttpDnsConfig {
|
||||
mContext = context
|
||||
return this
|
||||
}
|
||||
|
||||
fun getContext(): Context? {
|
||||
return mContext
|
||||
}
|
||||
|
||||
fun setSn(sn: String): MogoHttpDnsConfig {
|
||||
mSn = sn
|
||||
return this
|
||||
}
|
||||
|
||||
fun getSn(): String? {
|
||||
return mSn
|
||||
}
|
||||
|
||||
fun setShowDebugLog(showDebugLog: Boolean): MogoHttpDnsConfig {
|
||||
mShowDebugLog = showDebugLog
|
||||
return this
|
||||
}
|
||||
|
||||
fun showDebugLog(): Boolean {
|
||||
return mShowDebugLog
|
||||
}
|
||||
|
||||
fun setLoopCheckDelay(loopCheckDelay: Long): MogoHttpDnsConfig {
|
||||
mLoopCheckDelay = loopCheckDelay
|
||||
return this
|
||||
}
|
||||
|
||||
fun getLoopCheckDelay(): Long {
|
||||
return mLoopCheckDelay
|
||||
}
|
||||
|
||||
fun setCurrentLocation(currentLocation: IHttpDnsCurrentLocation): MogoHttpDnsConfig {
|
||||
mCurrentLocation = currentLocation
|
||||
return this
|
||||
}
|
||||
|
||||
fun getCurrentLocation(): IHttpDnsCurrentLocation? {
|
||||
return mCurrentLocation
|
||||
}
|
||||
|
||||
fun setEnv(env:Int):MogoHttpDnsConfig{
|
||||
mEnv = env
|
||||
return this
|
||||
}
|
||||
|
||||
fun getEnv():Int{
|
||||
return mEnv
|
||||
}
|
||||
|
||||
fun setDefaultUrl(defaultUrl:String):MogoHttpDnsConfig{
|
||||
mDefaultUrl = defaultUrl
|
||||
return this
|
||||
}
|
||||
|
||||
fun getDefaultUrl():String?{
|
||||
return mDefaultUrl
|
||||
}
|
||||
|
||||
fun setAppKey(appKey: String): MogoHttpDnsConfig {
|
||||
mAppKey = appKey
|
||||
return this
|
||||
}
|
||||
|
||||
fun getAppKey():String{
|
||||
return mAppKey ?: ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mogo.cloud.httpdns.bean
|
||||
|
||||
/**
|
||||
* httpDns需要的定位信息,需要使用高德定位的经纬度坐标和cityCode
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
data class HttpDnsSimpleLocation(val cityCode:String,val lat:Double,val lon:Double)
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.mogo.cloud.httpdns.listener
|
||||
|
||||
import com.mogo.cloud.httpdns.bean.HttpDnsSimpleLocation
|
||||
|
||||
interface IHttpDnsCurrentLocation {
|
||||
fun getCurrentLocation(): HttpDnsSimpleLocation?
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.mogo.cloud.httpdns.listener
|
||||
|
||||
import com.mogo.cloud.httpdns.HttpDnsHelper.Companion.HTTP_DNS_TYPE_HTTP
|
||||
|
||||
interface IMogoHttpDns {
|
||||
/**
|
||||
* 根据类型和host获取IP,直接通过网络请求获取全部路由表
|
||||
* 同时多线程多次请求会忽略部分网络请求,一定程度减少接口请求次数
|
||||
*
|
||||
* @param type [HTTP_DNS_TYPE_HTTP]用于请求http接口
|
||||
* [HTTP_DNS_TYPE_WS]用于webSocket长连接
|
||||
* 若增加新类型,可自行设置
|
||||
* @return 类型对应的ip:port,不带协议头以及path,请自行补齐
|
||||
* 特别注意,若此type没有对应的ip:port,本方法会返回null
|
||||
*/
|
||||
fun getHttpDnsAddress(type: Int, _host: String): String?
|
||||
|
||||
/**
|
||||
* 根据类型和host获取本地cache的路由表
|
||||
*
|
||||
* @param type [HTTP_DNS_TYPE_HTTP]用于请求http接口
|
||||
* [HTTP_DNS_TYPE_WS]用于webSocket长连接
|
||||
* 若增加新类型,可自行设置
|
||||
*
|
||||
* @return 类型对应的ip:port,不带协议头以及path,请自行补齐
|
||||
* 特别注意,若此type没有对应的ip:port,本方法会返回null
|
||||
*/
|
||||
fun getHttpDnsCachedAddress(type: Int, _host: String): String?
|
||||
|
||||
/**
|
||||
* 获取全部路由表
|
||||
*
|
||||
* @return 返回本地缓存全部路由表,如果没有则返回null
|
||||
*/
|
||||
fun getAllAddress(): Map<String, String>?
|
||||
|
||||
fun release()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.mogo.cloud.httpdns.listener
|
||||
|
||||
interface OnAddressChangedListener {
|
||||
fun onAddressChanged(address: Map<String, String>?)
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.mogo.cloud.httpdns.util
|
||||
|
||||
import android.util.ArrayMap
|
||||
import com.mogo.cloud.httpdns.listener.IHttpDnsCurrentLocation
|
||||
import org.json.JSONObject
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
|
||||
private const val TAG = "ApiManager"
|
||||
|
||||
/**
|
||||
* 接口请求管理类
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
class ApiManager(private val sn:String,private val env:Int,private val appKey:String) {
|
||||
|
||||
fun requestHttpDns(_location: IHttpDnsCurrentLocation):Map<String,String>? {
|
||||
val location = _location.getCurrentLocation() ?: return null
|
||||
var client: HttpURLConnection? = null
|
||||
var bufferedReader: BufferedReader? = null
|
||||
try {
|
||||
client =
|
||||
URL("http://dzt.zhidaozhixing.com/yycp-httpdns-service/api/httpDns/getIpAndPort").openConnection() as HttpURLConnection
|
||||
client.requestMethod = "POST"
|
||||
client.doInput = true
|
||||
client.doOutput = true
|
||||
client.useCaches = false
|
||||
client.setRequestProperty("Content-type", "application/json")
|
||||
client.setRequestProperty("Charset", "UTF-8")
|
||||
client.setRequestProperty("app-key", appKey)
|
||||
client.readTimeout = 1000
|
||||
client.connectTimeout = 1000
|
||||
client.connect()
|
||||
val params =
|
||||
"{\"sn\":\"$sn\",\"cityCode\":\"${location.cityCode}\",\"lat\":${location.lat},\"lon\":${location.lon},\"env\":$env}"
|
||||
L.d(TAG, "params: $params")
|
||||
client.outputStream.write(params.toByteArray())
|
||||
client.outputStream.flush()
|
||||
client.outputStream.close()
|
||||
L.d(TAG, "response: ${client.responseCode}")
|
||||
bufferedReader = BufferedReader(InputStreamReader(client.inputStream))
|
||||
val builder = StringBuilder()
|
||||
while (true) {
|
||||
val line = bufferedReader.readLine()
|
||||
if (line != null) {
|
||||
builder.append(line)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
val msg = builder.toString()
|
||||
bufferedReader.close()
|
||||
client.disconnect()
|
||||
L.d(TAG, msg)
|
||||
val json = JSONObject(msg)
|
||||
val jsonArray = json.optJSONObject("result")?.optJSONArray("urls")
|
||||
jsonArray?.apply {
|
||||
val map = ArrayMap<String, String>(length())
|
||||
for (i in 0 until length()) {
|
||||
val item = optJSONObject(i)
|
||||
val type = item.optInt("type")
|
||||
val url = item.optString("url")
|
||||
val host = item.optString("domain").toLowerCase(Locale.getDefault())
|
||||
|
||||
map["$type-$host"] = url
|
||||
}
|
||||
return map
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
L.e(TAG, e.message ?: "exception===")
|
||||
bufferedReader?.close()
|
||||
client?.disconnect()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.mogo.cloud.httpdns.util
|
||||
|
||||
import android.util.Log
|
||||
|
||||
/**
|
||||
* 简单实现日志工具类
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
object L {
|
||||
var isDebug = true
|
||||
fun d(tag: String, msg: String) {
|
||||
if (isDebug) {
|
||||
Log.d(tag, msg)
|
||||
// println(msg)
|
||||
}
|
||||
}
|
||||
|
||||
fun e(tag: String, msg: String) {
|
||||
Log.e(tag, msg)
|
||||
// println(msg)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.mogo.cloud.httpdns.util
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
|
||||
private const val TAG = "NetWorkUtil"
|
||||
|
||||
/**
|
||||
* 网络状态工具类
|
||||
* 监听和获取网络状态
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
class NetWorkUtil {
|
||||
private var statusCallback: ((Boolean) -> Unit)? = null
|
||||
private var connectivityManager: ConnectivityManager? = null
|
||||
|
||||
private var context: Context? = null
|
||||
|
||||
fun registerStatusCallback(context: Context, statusCallback: (Boolean) -> Unit) {
|
||||
this.statusCallback = statusCallback
|
||||
this.context = context
|
||||
connectivityManager =
|
||||
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val intentFilter = IntentFilter()
|
||||
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
|
||||
context.registerReceiver(receiver, intentFilter)
|
||||
}
|
||||
|
||||
|
||||
private val receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
connectivityManager?.apply {
|
||||
if (activeNetworkInfo == null) {
|
||||
L.d(TAG, "activityNetworkInfo is null")
|
||||
statusCallback?.invoke(false)
|
||||
} else {
|
||||
if (activeNetworkInfo!!.type == -1) {
|
||||
L.d(TAG, "activityNetworkInfo.type == -1")
|
||||
statusCallback?.invoke(false)
|
||||
} else {
|
||||
L.d(TAG, "activityNetworkInfo.type: ${activeNetworkInfo!!.type}")
|
||||
statusCallback?.invoke(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun release() {
|
||||
context?.unregisterReceiver(receiver)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.mogo.cloud.httpdns
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
@@ -16,4 +16,10 @@ org.gradle.jvmargs=-Xmx2048m
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
android.enableJetifier=true
|
||||
|
||||
## maven 配置
|
||||
RELEASE_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-releases/
|
||||
SNAPSHOT_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-snapshots/
|
||||
USERNAME=xintai
|
||||
PASSWORD=xintai2018
|
||||
43
gradle/upload.gradle
Normal file
43
gradle/upload.gradle
Normal file
@@ -0,0 +1,43 @@
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
task loggerSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
if (plugins.hasPlugin("java-library")) {
|
||||
from sourceSets.main.java.srcDirs
|
||||
} else if (plugins.hasPlugin("com.android.library")) {
|
||||
from android.sourceSets.main.java.sourceFiles
|
||||
} else if (plugins.hasPlugin('groovy')) {
|
||||
from sourceSets.main.groovy.srcDirs
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives loggerSourcesJar
|
||||
}
|
||||
|
||||
task loggerUpload(dependsOn: [uploadArchives, loggerSourcesJar]) {
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
repositories {
|
||||
mavenDeployer {
|
||||
|
||||
println project.name
|
||||
pom.project {
|
||||
packaging = 'aar'
|
||||
groupId = GROUP
|
||||
artifactId = POM_ARTIFACT_ID
|
||||
version = VERSION_NAME
|
||||
}
|
||||
|
||||
repository(url: rootProject.RELEASE_REPOSITORY_URL) {
|
||||
authentication(userName: rootProject.USERNAME, password: rootProject.PASSWORD)
|
||||
}
|
||||
|
||||
snapshotRepository(url: rootProject.SNAPSHOT_REPOSITORY_URL) {
|
||||
authentication(userName: rootProject.USERNAME, password: rootProject.PASSWORD)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
include ':foudations:mogo-httpdns'
|
||||
include ':foudations:mogo-passport'
|
||||
include ':app'
|
||||
rootProject.name = "MoGoAiCloudSdk"
|
||||
Reference in New Issue
Block a user