diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 7b384f8..1634ba9 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -13,10 +13,12 @@ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..6560a98 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,36 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 2def6b1..71e2a77 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,7 @@ - + diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]/shelved.patch b/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]/shelved.patch new file mode 100644 index 0000000..3f7f2e1 --- /dev/null +++ b/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]/shelved.patch @@ -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 @@ ++ ++ ++ ++ +\ No newline at end of file +Index: .idea/misc.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP +<+>\n\n \n \n \n \n \n \n \n \n \n +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- .idea/misc.xml (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff) ++++ .idea/misc.xml (date 1611045041000) +@@ -4,7 +4,7 @@ + + + +- ++ + + + +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 @@ ++ ++ ++ ++ ++ ++ +\ 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 @@ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +Index: .idea/gradle.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP +<+>\n\n \n \n \n \n +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- .idea/gradle.xml (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff) ++++ .idea/gradle.xml (date 1611044633000) +@@ -17,6 +17,7 @@ + + + + diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM__Default_Changelist_.xml b/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM__Default_Changelist_.xml new file mode 100644 index 0000000..bb9b9db --- /dev/null +++ b/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM__Default_Changelist_.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 16f50ab..603921c 100644 --- a/build.gradle +++ b/build.gradle @@ -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 diff --git a/foudations/mogo-httpdns/.gitignore b/foudations/mogo-httpdns/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/foudations/mogo-httpdns/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/foudations/mogo-httpdns/build.gradle b/foudations/mogo-httpdns/build.gradle new file mode 100644 index 0000000..7617ac7 --- /dev/null +++ b/foudations/mogo-httpdns/build.gradle @@ -0,0 +1,44 @@ +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' +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/consumer-rules.pro b/foudations/mogo-httpdns/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/foudations/mogo-httpdns/proguard-rules.pro b/foudations/mogo-httpdns/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/foudations/mogo-httpdns/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/androidTest/java/com/mogo/cloud/httpdns/ExampleInstrumentedTest.kt b/foudations/mogo-httpdns/src/androidTest/java/com/mogo/cloud/httpdns/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..65c0ee4 --- /dev/null +++ b/foudations/mogo-httpdns/src/androidTest/java/com/mogo/cloud/httpdns/ExampleInstrumentedTest.kt @@ -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) + } +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/AndroidManifest.xml b/foudations/mogo-httpdns/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7e2eddd --- /dev/null +++ b/foudations/mogo-httpdns/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/HttpDnsHelper.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/HttpDnsHelper.kt new file mode 100644 index 0000000..917d86a --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/HttpDnsHelper.kt @@ -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? = 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() + + 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? { + 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, old: Map): Map { + val diff = ArrayMap() + 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 + } +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/MogoHttpDnsClient.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/MogoHttpDnsClient.kt new file mode 100644 index 0000000..9a5ed7a --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/MogoHttpDnsClient.kt @@ -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? { + if (httpDnsHelper == null) { + throw IllegalStateException("MogoHttpDnsClient init error") + } + return httpDnsHelper!!.getAllAddress() + } + + override fun release() { + if (httpDnsHelper == null) { + throw IllegalStateException("MogoHttpDnsClient init error") + } + httpDnsHelper!!.release() + } + + +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/MogoHttpDnsConfig.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/MogoHttpDnsConfig.kt new file mode 100644 index 0000000..1cc19c7 --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/MogoHttpDnsConfig.kt @@ -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 ?: "" + } +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/bean/HttpDnsSimpleLocation.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/bean/HttpDnsSimpleLocation.kt new file mode 100644 index 0000000..5c2606e --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/bean/HttpDnsSimpleLocation.kt @@ -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) \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/IHttpDnsCurrentLocation.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/IHttpDnsCurrentLocation.kt new file mode 100644 index 0000000..03cee66 --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/IHttpDnsCurrentLocation.kt @@ -0,0 +1,7 @@ +package com.mogo.cloud.httpdns.listener + +import com.mogo.cloud.httpdns.bean.HttpDnsSimpleLocation + +interface IHttpDnsCurrentLocation { + fun getCurrentLocation(): HttpDnsSimpleLocation? +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/IMogoHttpDns.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/IMogoHttpDns.kt new file mode 100644 index 0000000..75e45bc --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/IMogoHttpDns.kt @@ -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? + + fun release() +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/OnAddressChangedListener.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/OnAddressChangedListener.kt new file mode 100644 index 0000000..8ff192b --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/listener/OnAddressChangedListener.kt @@ -0,0 +1,5 @@ +package com.mogo.cloud.httpdns.listener + +interface OnAddressChangedListener { + fun onAddressChanged(address: Map?) +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/ApiManager.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/ApiManager.kt new file mode 100644 index 0000000..2ce7962 --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/ApiManager.kt @@ -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? { + 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(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 + } + + +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/L.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/L.kt new file mode 100644 index 0000000..d908640 --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/L.kt @@ -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) + } +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/NetWorkUtil.kt b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/NetWorkUtil.kt new file mode 100644 index 0000000..64fa672 --- /dev/null +++ b/foudations/mogo-httpdns/src/main/java/com/mogo/cloud/httpdns/util/NetWorkUtil.kt @@ -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) + } +} \ No newline at end of file diff --git a/foudations/mogo-httpdns/src/test/java/com/mogo/cloud/httpdns/ExampleUnitTest.kt b/foudations/mogo-httpdns/src/test/java/com/mogo/cloud/httpdns/ExampleUnitTest.kt new file mode 100644 index 0000000..9d7020a --- /dev/null +++ b/foudations/mogo-httpdns/src/test/java/com/mogo/cloud/httpdns/ExampleUnitTest.kt @@ -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) + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index a4eb9ff..05c00ef 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,4 @@ +include ':foudations:mogo-httpdns' include ':foudations:mogo-passport' include ':app' rootProject.name = "MoGoAiCloudSdk" \ No newline at end of file