1、添加dNSCache库,并实现sina DNSCache 功能,优化服务器连接DNS搜索。
authorsnickersun <snickersun@qq.com>
Wed, 12 Feb 2020 17:09:11 +0000 (01:09 +0800)
committersnickersun <snickersun@qq.com>
Wed, 12 Feb 2020 17:09:11 +0000 (01:09 +0800)
2、实现SMS 命令行,可以重新配置服务器地址,IMEI地址以及获取手表状态。
支持的命令有:
#deviceinfo#
#status#
#imei:reset
#imei:123456789012345
#ip#=reset#
#ip#=192.168.1.1,8089#
#ip#=192.168.1.1:8089#

185 files changed:
app/app.iml
app/build.gradle
app/src/main/java/com/enqualcomm/support/Config.java
app/src/main/java/com/enqualcomm/support/Constants.java
app/src/main/java/com/enqualcomm/support/CoreService.java
app/src/main/java/com/enqualcomm/support/ICApplication.java
app/src/main/java/com/enqualcomm/support/ICSmsManager.java
app/src/main/java/com/enqualcomm/support/MainActivity.java
app/src/main/java/com/enqualcomm/support/bean/DNSTaskModel.java [new file with mode: 0644]
app/src/main/java/com/enqualcomm/support/bean/Runtime.java
app/src/main/java/com/enqualcomm/support/service/HeartRateManager.java
app/src/main/java/com/enqualcomm/support/service/Initialize.java
app/src/main/java/com/enqualcomm/support/service/KeepAlive.java
app/src/main/java/com/enqualcomm/support/utils/DeviceInfoUtil.java
app/src/main/java/com/enqualcomm/support/utils/DnsUtil.java [new file with mode: 0644]
app/src/main/java/com/enqualcomm/support/utils/HttpDnsRecordUtil.java [new file with mode: 0644]
app/src/main/java/com/enqualcomm/support/utils/IPtoAddress.java [new file with mode: 0644]
app/src/main/java/com/enqualcomm/support/utils/NettyConnection.java
app/src/main/java/com/enqualcomm/support/utils/NetworkObservable.java
app/src/main/java/com/enqualcomm/support/utils/SimSignalUtil.java
app/src/main/java/com/enqualcomm/support/utils/StorageUtils.java [new file with mode: 0644]
app/src/main/java/com/enqualcomm/support/utils/TimeUtil.java
app/src/main/java/com/enqualcomm/support/utils/Util.java
app/version_code.properties
dNSCache/build.gradle [new file with mode: 0644]
dNSCache/build/.transforms/7c72370c09d54379f48fb03517858be0.bin [new file with mode: 0644]
dNSCache/build/.transforms/7c72370c09d54379f48fb03517858be0/classes/classes.dex [new file with mode: 0644]
dNSCache/build/generated/source/buildConfig/debug/com/sina/util/dnscache/BuildConfig.java [new file with mode: 0644]
dNSCache/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml [new file with mode: 0644]
dNSCache/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output.json [new file with mode: 0644]
dNSCache/build/intermediates/annotation_processor_list/debug/annotationProcessors.json [new file with mode: 0644]
dNSCache/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt [new file with mode: 0644]
dNSCache/build/intermediates/compile_library_classes/debug/classes.jar [new file with mode: 0644]
dNSCache/build/intermediates/compile_only_not_namespaced_r_class_jar/debug/R.jar [new file with mode: 0644]
dNSCache/build/intermediates/incremental/debug-mergeJavaRes/merge-state [new file with mode: 0644]
dNSCache/build/intermediates/incremental/debug-mergeNativeLibs/merge-state [new file with mode: 0644]
dNSCache/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml [new file with mode: 0644]
dNSCache/build/intermediates/incremental/mergeDebugShaders/merger.xml [new file with mode: 0644]
dNSCache/build/intermediates/incremental/packageDebugAssets/merger.xml [new file with mode: 0644]
dNSCache/build/intermediates/incremental/packageDebugResources/compile-file-map.properties [new file with mode: 0644]
dNSCache/build/intermediates/incremental/packageDebugResources/merged.dir/values/values.xml [new file with mode: 0644]
dNSCache/build/intermediates/incremental/packageDebugResources/merger.xml [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/AppConfigUtil.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/BuildConfig.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$1.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$2.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$LogUpLoadTask.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$SpeedTestTask.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$UpdateTask.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$1.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$Data.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DomainInfo.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/Tools.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DBConstants.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DNSCacheDatabaseHelper.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DnsCacheManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/IDnsCache.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsConfig.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager$1.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDns.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDnsProvider.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser$JavaJSON_SINAHTTPDNS.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns$DNSPodCipher.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/LocalDns.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/SinaHttpDns.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient$UdpDnsInfo.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/FileUtil.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager$1.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/IDnsLog.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/ConnectFailModel.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/DomainModel.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack$IP.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/IpModel.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/ApacheHttpClientNetworkRequests.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/INetworkRequests.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/Constants.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$1.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$Util.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/IQuery.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/QueryManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IPlugIn.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IScore.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager$IpModelSort.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/ScoreManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/ErrNumPlugin.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/PriorityPlugin.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/BaseSpeedTest.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/ISpeedtest.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager$1.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest$Ping.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/Socket80Test.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool$DefaultThreadFactory.class [new file with mode: 0644]
dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool.class [new file with mode: 0644]
dNSCache/build/intermediates/library_java_res/debug/res.jar [new file with mode: 0644]
dNSCache/build/intermediates/library_manifest/debug/AndroidManifest.xml [new file with mode: 0644]
dNSCache/build/intermediates/local_only_symbol_list/debug/parseDebugLibraryResources/R-def.txt [new file with mode: 0644]
dNSCache/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt [new file with mode: 0644]
dNSCache/build/intermediates/merged_java_res/debug/out.jar [new file with mode: 0644]
dNSCache/build/intermediates/merged_manifests/debug/output.json [new file with mode: 0644]
dNSCache/build/intermediates/packaged-classes/debug/classes.jar [new file with mode: 0644]
dNSCache/build/intermediates/packaged_res/debug/drawable-hdpi-v4/ic_launcher.png [new file with mode: 0644]
dNSCache/build/intermediates/packaged_res/debug/drawable-mdpi-v4/ic_launcher.png [new file with mode: 0644]
dNSCache/build/intermediates/packaged_res/debug/drawable-xhdpi-v4/ic_launcher.png [new file with mode: 0644]
dNSCache/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/ic_launcher.png [new file with mode: 0644]
dNSCache/build/intermediates/packaged_res/debug/layout/activity_main.xml [new file with mode: 0644]
dNSCache/build/intermediates/packaged_res/debug/menu/menu_main.xml [new file with mode: 0644]
dNSCache/build/intermediates/packaged_res/debug/values/values.xml [new file with mode: 0644]
dNSCache/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt [new file with mode: 0644]
dNSCache/build/intermediates/runtime_library_classes/debug/classes.jar [new file with mode: 0644]
dNSCache/build/intermediates/symbols/debug/R.txt [new file with mode: 0644]
dNSCache/build/outputs/aar/dNSCache-debug.aar [new file with mode: 0644]
dNSCache/build/outputs/logs/manifest-merger-debug-report.txt [new file with mode: 0644]
dNSCache/dNSCache.iml [new file with mode: 0644]
dNSCache/src/main/AndroidManifest.xml [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/AppConfigUtil.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/DNSCache.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/DNSCacheConfig.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/DomainInfo.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/Tools.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/cache/DBConstants.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/cache/DNSCacheDatabaseHelper.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/cache/DnsCacheManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/cache/IDnsCache.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/DnsConfig.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/DnsManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IDns.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IDnsProvider.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IJsonParser.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/HttpPodDns.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/LocalDns.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/SinaHttpDns.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/UdpDns.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/log/FileUtil.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/log/HttpDnsLogManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/log/IDnsLog.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/model/ConnectFailModel.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/model/DomainModel.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/model/HttpDnsPack.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/model/IpModel.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/net/ApacheHttpClientNetworkRequests.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/net/INetworkRequests.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/Constants.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/NetworkManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/query/IQuery.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/query/QueryManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/IPlugIn.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/IScore.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/PlugInManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/ScoreManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/ErrNumPlugin.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/PriorityPlugin.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/speedtest/BaseSpeedTest.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/speedtest/ISpeedtest.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/speedtest/SpeedtestManager.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/speedtest/impl/PingTest.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/speedtest/impl/Socket80Test.java [new file with mode: 0644]
dNSCache/src/main/java/com/sina/util/dnscache/thread/RealTimeThreadPool.java [new file with mode: 0644]
dNSCache/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
dNSCache/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
dNSCache/src/main/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
dNSCache/src/main/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
dNSCache/src/main/res/layout/activity_main.xml [new file with mode: 0644]
dNSCache/src/main/res/menu/menu_main.xml [new file with mode: 0644]
dNSCache/src/main/res/values/strings.xml [new file with mode: 0644]

index 325d885..e9dfcaa 100644 (file)
@@ -4,8 +4,8 @@
     <facet type="android-gradle" name="Android-Gradle">\r
       <configuration>\r
         <option name="GRADLE_PROJECT_PATH" value=":app" />\r
-        <option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" value="3.5.0" />\r
-        <option name="LAST_KNOWN_AGP_VERSION" value="3.5.0" />\r
+        <option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" value="3.5.3" />\r
+        <option name="LAST_KNOWN_AGP_VERSION" value="3.5.3" />\r
       </configuration>\r
     </facet>\r
     <facet type="android" name="Android">\r
     <orderEntry type="library" name="Gradle: com.android.support:support-compat:25.1.0@aar" level="project" />\r
     <orderEntry type="library" name="Gradle: com.kymjs.rxvolley:rxvolley:1.1.3@aar" level="project" />\r
     <orderEntry type="library" name="Gradle: io.reactivex:rxandroid:1.1.0@aar" level="project" />\r
+    <orderEntry type="module" module-name="dNSCache" />\r
+    <orderEntry type="module" module-name="dNSCache" />\r
+    <orderEntry type="module" module-name="dNSCache" />\r
+    <orderEntry type="module" module-name="dNSCache" />\r
+    <orderEntry type="module" module-name="dNSCache" />\r
+    <orderEntry type="module" module-name="dNSCache" />\r
   </component>\r
 </module>
\ No newline at end of file
index d1a2093..bbc4d72 100644 (file)
@@ -25,12 +25,7 @@ android {
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 
     }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-    }
+
     signingConfigs {
         key {
             storeFile file("EQC_G5.jks")
@@ -89,13 +84,14 @@ android {
 //    }
 }
 dependencies {
-    compile fileTree(include: ['*.jar'], dir: 'libs')
+    compile fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
         exclude group: 'com.android.support', module: 'support-annotations'
     })
     compile 'com.android.support:appcompat-v7:25.1.0'
     compile 'com.github.ChestnutPlus:TestModules:v1.0.16'
     testCompile 'junit:junit:4.12'
+    implementation project(path: ':dNSCache')
 }
 
 def getVersionCode() {
@@ -119,6 +115,6 @@ def getVersionCode() {
 
 def releaseTime() {
 
-    return new Date().format("yyyyMMddHHmm", TimeZone.getTimeZone("GMT+08:00"))
+    return new Date().format("yyMMddHHmm", TimeZone.getTimeZone("GMT+08:00"))
 
 }
\ No newline at end of file
index 351b79f..c0c75d8 100644 (file)
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
 import android.text.TextUtils;\r
 \r
 import com.enqualcomm.support.bean.ICLocation;\r
+import com.enqualcomm.support.bean.Runtime;\r
 import com.enqualcomm.support.utils.SharPreferenceUtil;\r
 \r
 import org.json.JSONException;\r
@@ -273,6 +274,7 @@ public class Config {
   }\r
 \r
   final static String KeyProtocolServerIP="ProtocolServerIP";\r
+  final static String KeyProtocolServerHOST="ProtocolServerHOST";\r
   final static String KeyProtocolServerPort="ProtoclServerPort";;\r
   final static String KeyFotaServerIP="FotaServerIP";\r
   final static String KeyFotaServerPort="FotaServerPort";\r
@@ -285,8 +287,9 @@ public class Config {
 \r
   final static String  KeyContactsList="ContactsList";\r
   final static String  KeySOSNumbersList="SOSNumbersList";\r
+  final static String KeyIMEI="IMEI";\r
 \r
-\r
+  final static String KeyHeartBeatCycle="ServerHeartBeatCycle";\r
 \r
   public static void setAlarmCycle(Context context, int cycle){\r
     SharPreferenceUtil.setPrefInt(context,KeyAlarmCycle,cycle);\r
@@ -306,6 +309,34 @@ public class Config {
     return SharPreferenceUtil.getPrefString(context,KeyProtocolServerIP,"118.178.155.223");\r
   }\r
 \r
+  public static void loadModCycleSettings(Runtime runtime){\r
+    runtime.setPpgTestCycle(Config.getPPGTestCycle(runtime.getContextProxy().context));\r
+    runtime.getLocationInstance().setLocation_cycle(Config.getLocationCycle(runtime.getContextProxy().context));\r
+    runtime.getLocationInstance().setWorkingMod(Config.getLocationMode(runtime.getContextProxy().context));\r
+  }\r
+\r
+  public static void loadHearBeatSetting(Runtime runtime){\r
+    runtime.setHeartBeatCycle(Config.getHeartBeatCycle(runtime.getContextProxy().context));\r
+  }\r
+  public static void loadServerSettings(Runtime runtime){\r
+    runtime.setHostAndPort(Config.getProtocolServerHost(runtime.getContextProxy().context),Config.getProtocolServerPort(runtime.getContextProxy().context));\r
+  }\r
+\r
+  public static void setIMEI(Context context, String imei){\r
+    SharPreferenceUtil.setPrefString(context,KeyIMEI,imei);\r
+  }\r
+\r
+  public static String getIMEI(Context context){\r
+    return SharPreferenceUtil.getPrefString(context,KeyIMEI,"");\r
+  }\r
+\r
+  public static String getProtocolServerHost(Context context){\r
+    return SharPreferenceUtil.getPrefString(context,KeyProtocolServerHOST,"watch.jiai.pro");\r
+  }\r
+\r
+  public static void setProtocolServerHost(Context context,String host){\r
+    SharPreferenceUtil.setPrefString(context,KeyProtocolServerHOST,host);\r
+  }\r
   public static int getProtocolServerPort(Context context){\r
     return SharPreferenceUtil.getPrefInt(context,KeyProtocolServerPort,8090);\r
   }\r
@@ -333,6 +364,14 @@ public class Config {
     return SharPreferenceUtil.getPrefInt(context,KeyPpgTestCycle,30);\r
   }\r
 \r
+\r
+  public static int getHeartBeatCycle(Context context){\r
+    return SharPreferenceUtil.getPrefInt(context,KeyHeartBeatCycle,6);\r
+  }\r
+\r
+  public static void setHeartBeatCycle(Context context,int cycle){\r
+    SharPreferenceUtil.setPrefInt(context,KeyHeartBeatCycle,cycle);\r
+  }\r
   public static void setLocationCycle(Context context,int cycle){\r
     SharPreferenceUtil.setPrefInt(context,KeyLocationCycle,cycle);\r
   }\r
index f50b592..42cb2af 100644 (file)
@@ -3,6 +3,8 @@ package com.enqualcomm.support;
 import android.net.Uri;\r
 \r
 public interface Constants {\r
+\r
+  public static final String ACTION_BROADCAST_PPG = "com.enqualcomm.support.ACTION_BROADCAST_PPG";\r
   public static final String ACTION_ADDTEST_CONTACTS = "com.enqualcomm.imessage.ACTION_ADDTEST_CONTACTS";\r
   \r
   public static final String ACTION_ALARM_ADD_DATAPOINTS = "com.enqualcomm.support.ADD_DATAPOINTS";\r
index 6c294fc..eba3437 100644 (file)
@@ -236,12 +236,6 @@ public class CoreService extends Service {
             if (coreService == null)\r
                 return;\r
             Logger.i("onConnectionClose++ retry to connect again!");\r
-//            startConnectionRetryTimer();\r
-            String ip=Util.parseHostGetIPAddress(coreService.runtime.getHost());\r
-            if ( ip !=null && ! ip.equals(coreService.runtime.getSrvIP())){\r
-                Logger.i("HostName "+coreService.runtime.getHost()+ " IP changed from "+coreService.runtime.getSrvIP()+" to "+ip);\r
-                coreService.runtime.setSrvIP(ip);\r
-            }\r
             coreService.connectionServiceChain.processConnectionClose(coreService.connection, coreService.runtime);\r
         }\r
 \r
@@ -327,14 +321,14 @@ public class CoreService extends Service {
 \r
 \r
     private AbstractConnectionService getConnectionServiceChain() {\r
-        Initialize initialize = new Initialize();\r
+//        Initialize initialize = new Initialize();\r
         CheckSIM checkSIM = new CheckSIM();\r
         this.mKeepAlive = new KeepAlive();\r
         this.mDeliver = new Deliver(this.connection,this.runtime);\r
-        initialize.setNext(checkSIM);\r
+//        initialize.setNext(checkSIM);\r
         checkSIM.setNext(this.mKeepAlive);\r
         this.mKeepAlive.setNext(this.mDeliver);\r
-        return initialize;\r
+        return checkSIM;\r
     }\r
 \r
     private void getDBFile() {\r
@@ -354,12 +348,6 @@ public class CoreService extends Service {
         return sendChatMessage;\r
     }\r
 \r
-    private void loadSettings(){\r
-        this.runtime.setPpgTestCycle(Config.getPPGTestCycle(this));\r
-        this.runtime.getLocationInstance().setLocation_cycle(Config.getLocationCycle(this));\r
-        this.runtime.getLocationInstance().setWorkingMod(Config.getLocationMode(this));\r
-    }\r
-\r
     private void loadStepCount() {\r
         int i = SharPreferenceUtil.getPrefInt(this, KEY_STEP_COUNT, 0);\r
         int j = SharPreferenceUtil.getPrefInt(this, KEY_SAVE_STEP_COUNT, 0);\r
@@ -463,9 +451,16 @@ public class CoreService extends Service {
         this.runtime.setDBHelper(new DBHelper(getContentResolver(), this));\r
         this.runtime.setContextProxy(new ContextProxy(this));\r
         this.runtime.setLbsHelper(new LBSHelper(this,this.runtime.getContextProxy().getWifiManager(), this.runtime));\r
-        this.runtime.setImeiAndCid(PhoneUtils.getIMEI(this),"");\r
+\r
+        if (Config.getIMEI(runtime.getContextProxy().context).isEmpty()){\r
+            //如果配置里有IMEI,优先选配置里的,没有则选择系统的\r
+            runtime.setImeiAndCid(PhoneUtils.getIMEI(this),"");\r
+        }  else{\r
+            runtime.setImeiAndCid(Config.getIMEI(runtime.getContextProxy().context),"");\r
+        }\r
         this.runtime.setHRS(new heartRateStatus());\r
         this.runtime.setUseQueue(true);\r
+        this.runtime.initDnsUtil(this.getApplicationContext());\r
         this.connectionServiceChain = getConnectionServiceChain();\r
         this.invokeHandlerServiceChain = getInvokeHandlerServiceChain();\r
         if (cmcm_call_eiot_into_powersave_mode() == 1) {\r
@@ -478,7 +473,13 @@ public class CoreService extends Service {
 \r
         //保证获取正确的计步数据及其他参数初始化\r
         loadStepCount();\r
-        loadSettings();\r
+        //初始化ServerHeartBeat Cycle\r
+        Config.loadHearBeatSetting(runtime);\r
+        //初始化PPG,LocationMod,LocationCycle\r
+        Config.loadModCycleSettings(runtime);\r
+        //初始化IP\r
+        Config.loadServerSettings(runtime);\r
+\r
 \r
         this.connectionServiceChain.processAttach(this.connection, this.runtime);\r
         this.invokeHandlerServiceChain.processAttach(this.connection, this.runtime);\r
@@ -486,12 +487,13 @@ public class CoreService extends Service {
         if (Config.LOG_TOFILE)  FileOutputUtil.fileOutput(runtime.getCacheDir(), "alarmCycle", "设置闹钟服务  alarmCycle");\r
         this.locationClient = new LocationClient(this.connection, this.runtime);\r
         this.connection.open();\r
-        this.connection.connect(this.runtime.getSrvIP(), this.runtime.getPort());\r
-        this.locationClient.start();\r
 \r
         //启动inner Service\r
         startService(new Intent(this, InnerService.class));\r
 \r
+        ReConnectToServer();\r
+        this.locationClient.start();\r
+\r
 \r
         //设置本service为前台运行,不被会被清理\r
         Notification notification = new Notification();\r
@@ -500,7 +502,6 @@ public class CoreService extends Service {
         notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;\r
         startForeground(GRAY_SERVICE_ID, notification);\r
 \r
-\r
         //注册接收  时间和tiimezone 变更消息\r
         IntentFilter intentFilter = new IntentFilter();\r
 //        intentFilter.addAction("android.intent.action.TIME_SET");\r
@@ -690,7 +691,7 @@ public class CoreService extends Service {
 \r
                             }else if(ACTION_SEND_EMEGENCY_LOCATION_STOP.equals(paramIntent.getAction())){\r
                                 //stop Emegency location Stop\r
-                                loadSettings(); //回复之前的 工作模式即可\r
+                                Config.loadModCycleSettings(runtime); //回复之前的 工作模式即可\r
                             }else if (ACTION_BATTERY_LOW_MSG.equals(paramIntent.getAction())){\r
 \r
                                 runtime.setAlarmType(false,runtime.getBatteryLow(),false,false);\r
@@ -778,19 +779,9 @@ public class CoreService extends Service {
     public void setHeartAlarm(){\r
 //        int mod=runtime.getLocationInstance().getWorkingMod();\r
         StringBuilder sb=new StringBuilder();\r
-        int cycle=3;\r
-//        switch(mod){\r
-//            case EMERGNECY_MOD:\r
-//            case REALTIME_MOD:\r
-//                cycle=1;\r
-//                break;\r
-//            case NORMAL_MOD:\r
-//                cycle=15;\r
-//                break;\r
-//            case LOWPOWER_MOD:\r
-//                cycle=60;\r
-//                break;\r
-//        }\r
+        int cycle=runtime.getHeartBeatCycle();\r
+\r
+        //心跳指令默认设置为3分钟\r
         AlarmHelper.setRealTimeAlarm(runtime.getContextProxy().context,cycle, HEART_ALARM);\r
         sb.append(" setHeartAlarm  "+HEART_ALARM+", cycle "+cycle);\r
 \r
@@ -873,33 +864,45 @@ public class CoreService extends Service {
     }\r
 \r
     public void startConnectionRetryTimer(){\r
-        if (mTimer_retry_connect == null) {\r
-            mTimer_retry_connect = new Timer();\r
-        }\r
-\r
-        //如果开始进行连接重试,证明网络断开的,那么KeepAlive也需要重连(心跳包)\r
-\r
-        KeepAlive.isConnected=false;\r
-        if (mTimer_retry_connect !=null){\r
-            mTimer_retry_connect.schedule(new TimerTask() {\r
-                @Override\r
-                public void run() {\r
-                    do_timer_task();\r
-                }\r
-            },0,5000); //每5秒重试一次\r
+        //联网再重试连接服务器\r
+        if (SimSignalUtil.checkNet(runtime.getContextProxy().context) ) {\r
+             stopConnectionRetryTimer();\r
+            if (mTimer_retry_connect == null) {\r
+                mTimer_retry_connect = new Timer();\r
+            }\r
+            //如果开始进行连接重\r
+                // {\r
+            // 试,证明网络断开的,那么KeepAlive也需要重连(心跳包)\r
+\r
+            KeepAlive.isConnected = false;\r
+            if (mTimer_retry_connect != null) {\r
+                mTimer_retry_connect.schedule(new TimerTask() {\r
+                    @Override\r
+                    public void run() {\r
+                        ReConnectToServer();\r
+                    }\r
+                }, 0, 5000); //每5秒重试一次\r
+            }\r
         }\r
     }\r
 \r
-    public void do_timer_task(){\r
-\r
+    public void ReConnectToServer(){\r
 \r
-        this.connection.connect(this.runtime.getSrvIP(), this.runtime.getPort());\r
+        if (SimSignalUtil.checkNet(runtime.getContextProxy().context) ) {\r
+            String ip=runtime.getDnsUtil().getServerIP_ByDNSCache(runtime.getHost());\r
+            if (null != ip && !ip.equals(runtime.getSrvIP())) {\r
+                runtime.setSrvIP(ip);\r
+            }\r
+            this.connection.connect(this.runtime.getSrvIP(), this.runtime.getPort());\r
 \r
-        //里面如果连接成功 connectionOpen 会先发送 AP00 登录包 和发送AP03 心跳包 ,都成功则停止重试\r
-         if (connection.isServerConnected() && KeepAlive.isConnected)\r
-         {\r
-             stopConnectionRetryTimer();\r
-         }\r
+            //里面如果连接成功 connectionOpen 会先发送 AP00 登录包 和发送AP03 心跳包 ,都成功则停止重试\r
+            if (connection.isServerConnected() && KeepAlive.isConnected) {\r
+                stopConnectionRetryTimer();\r
+            }\r
+        }else{\r
+            //没有网络就不用重新尝试连接网络了。网络连接后再重新尝试联网\r
+            stopConnectionRetryTimer();\r
+        }\r
     }\r
 \r
     public void stopConnectionRetryTimer(){\r
@@ -940,6 +943,10 @@ public class CoreService extends Service {
 \r
     }\r
 \r
+    public void disconnect_server(){\r
+        this.connection.close();\r
+    }\r
+\r
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {\r
         @Override\r
         public void onReceive(Context context, Intent intent) {\r
index d78344d..8d45324 100644 (file)
@@ -10,6 +10,7 @@ import android.util.SparseArray;
 \r
 \r
 import com.enqualcomm.support.BuildConfig;\r
+import com.sina.util.dnscache.DNSCache;\r
 \r
 import java.util.HashMap;\r
 \r
index fb5a376..a422450 100644 (file)
@@ -17,10 +17,13 @@ import android.widget.Toast;
 import com.enqualcomm.support.bean.Runtime;\r
 import com.enqualcomm.support.utils.DeviceInfoUtil;\r
 import com.enqualcomm.support.utils.Logger;\r
+import com.enqualcomm.support.utils.ServiceUtil;\r
 \r
 import java.util.ArrayList;\r
 import java.util.Iterator;\r
 \r
+import chestnut.utils.PhoneUtils;\r
+\r
 \r
 public class ICSmsManager {\r
     private static String mNumber;\r
@@ -41,50 +44,6 @@ public class ICSmsManager {
         intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");\r
         intentFilter.setPriority(2147483647);\r
         this.mContext.registerReceiver(this.smsReceiver, intentFilter);\r
-\r
-\r
-        //处理返回的发送状态\r
-        String SENT_SMS_ACTION = "SENT_SMS_ACTION";\r
-        Intent sentIntent = new Intent(SENT_SMS_ACTION);\r
-        PendingIntent sentPI = PendingIntent.getBroadcast(mContext, 0, sentIntent,\r
-                0);\r
-// register the Broadcast Receivers\r
-        mContext.registerReceiver(new BroadcastReceiver() {\r
-            @Override\r
-            public void onReceive(Context _context, Intent _intent) {\r
-                switch (getResultCode()) {\r
-                    case Activity.RESULT_OK:\r
-                        Toast.makeText(mContext,\r
-                                "短信发送成功", Toast.LENGTH_SHORT)\r
-                                .show();\r
-                        break;\r
-                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:\r
-                        break;\r
-                    case SmsManager.RESULT_ERROR_RADIO_OFF:\r
-                        break;\r
-                    case SmsManager.RESULT_ERROR_NULL_PDU:\r
-                        break;\r
-                }\r
-            }\r
-        }, new IntentFilter(SENT_SMS_ACTION));\r
-\r
-\r
-        //处理返回的接收状态\r
-        String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";\r
-// create the deilverIntent parameter\r
-        Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);\r
-        PendingIntent deliverPI = PendingIntent.getBroadcast(mContext, 0,\r
-                deliverIntent, 0);\r
-        mContext.registerReceiver(new BroadcastReceiver() {\r
-            @Override\r
-            public void onReceive(Context _context, Intent _intent) {\r
-                Toast.makeText(mContext,\r
-                        "收信人已经成功接收", Toast.LENGTH_SHORT)\r
-                        .show();\r
-            }\r
-        }, new IntentFilter(DELIVERED_SMS_ACTION));\r
-\r
-\r
     }\r
 \r
     public void sendSMS(String phonenumber, String msg) {\r
@@ -102,12 +61,104 @@ public class ICSmsManager {
 \r
         return true;\r
     }\r
+\r
+    //1:短信设置服务器\r
+    //#ip#=198.11.183.28,5088#\r
+    //回复 ip set ok\r
+    //\r
+    //2:短信写IMEI\r
+    //#imei:108111804000475\r
+    //回复  imri write ok\r
+    //\r
+    //3:  短信增加APN\r
+    //#apn#=MCC,MNC,apn name,apn name,user name,password#\r
+    //回复  APN set ok\r
+    //\r
+    //4:远程查询软件版本和IMEI号码\r
+    //#status#\r
+    //回复\r
+    //IMEI: 353503535035350\r
+    //SW: L02_20200208_V1\r
     public void handleSMS_CMD(String phonenumber, String sms){\r
         if (isAdminNumber(phonenumber)) {\r
-            if (sms.startsWith("GetDeviceInfo")) {\r
-                    sendSMS(phonenumber,DeviceInfoUtil.getDeviceInfo(runtime));\r
+            if (sms.startsWith("#deviceinfo#")) {\r
+                Logger.i("SMS "+sms+" reply "+DeviceInfoUtil.getShortDeviceInfo(runtime));\r
+                sendSMS(phonenumber,DeviceInfoUtil.getShortDeviceInfo(runtime));\r
+            }else if (sms.startsWith("#status#")) {\r
+                String reply="IMEI="+runtime.IMEI()+"\nSW:"+DeviceInfoUtil.getVersionCode(runtime.getContextProxy().context)+" "+DeviceInfoUtil.getSWVersionDisplayName();\r
+                Logger.i("SMS "+sms+" reply \n"+reply);\r
+                sendSMS(phonenumber,reply);\r
+            }else if (sms.startsWith("#imei:")) {\r
+                String imei=sms.substring(6);\r
+                Logger.i("SMS "+sms+" imei="+imei);\r
+                if (imei.length()==15 ) {\r
+                    Config.setIMEI(runtime.getContextProxy().context, imei);\r
+                    runtime.setImeiAndCid(imei, "");\r
+                    sendSMS(phonenumber, "set IMEI " + imei + " sucess !");\r
+                    CoreService.getInstance().disconnect_server();\r
+                    CoreService.getInstance().ReConnectToServer();\r
+                }else if (imei.equals("reset")) {\r
+                    Config.setIMEI(runtime.getContextProxy().context, "");\r
+                    runtime.setImeiAndCid(PhoneUtils.getIMEI(runtime.getContextProxy().context), "");\r
+                    sendSMS(phonenumber, "reset IMEI to " + PhoneUtils.getIMEI(runtime.getContextProxy().context) + " sucess !");\r
+                    CoreService.getInstance().disconnect_server();\r
+                    CoreService.getInstance().ReConnectToServer();\r
+                }else{\r
+                    sendSMS(phonenumber, "set IMEI " + imei + "  failed ! len!=15");\r
+                }\r
+            }else if (sms.startsWith("#ip#=") && sms.endsWith("#")) {\r
+                String tmp[]=sms.split("=");\r
+                String reply="";\r
+                Logger.i(sms+" len "+tmp.length);\r
+                if (tmp.length==2)\r
+                {\r
+                    //分析 以 , 为分界的格式\r
+                    String[] ipstr = tmp[1].split(",");\r
+                    if (ipstr[0].equals("reset#")) {\r
+                        Config.setProtocolServerHost(runtime.getContextProxy().context, Runtime.DefaultHost);\r
+                        Config.setProtocolServerAddr(runtime.getContextProxy().context, "", Runtime.DefaultPort);\r
+                        reply = "reset ServerIP to " + Runtime.DefaultHost + ":" + Runtime.DefaultPort + " success! ";\r
+                        Config.loadServerSettings(runtime);\r
+                        CoreService.getInstance().disconnect_server();\r
+                        CoreService.getInstance().ReConnectToServer();\r
+                    }else if (ipstr.length==2){\r
+                        String ip=ipstr[0];\r
+                        int port=Integer.valueOf(ipstr[1].replace("#",""));\r
+                        Config.setProtocolServerHost(runtime.getContextProxy().context,ip);\r
+                        Config.setProtocolServerAddr(runtime.getContextProxy().context,"",port);\r
+                        reply = sms+" success! ";\r
+                        Config.loadServerSettings(runtime);\r
+                        CoreService.getInstance().disconnect_server();\r
+                        CoreService.getInstance().ReConnectToServer();\r
+                    }else{\r
+                        //分析以 : 为分界的格式\r
+                        ipstr = tmp[1].split(":");\r
+\r
+                        if (ipstr[0].equals("reset#")) {\r
+                            Config.setProtocolServerHost(runtime.getContextProxy().context, Runtime.DefaultHost);\r
+                            Config.setProtocolServerAddr(runtime.getContextProxy().context, "", Runtime.DefaultPort);\r
+                            reply = "reset ServerIP to " + Runtime.DefaultHost + ":" + Runtime.DefaultPort + " success! ";\r
+                            Config.loadServerSettings(runtime);\r
+                            CoreService.getInstance().disconnect_server();\r
+                            CoreService.getInstance().ReConnectToServer();\r
+                        } else if (ipstr.length == 2) {\r
+                            String ip = ipstr[0];\r
+                            int port = Integer.valueOf(ipstr[1].replace("#", ""));\r
+                            Config.setProtocolServerHost(runtime.getContextProxy().context, ip);\r
+                            Config.setProtocolServerAddr(runtime.getContextProxy().context, "", port);\r
+                            reply = sms + " success! ";\r
+                            Config.loadServerSettings(runtime);\r
+                            CoreService.getInstance().disconnect_server();\r
+                            CoreService.getInstance().ReConnectToServer();\r
+                        } else {\r
+                            reply = sms + " falied! ";\r
+                        }\r
+                    }\r
+                }else{\r
+                    reply = sms + " falied! ";\r
+                }\r
+                sendSMS(phonenumber, reply);\r
             }\r
-\r
         }\r
     }\r
 \r
index 33e6466..0237d3e 100644 (file)
@@ -15,6 +15,7 @@ import android.widget.TextView;
 import android.widget.ToggleButton;
 
 import com.enqualcomm.support.R;
+import com.enqualcomm.support.utils.DeviceInfoUtil;
 import com.ic.jni.ICJniUtils;
 import com.enqualcomm.support.CoreService;
 import com.enqualcomm.support.utils.Logger;
@@ -93,7 +94,7 @@ public class MainActivity extends AppCompatActivity {
 
 
         TextView tv_version=(TextView)findViewById(R.id.textViewVersion);
-        tv_version.setText(   getVersionName(this));
+        tv_version.setText(DeviceInfoUtil.getVersionName(this));
 
     }
 
@@ -123,30 +124,6 @@ public class MainActivity extends AppCompatActivity {
 
 
     }
-    /**
-     * 得到当前应用版本名称的方法
-     *
-     * @param context
-     *            :上下文
-     * @throws Exception
-     */
-    public static String getVersionName(Context context)  {
-        // 获取packagemanager的实例
-        PackageManager packageManager = context.getPackageManager();
-        // getPackageName()是你当前类的包名
-        PackageInfo packInfo = null;
-        String version="V001";
-        try {
-            packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
-            version = packInfo.versionName;
-        } catch (PackageManager.NameNotFoundException e) {
-            e.printStackTrace();
-        }
-         return version;
-    }
-
-
-
 
     private View.OnClickListener clickListener = new View.OnClickListener() {
         @Override
diff --git a/app/src/main/java/com/enqualcomm/support/bean/DNSTaskModel.java b/app/src/main/java/com/enqualcomm/support/bean/DNSTaskModel.java
new file mode 100644 (file)
index 0000000..e14c5a6
--- /dev/null
@@ -0,0 +1,76 @@
+package com.enqualcomm.support.bean;
+
+import com.sina.util.dnscache.DomainInfo;
+
+public class DNSTaskModel {
+
+       
+       //---------------任务---------------
+       
+       public long taskID  = 0 ; 
+       
+       public int status = 0 ;  //状态:(完成\错误)
+       
+       public long taskStartTime = 0 ; //开始时间:
+       
+       public long taskStopTime = 0 ;//结束时间:
+       
+       public long taskExpendTime = 0 ;//消耗时间:
+       
+       public String url = "" ; //任务传入URL
+       
+       //-------------HTTPDNS库-------------
+       
+       public String httpDnsResult = "" ;  //返回结果:
+       
+       public long httpDnsExpendTime = 0 ; //响应耗时:
+       
+       
+
+       //------------IP+HOST请求------------
+       
+       public String hostUrl = "" ; //访问URL:
+       
+       public String hostIp = "" ; //访问服务器IP:
+       
+       public int hostCode = 0 ; //服务器返回CODE:
+       
+       public byte[] hostInputStreamResult = null ;
+       
+       public String hostResult = "" ; //服务器返回结果:(可点击看详情)
+       
+       public long hostExpendTime = 0 ; //请求耗时:
+       
+       
+       
+       //------------域名直接请求------------
+       
+       public String domainUrl = "" ; //访问URL:
+       
+       public String domainIp = "" ; //访问服务器IP:
+       
+       public int domainCode = 0 ; //服务器返回CODE:
+       
+       public byte[] domainInputStreamResult = null ;
+       
+       public String domainResult = "" ; //服务器返回结果:(可点击看详情)
+       
+       public long domainExpendTime = 0 ; //请求耗时:
+       
+       
+       
+       //------------设备环境信息------------
+       
+       public String netType = "";  //网络环境(WIFI\2G\3G\4G\未知)
+       
+       public String spName = "" ;  //运营商:(WIFI名字\手机卡运营商\未知)
+       
+       
+       
+       
+       //------------HttpDns返回相关信息------------
+       
+       public DomainInfo[] domainInfo = null ;
+       
+       
+}
index e6dfe08..8d0743e 100644 (file)
@@ -1,9 +1,12 @@
 package com.enqualcomm.support.bean;\r
 \r
 \r
+import android.content.Context;\r
+\r
 import com.enqualcomm.support.adapter.LBSHelper;\r
 import com.enqualcomm.support.utils.ContextProxy;\r
 import com.enqualcomm.support.utils.DBHelper;\r
+import com.enqualcomm.support.utils.DnsUtil;\r
 import com.enqualcomm.support.utils.Logger;\r
 \r
 import java.io.File;\r
@@ -54,7 +57,10 @@ public class Runtime {
   private String haveBuy;\r
   \r
   private String haveTry;\r
-  \r
+\r
+  public static final String DefaultHost="watch.jiai.pro";\r
+  public static final int DefaultPort=8090;\r
+\r
   private String host = "watch.jiai.pro"; //118.178.155.223\r
 \r
   private String srvIP = "118.178.155.223";//"39.98.94.164";\r
@@ -63,6 +69,7 @@ public class Runtime {
 \r
   private int port = 8090;//20048;//8888;//8090;\r
 \r
+\r
   private boolean testServerProp=false;\r
 \r
   private String imei_cid = "";\r
@@ -155,12 +162,31 @@ public class Runtime {
   private boolean shutdown;\r
   \r
 \r
+\r
+ private DnsUtil dnsUtil=null;\r
+\r
+ public void initDnsUtil(Context context){\r
+   if (dnsUtil==null)\r
+     dnsUtil=new DnsUtil(5,context);\r
+ }\r
+  public DnsUtil getDnsUtil(){\r
+    return dnsUtil;\r
+  }\r
   private int lastStepCount=0;\r
   private long timestamp;\r
   \r
   public int totalStepCount;\r
 \r
+  private int heartbeatCycle;\r
+\r
 \r
+  public int getHeartBeatCycle()\r
+  {\r
+    return heartbeatCycle;\r
+  }\r
+  public void setHeartBeatCycle(int cycle){\r
+    heartbeatCycle=cycle;\r
+  }\r
   public heartRateStatus getHRS(){\r
     return HRS;\r
   }\r
@@ -278,11 +304,16 @@ public class Runtime {
   \r
   public void setHaveBatteryChange(boolean paramBoolean) { this.haveBatteryChange = paramBoolean; }\r
 \r
+  public void setHost(String _host){\r
+      host=_host;\r
+  }\r
   public void setHostAndPort(String paramString, int paramInt) {\r
     this.host = paramString;\r
     this.port = paramInt;\r
   }\r
-  \r
+  public void setPort(int _port){\r
+    port=_port;\r
+  }\r
   public void setImeiAndCid(String paramString1, String paramString2) {\r
     this.imei = paramString1;\r
     this.cid = paramString2;\r
index a4e4aaf..81b13b5 100644 (file)
@@ -30,6 +30,7 @@ import com.enqualcomm.support.utils.TimeUtil;
 import java.util.Timer;\r
 import java.util.TimerTask;\r
 \r
+import static com.enqualcomm.support.Constants.ACTION_BROADCAST_PPG;\r
 import static com.enqualcomm.support.Constants.ACTION_HEATR_RATE_START;\r
 import static com.enqualcomm.support.Constants.MSG_WHAT_PPG;\r
 import static com.enqualcomm.support.Constants.key_bph;\r
@@ -62,8 +63,10 @@ public class HeartRateManager extends AbstractInvokeHandlerService {
           case 100: {\r
             //只有检测PPG成功,且网络连接中才发送数据\r
             if (runtime.getHRS().getHeartrateWorkingStat() == heartRateStatus.HEARTRATE_WORKINGSTAT.HEARTRATE_TEST_SUCCESS) {\r
-              runtime.getHRS().setLastTestTime(TimeUtil.getLocalTime());\r
+              runtime.getHRS().setLastTestTime(TimeUtil.getSystemTime3());\r
               String PPGDATA = protocolAPIHelper.APHT(runtime);\r
+              sendBroadcastPPGResult();\r
+              //因为协议中没有时间变量,所以只能实时传输,如果恰巧没有网络也只能丢弃,有时间变量的话,可以考虑通过deliver的buffer来进行缓存发送\r
               if (connection.isServerConnected()) {\r
                 connection.send(protocolAPIHelper.genStringMessage("APHT", PPGDATA));\r
                 Logger.i("Send PPG " + PPGDATA);\r
@@ -112,6 +115,14 @@ public class HeartRateManager extends AbstractInvokeHandlerService {
     }\r
   };\r
 \r
+  private void sendBroadcastPPGResult(){\r
+    Intent intent=new Intent(ACTION_BROADCAST_PPG);\r
+    intent.putExtra("ppg",runtime.getHRS().getPPG());\r
+    intent.putExtra("bph",runtime.getHRS().getBPH());\r
+    intent.putExtra("bpl",runtime.getHRS().getBPL());\r
+    intent.putExtra("time",runtime.getHRS().getTestTime());\r
+    runtime.getContextProxy().context.sendBroadcast(intent);\r
+  }\r
   public void regReceiver(){\r
     //注册“网络变化”的广播接收器\r
     IntentFilter intentFilter = new IntentFilter();\r
index ec9b80b..d29e630 100644 (file)
@@ -60,8 +60,8 @@ public class Initialize extends AbstractConnectionService {
     if (this.initOK)\r
       return false; \r
 \r
-    if (paramRuntime.IMSI() != null && !paramRuntime.IMSI().startsWith("46001"))\r
-      paramRuntime.IMSI().startsWith("46006");\r
+//    if (paramRuntime.IMSI() != null && !paramRuntime.IMSI().startsWith("46001"))\r
+//      paramRuntime.IMSI().startsWith("46006");\r
 \r
 //区分联通、移动、电信 号码的策略\r
 //1 通过IMSI号前5位判断\r
@@ -76,25 +76,16 @@ public class Initialize extends AbstractConnectionService {
 //ICCID前六位运营商代码:中国移动的为:898600;898602 ,中国联通的为:898601,中国电信898603\r
 \r
 \r
-    int i = SharPreferenceUtil.getPrefInt((paramRuntime.getContextProxy()).context, "location_mode", 2);\r
-    int j = SharPreferenceUtil.getPrefInt((paramRuntime.getContextProxy()).context, "location_cycle", 3);\r
-    StringBuilder stringBuilder = new StringBuilder();\r
-    stringBuilder.append(i);\r
-    stringBuilder.append("@");\r
-    stringBuilder.append(j);\r
-    Config.work_mode = stringBuilder.toString();\r
-    stringBuilder = new StringBuilder();\r
-    stringBuilder.append(" antioff =");\r
-    stringBuilder.append(Config.antioff);\r
-    Logger.i(stringBuilder.toString());\r
-    Config.sw_release_no = DeviceInfoUtil.getCustomId();\r
+    Config.loadServerSettings(paramRuntime);\r
+\r
     //发送登录包\r
     paramConnection.send(new StringMessage(protocolAPIHelper.AP00(paramRuntime)));\r
-//    paramConnection.send(new StringMessage(protocolAPIHelper.AP00(paramRuntime)));\r
-//    paramConnection.send(new StringMessage(protocolAPIHelper.AP00(paramRuntime)));\r
+\r
+\r
     return false;\r
   }\r
-  \r
+\r
+\r
   public void onDetach(Connection paramConnection, Runtime paramRuntime) { this.initOK = false; }\r
 \r
 \r
index c61eb8a..205707b 100644 (file)
@@ -97,11 +97,11 @@ public class KeepAlive extends AbstractConnectionService {
         this.reConnectionNumber++;\r
         this.firstReConnected = false;\r
       } \r
-      if (paramRuntime.getLockSimInfo()) {\r
-        paramConnection.disconnect();\r
-        return;\r
-      } \r
-      paramConnection.connect(paramRuntime.getSrvIP(), paramRuntime.getPort());\r
+//      if (paramRuntime.getLockSimInfo()) {\r
+//        paramConnection.disconnect();\r
+//        return;\r
+//      }\r
+      CoreService.getInstance().ReConnectToServer();\r
     } \r
   }\r
   \r
@@ -124,8 +124,8 @@ public class KeepAlive extends AbstractConnectionService {
               if (this.first) {\r
                 this.first = false;\r
                 return;\r
-              } \r
-              connection.connect(runtime.getSrvIP(), runtime.getPort());\r
+              }\r
+              CoreService.getInstance().ReConnectToServer();\r
             } \r
           }\r
         });\r
@@ -162,16 +162,12 @@ public class KeepAlive extends AbstractConnectionService {
     stringBuilder.append(",set KeepAlive isConnected = true");\r
     Logger.i(stringBuilder.toString());\r
 //    if (!connectionError) {\r
-      connectionError = false;\r
-//    connection.send(protocolAPIHelper.genStringMessage("AP00",protocolAPIHelper.AP00(paramRuntime)));\r
+    connectionError = false;\r
+\r
+    //发送登录包\r
+    connection.send(protocolAPIHelper.genStringMessage("AP00",protocolAPIHelper.AP00(paramRuntime)));\r
+    //发送心跳包\r
     connection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime)));\r
-//    connection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime)));\r
-//    connection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime)));\r
-//      if (Deliver.haveSendH42) {\r
-//        ServiceUtil.offerQueue(new StringMessage(protocolAPIHelper.AP03(paramRuntime)));\r
-//        Deliver.haveSendH42 = false;\r
-//      }\r
-//    }\r
 \r
     isConnected = true;\r
     this.firstReConnected = true;\r
index a87035a..2614006 100644 (file)
@@ -2,6 +2,8 @@ package com.enqualcomm.support.utils;
 \r
 import android.app.ActivityManager;\r
 import android.content.Context;\r
+import android.content.pm.PackageInfo;\r
+import android.content.pm.PackageManager;\r
 import android.database.Cursor;\r
 import android.net.Uri;\r
 import android.os.Build;\r
@@ -32,7 +34,43 @@ public class DeviceInfoUtil {
       str2 = "0"; \r
     return str2;\r
   }\r
-  \r
+\r
+  /**\r
+   * 得到当前应用版本名称的方法\r
+   *\r
+   * @param context\r
+   *            :上下文\r
+   * @throws Exception\r
+   */\r
+  public static String getVersionName(Context context)  {\r
+    // 获取packagemanager的实例\r
+    PackageManager packageManager = context.getPackageManager();\r
+    // getPackageName()是你当前类的包名\r
+    try {\r
+      PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);\r
+      String version = packInfo.versionName;\r
+      return version;\r
+\r
+    }catch (Exception e){\r
+      e.printStackTrace();\r
+    }\r
+    return "";\r
+  }\r
+\r
+  public static String getVersionCode(Context context)  {\r
+    // 获取packagemanager的实例\r
+    PackageManager packageManager = context.getPackageManager();\r
+    // getPackageName()是你当前类的包名\r
+    try {\r
+      PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);\r
+      String version = "V"+packInfo.versionCode;\r
+      return version;\r
+\r
+    }catch (Exception e){\r
+      e.printStackTrace();\r
+    }\r
+    return "";\r
+  }\r
   public static int getCustomId() {\r
     int i = -1;\r
     try {\r
@@ -143,14 +181,13 @@ public class DeviceInfoUtil {
 \r
   public static String getDeviceInfo(Runtime runtime){\r
 \r
-    int ppg= ICJniUtils.getPPG();\r
     SimSignalUtil sim=SimSignalUtil.getInstance(runtime.getContextProxy().context);\r
     return new StringBuilder()\r
-            .append(TimeUtil.getSystemTime3())\r
-            .append(SimSignalUtil.hasSimCard(runtime.getContextProxy().context)?" SIM ":" NoSIM ")\r
+            .append(TimeUtil.getLocalTime2()).append(" ").append(DeviceInfoUtil.getVersionCode(runtime.getContextProxy().context))\r
+            .append(SimSignalUtil.hasSimCard(runtime.getContextProxy().context)?"\n SIM ":" NoSIM ")\r
             .append(sim.getNetworkType()==SimSignalUtil.IS_2G?"2G":(sim.getNetworkType()==SimSignalUtil.IS_3G)?"3G":(sim.getNetworkType()==SimSignalUtil.IS_4G?"4G":"unknown"))\r
-            .append(" [").append(runtime.getSignalStrength()+100).append(",Mini:").append(SimSignalUtil.getMinSignalStrength(sim.getNetworkType())).append("]")\r
-            .append("\n KeepAlive ").append(KeepAlive.isConnected)\r
+            .append(" [").append(runtime.getSignalStrength()).append(",Mini:").append(SimSignalUtil.getMinSignalStrength(sim.getNetworkType())).append("]")\r
+            .append("\n KeepAlive ").append(KeepAlive.isConnected).append(" , HBcycle ").append(runtime.getHeartBeatCycle())\r
             .append("\n ServerConnected is ").append(runtime.isServerProtocolConnected())\r
             .append(" \n Bat ").append(runtime.getBattery())\r
             .append(" StepCount ").append(runtime.getTotalStepCount())\r
@@ -159,11 +196,32 @@ public class DeviceInfoUtil {
             .append(" \n LocationType ").append(runtime.getLocationInstance().getLocationType())\r
             .append(" at ").append(runtime.getLocationInstance().getLocationTime())\r
             .append(" \n PPGTestCycle ").append(runtime.getPpgTestCycle())\r
-            .append("\n PPGStarted ").append(ICJniUtils.isPPGStarted())\r
-            .append(",weared ").append(ICJniUtils.isWeared())\r
-            .append(",ppg ").append(ppg)\r
-            .append(",bph ").append(ICJniUtils.getHighBloodPressure())\r
-            .append(",bpl ").append(ICJniUtils.getLowBloodPressure())\r
+            .append("\n LastPPG ").append(runtime.getHRS().getPPG())\r
+            .append(",bph ").append(runtime.getHRS().getBPH())\r
+            .append(",bpl ").append(runtime.getHRS().getBPL())\r
+            .append(" at ").append(runtime.getHRS().getTestTime())\r
+            .toString();\r
+  }\r
+  public static String getShortDeviceInfo(Runtime runtime){\r
+\r
+    SimSignalUtil sim=SimSignalUtil.getInstance(runtime.getContextProxy().context);\r
+    return new StringBuilder()\r
+            .append(DeviceInfoUtil.getVersionCode(runtime.getContextProxy().context))\r
+            .append(SimSignalUtil.hasSimCard(runtime.getContextProxy().context)?" ":" NoSIM ")\r
+            .append(sim.getNetworkType()==SimSignalUtil.IS_2G?"2G":(sim.getNetworkType()==SimSignalUtil.IS_3G)?"3G":(sim.getNetworkType()==SimSignalUtil.IS_4G?"4G":"unknown"))\r
+            .append("[").append(runtime.getSignalStrength()).append("]")\r
+            .append("\nHeartbeat[").append(runtime.getSrvIP()).append(":").append(runtime.getPort()).append(",").append(runtime.isServerProtocolConnected()).append(",").append(runtime.getHeartBeatCycle())\r
+            .append("]\nBat").append(runtime.getBattery())\r
+            .append(",Step").append(runtime.getTotalStepCount())\r
+            .append( "\nLocation[M").append(runtime.getLocationInstance().getWorkingMod())\r
+            .append(",C").append(runtime.getLocationInstance().getLocation_cycle())\r
+            .append(",T").append(runtime.getLocationInstance().getLocationType())\r
+            .append(",").append(runtime.getLocationInstance().getLocationTime())\r
+            .append("]\nPPG[C").append(runtime.getPpgTestCycle())\r
+            .append(",P").append(runtime.getHRS().getPPG())\r
+            .append(",H").append(runtime.getHRS().getBPH())\r
+            .append(",L").append(runtime.getHRS().getBPL())\r
+            .append(",").append(runtime.getHRS().getTestTime()).append("]")\r
             .toString();\r
   }\r
 \r
diff --git a/app/src/main/java/com/enqualcomm/support/utils/DnsUtil.java b/app/src/main/java/com/enqualcomm/support/utils/DnsUtil.java
new file mode 100644 (file)
index 0000000..90214af
--- /dev/null
@@ -0,0 +1,205 @@
+package com.enqualcomm.support.utils;\r
+\r
+\r
+import android.content.Context;\r
+import android.os.Handler;\r
+import android.os.Message;\r
+\r
+import com.enqualcomm.support.Config;\r
+import com.enqualcomm.support.bean.DNSTaskModel;\r
+import com.sina.util.dnscache.DNSCache;\r
+import com.sina.util.dnscache.DomainInfo;\r
+import com.sina.util.dnscache.Tools;\r
+import com.sina.util.dnscache.net.ApacheHttpClientNetworkRequests;\r
+import com.sina.util.dnscache.net.INetworkRequests;\r
+import com.sina.util.dnscache.net.networktype.NetworkManager;\r
+\r
+import java.util.HashMap;\r
+import java.util.concurrent.Callable;\r
+import java.util.concurrent.ExecutorService;\r
+import java.util.concurrent.Executors;\r
+\r
+import static com.sina.util.dnscache.AppConfigUtil.getApplicationContext;\r
+\r
+public class DnsUtil  {\r
+\r
+    public long ID_NUMBER = 0 ;\r
+\r
+\r
+    public final ExecutorService fixedThreadPool;\r
+\r
+    public DnsUtil(int size, Context context){\r
+\r
+        DNSCache.Init(context);\r
+        DNSCache.getInstance().preLoadDomains(new String[]{Config.getProtocolServerHost(context)});\r
+\r
+        fixedThreadPool = Executors.newFixedThreadPool(size);\r
+    }\r
+\r
+    public void runTask(final DNSTaskModel model, final Callable<DNSTaskModel> call){\r
+\r
+        fixedThreadPool.execute( new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+                try {\r
+\r
+                    Thread.currentThread().setName("Task Pool");\r
+\r
+                    Logger.log("TAG", "任务开始");\r
+\r
+                    model.taskStartTime = System.currentTimeMillis();\r
+                    model.taskID = ++ID_NUMBER;\r
+\r
+\r
+                    model.domainUrl = model.url ;\r
+                    model.domainIp = java.net.InetAddress.getByName(Tools.getHostName(model.domainUrl)).getHostAddress();\r
+                    INetworkRequests domainNetRequests = new ApacheHttpClientNetworkRequests() ;\r
+                    HashMap<String, String> lmapKey = null ;\r
+                    lmapKey = new HashMap<String, String>();\r
+                    lmapKey.put("Connection", "keep-alive");\r
+\r
+//                    long startDomainRequests = System.currentTimeMillis();\r
+//                    model.domainInputStreamResult = domainNetRequests.requestsByteArr(model.domainUrl,lmapKey) ;\r
+//                    model.domainResult = byteToString(model.domainInputStreamResult) ;\r
+//                    model.domainExpendTime = System.currentTimeMillis() - startDomainRequests ;\r
+//                    model.domainCode = model.domainResult == null ? 500 : 200 ;\r
+\r
+                    try {\r
+                        long startHttpDns = System.currentTimeMillis();\r
+                        DomainInfo[] infoList = DNSCache.getInstance().getDomainServerIp(model.url) ;\r
+//                        model.httpDnsExpendTime = System.currentTimeMillis() - startHttpDns ;\r
+                        if( infoList == null || infoList.length == 0 ){\r
+                            model.httpDnsResult = "null" ;\r
+                        }else{\r
+                            model.domainInfo = infoList;\r
+//                            for( DomainInfo info : infoList ) model.httpDnsResult += Tools.getHostName(info.url) + "、" ;\r
+//\r
+//                            HashMap<String, String> hmapKey = null ;\r
+//                            hmapKey = new HashMap<String, String>();\r
+//                            hmapKey.put("host", infoList[0].host);\r
+\r
+\r
+                            model.hostUrl = infoList[0].url ;\r
+                            model.hostIp = Tools.getHostName(infoList[0].url) ;\r
+//                            INetworkRequests hostNetRequests = new ApacheHttpClientNetworkRequests() ;\r
+//                            long startHostRequests = System.currentTimeMillis();\r
+//\r
+//                            model.hostInputStreamResult = hostNetRequests.requestsByteArr(infoList[0].url, hmapKey) ;\r
+//                            model.hostResult = byteToString(model.hostInputStreamResult) ;\r
+//\r
+//                            model.hostExpendTime = System.currentTimeMillis() - startHostRequests ;\r
+//                            model.hostCode = model.hostResult == null ? 0 : 200 ;\r
+\r
+                        }\r
+                    } catch (Exception e) {\r
+                        e.printStackTrace();\r
+                    }\r
+\r
+\r
+                    try {\r
+\r
+                        // 反馈任务\r
+//                        model.domainInfo[0].code = String.valueOf(model.domainCode) ;\r
+//                        model.domainInfo[0].data = model.domainResult ;\r
+//                        model.domainInfo[0].startTime = String.valueOf(startDomainRequests) ;\r
+////                                           DNSCache.getInstance().setDomainServerIpInfo( model.domainInfo[0] );\r
+//\r
+//                        model.netType = NetworkManager.getInstance().NETWORK_TYPE_STR ;\r
+//                        model.spName = NetworkManager.getInstance().SP_TYPE_STR ;\r
+//\r
+//                        model.status = 1 ;\r
+//                        model.taskStopTime = System.currentTimeMillis();\r
+//                        model.taskExpendTime = model.taskStopTime - model.taskStartTime ;\r
+\r
+                        Logger.log("TAG", "任务结束");\r
+                        call.call();\r
+\r
+                    } catch (Exception e) {\r
+                        // TODO: handle exception\r
+                        e.printStackTrace();\r
+                    }\r
+\r
+\r
+                } catch (Exception e) {\r
+                    Logger.log("TAG", "任务失败");\r
+                    e.printStackTrace();\r
+                }\r
+\r
+//                             try {\r
+//                                     Thread.sleep( (int) (Math.random() * 1000) );\r
+//                             } catch (InterruptedException e) {\r
+//                                     e.printStackTrace();\r
+//                             }\r
+            }\r
+        } );\r
+    }\r
+\r
+\r
+    private String byteToString(byte[] data){\r
+        return new String(data) ;\r
+    }\r
+\r
+    public void reset(){\r
+        ID_NUMBER = 0;\r
+    }\r
+\r
+    public boolean isShutdown() {\r
+        return fixedThreadPool.isShutdown();\r
+    }\r
+\r
+    public void shutdownNow() {\r
+        fixedThreadPool.shutdownNow();\r
+    }\r
+\r
+    public void shutdown() {\r
+        fixedThreadPool.shutdown();\r
+    }\r
+\r
+\r
+\r
+\r
+    // ///////////////////////////////////////////////////////////////\r
+\r
+    int finishTag = 0;\r
+\r
+    public String getServerIP_ByDNSCache(String host) {\r
+\r
+\r
+        DNSTaskModel temp=new DNSTaskModel();\r
+        if (host.toLowerCase().startsWith("http://")) {\r
+            temp.url = host;\r
+        }else{\r
+            temp.url = "http://"+host;\r
+        }\r
+        temp.hostIp=null;\r
+        temp.domainIp=null;\r
+\r
+        Callable<DNSTaskModel> call = new Callable<DNSTaskModel>() {\r
+            @Override\r
+            public DNSTaskModel call() throws Exception {\r
+                Logger.i("get "+temp.url+" "+temp.domainIp+" , DnsCacheIP "+temp.hostIp);\r
+\r
+                return temp;\r
+            }\r
+        };\r
+        runTask(temp, call);\r
+        String ip;\r
+//        Logger.i(temp.toString());\r
+        if (temp.domainIp!=null){\r
+            if (temp.hostIp!=null){\r
+                ip=temp.hostIp.toString();\r
+            }else{\r
+                ip=temp.domainIp.toString();\r
+            }\r
+        }else{\r
+            if(temp.hostIp!=null){\r
+                ip=temp.hostIp.toString();\r
+            }else {\r
+                ip=null;\r
+            }\r
+        }\r
+        return ip;\r
+    }\r
+\r
+}\r
diff --git a/app/src/main/java/com/enqualcomm/support/utils/HttpDnsRecordUtil.java b/app/src/main/java/com/enqualcomm/support/utils/HttpDnsRecordUtil.java
new file mode 100644 (file)
index 0000000..cdc1462
--- /dev/null
@@ -0,0 +1,146 @@
+package com.enqualcomm.support.utils;
+
+
+
+import com.enqualcomm.support.ICApplication;
+import com.enqualcomm.support.bean.DNSTaskModel;
+
+import org.json.JSONException;
+import org.json.JSONStringer;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * httpdns请求数据对比的缓存文件
+ * @author xingyu10
+ *
+ */
+public class HttpDnsRecordUtil {
+
+    private static final String DNS_LOG_FOLDER = "/Android/data/.log/com.sina.util.dnscache/cache/";
+
+    /**
+     * 将任务数缓存至本地
+     * @param model
+     */
+    public static void record(DNSTaskModel model) {
+        File logFolder = getLogFolder();
+        if (null == logFolder) {
+            return;
+        }
+        File writtingFile = getWrittingFile(logFolder);
+        if (null == writtingFile) {
+            return;
+        }
+        FileWriter writer = null;
+        String content = generateLogContent(model);
+        try {
+            writer = new FileWriter(writtingFile, true);
+            String lineSeparator = System.getProperty("line.separator");
+            writer.write(content + lineSeparator);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (writer != null) {
+                    writer.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    /**
+     * 获得最近使用的缓存文件
+     * @return
+     */
+    public static File getRecentlyRecordFile(){
+        File logFolder = getLogFolder();
+        if (null == logFolder) {
+            return null;
+        }
+        return getWrittingFile(logFolder);
+    }
+    /**
+     * 获取所有的缓存文件
+     * @return
+     */
+    public static File[] getRecordFiles(){
+        File logFolder = getLogFolder();
+        if (null == logFolder) {
+            return null;
+        }
+        return logFolder.listFiles();
+    }
+    /**
+     * 删除缓存文件
+     * @return
+     */
+    public static boolean removeFiles(){
+        File logFolder = getLogFolder();
+        if (null == logFolder) {
+            return false;
+        }
+        boolean succ = true;
+        File[] files = logFolder.listFiles();
+        if (null != files) {
+            for (File dstFile : files) {
+                succ &= dstFile.delete();
+            }
+        }
+        return succ;
+    }
+    private static String generateLogContent(DNSTaskModel model) {
+        String result = null;
+        JSONStringer jsonStringer = new JSONStringer();
+        try {
+            jsonStringer.object().key("taskID").value(model.taskID).key("taskExpendTime").value(model.taskExpendTime).key("hostExpendTime")
+                    .value(model.hostExpendTime).key("domainExpendTime").value(model.domainExpendTime).endObject();
+            result = jsonStringer.toString();
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    /**
+     * eg: httpdns.0.log httpdns.1.log
+     * 
+     * @param folder
+     * @return
+     */
+    static File getWrittingFile(File folder) {
+        File file = null;
+        if (null != folder) {
+            String[] list = folder.list();
+            if (null == list || list.length == 0) {
+                file = new File(folder, "httpdns." + 0 + ".log");
+                return file;
+            } else {
+                int lastIndex = list.length - 1;
+                file = new File(folder, "httpdns." + lastIndex + ".log");
+                // 10MB则继续新建
+                if (file.length() > 10 * 1024 * 1024) {
+                    file = new File(folder, "httpdns." + (lastIndex + 1) + ".log");
+                }
+                return file;
+            }
+        }
+        return file;
+    }
+
+    static File getLogFolder() {
+        return createLogFolderIfNecessary();
+    }
+
+    static File createLogFolderIfNecessary() {
+        File cacheDir = StorageUtils.getCacheDirectory(ICApplication.getInstance());
+        File logdir = new File(cacheDir, ".log");
+        if (!logdir.exists()) {
+            logdir.mkdirs();
+        }
+        return logdir;
+    }
+}
diff --git a/app/src/main/java/com/enqualcomm/support/utils/IPtoAddress.java b/app/src/main/java/com/enqualcomm/support/utils/IPtoAddress.java
new file mode 100644 (file)
index 0000000..7e718b9
--- /dev/null
@@ -0,0 +1,133 @@
+package com.enqualcomm.support.utils;
+
+import android.os.Handler;
+import android.os.Message;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class IPtoAddress {
+
+       /////////////////////////////////////////////////////////////////
+       
+       private static IPtoAddress Instance = null;
+
+    private IPtoAddress() { }
+
+    public static IPtoAddress getInstance() {
+
+        if( Instance == null ){
+            Instance = new IPtoAddress();
+        }
+        return IPtoAddress.Instance;
+    }
+    
+       /////////////////////////////////////////////////////////////////
+
+       /**
+     * 缓存初始容量值
+     */
+    private final int INIT_SIZE = 8;
+
+    /**
+     * 缓存最大容量值
+     */
+    private final int MAX_CACHE_SIZE = 32;
+    
+    /**
+     * 缓存链表
+     */
+       private ConcurrentHashMap<String, String> data = new ConcurrentHashMap<String, String>(INIT_SIZE, MAX_CACHE_SIZE);
+
+       private final String API_URL = "http://ip138.com/ips1388.asp?ip=";
+       
+       /////////////////////////////////////////////////////////////////
+
+       public void toAddress( final int id,  final String ip, final Handler handler){
+               
+               String add = data.get(ip) ; 
+               
+               if( add != null ){
+                       
+                       Message message = new Message();
+            message.what = id;
+            message.obj = add;
+            handler.sendMessage(message);
+
+               }else{
+                       
+                       // 请求服务器 查询ip 对应的地址
+                       new Thread( new Runnable() {
+                               
+                               @Override
+                               public void run() {
+                                       // TODO Auto-generated method stub
+                                       Thread.currentThread().setName("IP to AddressAndSp"); 
+                                       
+                                       String result = executeHttpGet(ip) ;
+                                       result = regularAddress(result) ; 
+                                       data.put(ip, result) ; 
+                                       
+                                       Message message = new Message();
+                           message.what = id;
+                           message.obj = result;
+                           handler.sendMessage(message);
+                                       
+                               }
+                       } ).start();
+                       
+               }
+               
+       }
+       
+       private String regularAddress( String result ){
+               String str = "" ; 
+               Pattern p = Pattern.compile("来自:(.*)<br/><br/></td>");  
+               Matcher m = p.matcher(result);  
+               while(m.find()){
+                       str += m.group(1) ; 
+               }
+               return str ; 
+       }
+       
+       private String executeHttpGet( final String ip  ) {
+        String result = null;
+        URL url = null;
+        HttpURLConnection connection = null;
+        InputStreamReader in = null;
+        try {
+            url = new URL(API_URL + ip);
+            connection = (HttpURLConnection) url.openConnection();
+            in = new InputStreamReader(connection.getInputStream(),"gb2312");
+            BufferedReader bufferedReader = new BufferedReader(in);
+            StringBuffer strBuffer = new StringBuffer();
+            String line = null;
+            while ((line = bufferedReader.readLine()) != null) {
+                strBuffer.append(line);
+            }
+            result = strBuffer.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+ 
+        }
+        return result;
+    }
+    
+}
index f731b96..e1162ed 100644 (file)
@@ -206,8 +206,14 @@ public class NettyConnection implements Connection {
   \r
   public void connect(final String host, final int port) {\r
     long l = SystemClock.elapsedRealtime();\r
-    if (l - realtime_old < 3000L)\r
-      return; \r
+    if (host.isEmpty()||host ==null){\r
+        Logger.i("host name error "+host);\r
+        return ;\r
+    }\r
+    if (l - realtime_old < 3000L ) {\r
+        Logger.i("3秒内skip 重连!");\r
+        return;\r
+    }\r
     realtime_old = l;\r
     Logger.i("connect1 "+host+":"+port);\r
 //    disconnect();\r
index 1110418..fc250d8 100644 (file)
@@ -13,8 +13,8 @@ package com.enqualcomm.support.utils;
 public class NetworkObservable {\r
   BroadcastReceiver mNetStateBroadcastReceiver = new BroadcastReceiver() {\r
     public void onReceive(Context var1, Intent var2) {\r
-      NetworkInfo var3 = ((ConnectivityManager)var1.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();\r
-      if (var3 != null && var3.isAvailable()) {\r
+      NetworkInfo networkInfo = ((ConnectivityManager)var1.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();\r
+      if (networkInfo != null && networkInfo.isAvailable()) {\r
         StringBuilder var4 = new StringBuilder();\r
         var4.append("BroadcastReceiver---reConnection++  KeepAlive.isConnected=");\r
         var4.append(KeepAlive.isConnected);\r
@@ -25,6 +25,7 @@ public class NetworkObservable {
         Logger.i(var4.toString());\r
         if (!KeepAlive.isConnected && !NetworkObservable.this.network_is_from_no_to_yes) {\r
           if (NetworkObservable.this.network_is_down) {\r
+\r
             NetworkObservable.this.objectPublishSubject.onNext(3);\r
             NetworkObservable.this.network_is_down = false;\r
           } else {\r
@@ -36,7 +37,6 @@ public class NetworkObservable {
         } else if (KeepAlive.isConnected) {\r
           NetworkObservable.this.network_is_down = false;\r
         }\r
-\r
         NetworkObservable.this.network_is_from_no_to_yes = false;\r
       } else {\r
         Logger.i("网络断开");\r
index 888c359..5c9bb10 100644 (file)
@@ -4,6 +4,8 @@ import android.content.ContentResolver;
 import android.content.Context;\r
 import android.content.Intent;\r
 import android.hardware.display.DisplayManager;\r
+import android.net.ConnectivityManager;\r
+import android.net.NetworkInfo;\r
 import android.os.Build;\r
 import android.os.PowerManager;\r
 import android.provider.Settings;\r
@@ -101,7 +103,51 @@ public class SimSignalUtil {
     stringBuilder.append(paramString);\r
     Logger.i(stringBuilder.toString());\r
   }\r
-  \r
+\r
+  /**\r
+   * 检查用户的网络:是否有网络,所需权限:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>\r
+   */\r
+  public static boolean checkNet(Context context) {\r
+    // 判断:WIFI链接\r
+    boolean isWIFI = isWIFIConnection(context);\r
+    // 判断:Mobile链接\r
+    boolean isMOBILE = isMOBILEConnection(context);\r
+    if (!isWIFI && !isMOBILE) {\r
+      return false;//既不是手机连接,也不是wifi连接\r
+    }\r
+    return true;\r
+  }/**\r
+   * 判断:是否是手机链接\r
+   * @param context\r
+   * @return\r
+   */\r
+  private static boolean isMOBILEConnection(Context context) {\r
+    ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);\r
+    //获取连接的信息\r
+    NetworkInfo networkInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);\r
+    if (networkInfo != null) {\r
+      return networkInfo.isConnected();\r
+    }\r
+    return false;\r
+  }\r
+\r
+  /**\r
+   * 判断:WIFI链接\r
+   *\r
+   * @param context\r
+   * @return\r
+   */\r
+  private static boolean isWIFIConnection(Context context) {\r
+    ConnectivityManager manager = (ConnectivityManager) context\r
+            .getSystemService(Context.CONNECTIVITY_SERVICE);\r
+\r
+    NetworkInfo networkInfo = manager\r
+            .getNetworkInfo(ConnectivityManager.TYPE_WIFI);\r
+    if (networkInfo != null) {\r
+      return networkInfo.isConnected();\r
+    }\r
+    return false;\r
+  }\r
   public int getNetworkType() {\r
     init();\r
     int networktype=IS_UNKNOWN;\r
diff --git a/app/src/main/java/com/enqualcomm/support/utils/StorageUtils.java b/app/src/main/java/com/enqualcomm/support/utils/StorageUtils.java
new file mode 100644 (file)
index 0000000..b19e086
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright 2011-2013 Sergey Tarasevich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+package com.enqualcomm.support.utils;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+import android.os.StatFs;
+
+import java.io.File;
+import java.io.IOException;
+
+import static android.os.Environment.MEDIA_MOUNTED;
+
+/**
+ * Provides application storage paths
+ *
+ * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
+ * @since 1.0.0
+ */
+public final class StorageUtils {
+
+       private static final String EXTERNAL_STORAGE_PERMISSION = "android.permission.WRITE_EXTERNAL_STORAGE";
+       private static final String INDIVIDUAL_DIR_NAME = "uil-images";
+
+       private StorageUtils() {
+       }
+
+       /**
+        * Returns application cache directory. Cache directory will be created on SD card
+        * <i>("/Android/data/[app_package_name]/cache")</i> if card is mounted and app has appropriate permission. Else -
+        * Android defines cache directory on device's file system.
+        *
+        * @param context Application context
+        * @return Cache {@link File directory}.<br />
+        * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
+        * {@link Context#getCacheDir() Context.getCacheDir()} returns null).
+        */
+       public static File getCacheDirectory(Context context) {
+               return getCacheDirectory(context, true);
+       }
+
+       /**
+        * Returns application cache directory. Cache directory will be created on SD card
+        * <i>("/Android/data/[app_package_name]/cache")</i> (if card is mounted and app has appropriate permission) or
+        * on device's file system depending incoming parameters.
+        *
+        * @param context        Application context
+        * @param preferExternal Whether prefer external location for cache
+        * @return Cache {@link File directory}.<br />
+        * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
+        * {@link Context#getCacheDir() Context.getCacheDir()} returns null).
+        */
+       public static File getCacheDirectory(Context context, boolean preferExternal) {
+               File appCacheDir = null;
+               if (preferExternal && MEDIA_MOUNTED
+                               .equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context) && haveFreeSpace()) {
+                       appCacheDir = getExternalCacheDir(context);
+               }
+               if (appCacheDir == null) {
+                       appCacheDir = context.getCacheDir();
+               }
+               if (appCacheDir == null) {
+                       String cacheDirPath = "/data/data/" + context.getPackageName() + "/cache/";
+                       appCacheDir = new File(cacheDirPath);
+               }
+               return appCacheDir;
+       }
+
+       /**
+        * Returns individual application cache directory (for only image caching from ImageLoader). Cache directory will be
+        * created on SD card <i>("/Android/data/[app_package_name]/cache/uil-images")</i> if card is mounted and app has
+        * appropriate permission. Else - Android defines cache directory on device's file system.
+        *
+        * @param context Application context
+        * @return Cache {@link File directory}
+        */
+       public static File getIndividualCacheDirectory(Context context) {
+               File cacheDir = getCacheDirectory(context);
+               File individualCacheDir = new File(cacheDir, INDIVIDUAL_DIR_NAME);
+               if (!individualCacheDir.exists()) {
+                       if (!individualCacheDir.mkdir()) {
+                               individualCacheDir = cacheDir;
+                       }
+               }
+               return individualCacheDir;
+       }
+
+       /**
+        * Returns specified application cache directory. Cache directory will be created on SD card by defined path if card
+        * is mounted and app has appropriate permission. Else - Android defines cache directory on device's file system.
+        *
+        * @param context  Application context
+        * @param cacheDir Cache directory path (e.g.: "AppCacheDir", "AppDir/cache/images")
+        * @return Cache {@link File directory}
+        */
+       public static File getOwnCacheDirectory(Context context, String cacheDir) {
+               File appCacheDir = null;
+               if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && hasExternalStoragePermission(context)) {
+                       appCacheDir = new File(Environment.getExternalStorageDirectory(), cacheDir);
+               }
+               if (appCacheDir == null || (!appCacheDir.exists() && !appCacheDir.mkdirs())) {
+                       appCacheDir = context.getCacheDir();
+               }
+               return appCacheDir;
+       }
+
+       private static File getExternalCacheDir(Context context) {
+               File dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
+               File appCacheDir = new File(new File(dataDir, context.getPackageName()), "cache");
+               if (!appCacheDir.exists()) {
+                       if (!appCacheDir.mkdirs()) {
+                               return null;
+                       }
+                       try {
+                               new File(appCacheDir, ".nomedia").createNewFile();
+                       } catch (IOException e) {
+                       }
+               }
+               return appCacheDir;
+       }
+
+       private static boolean hasExternalStoragePermission(Context context) {
+               int perm = context.checkCallingOrSelfPermission(EXTERNAL_STORAGE_PERMISSION);
+               return perm == PackageManager.PERMISSION_GRANTED;
+       }
+
+       private static boolean haveFreeSpace() {
+        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            StatFs st = new StatFs(Environment.getExternalStorageDirectory().getPath());
+            int blockSize = st.getBlockSize();
+            long available = st.getAvailableBlocks();
+            long availableSize = (blockSize * available);
+            if (availableSize < 1024 * 1024 * 10) {// //sd卡空间如果小于10M,就认为sd卡空间不足
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+}
index b30642b..5c6afb1 100644 (file)
@@ -10,7 +10,10 @@ public class TimeUtil {
   public static String getLocalTime() { return getLocalTime(System.currentTimeMillis()); }\r
   \r
   public static String getLocalTime(long paramLong) { return (new SimpleDateFormat("yyyy/MM/dd,HH:mm:ss")).format(new Date(paramLong)); }\r
-  \r
+  public static String getLocalTime2() { return getLocalTime2(System.currentTimeMillis()); }\r
+\r
+  public static String getLocalTime2(long paramLong) { return (new SimpleDateFormat("MMddHHmmss")).format(new Date(paramLong)); }\r
+\r
   public static String getSystemTime() { return getSystemTime(System.currentTimeMillis()); }\r
   \r
   public static String getSystemTime(long paramLong) { return (new SimpleDateFormat("yyyy-MM-dd;HH:mm:ss")).format(new Date(paramLong)); }\r
index a539735..88560fc 100644 (file)
@@ -42,6 +42,7 @@ public class Util {
   public static Charset UTF_8 = Charset.forName("UTF-8");\r
 \r
 \r
+\r
   /**\r
    * 解析域名获取IP数组\r
    * @param host\r
@@ -50,6 +51,8 @@ public class Util {
   public static String parseHostGetIPAddress(String host) {\r
     StringBuilder serverip=new StringBuilder("");\r
     try {\r
+\r
+\r
       InetAddress[] inetAddressArr = InetAddress.getAllByName(host);\r
       if (inetAddressArr != null && inetAddressArr.length > 0) {\r
         String[] ipAddressArr = new String[inetAddressArr.length];\r
index c9bc6a9..0bb413a 100644 (file)
@@ -1,2 +1,2 @@
-#Mon Feb 10 23:47:07 CST 2020\r
-VERSION_CODE=348\r
+#Wed Feb 12 23:18:01 CST 2020\r
+VERSION_CODE=351\r
diff --git a/dNSCache/build.gradle b/dNSCache/build.gradle
new file mode 100644 (file)
index 0000000..f62c888
--- /dev/null
@@ -0,0 +1,38 @@
+apply plugin: 'com.android.library'\r
+\r
+android {\r
+    compileSdkVersion 18\r
+    buildToolsVersion "28.0.3"\r
+\r
+    defaultConfig {\r
+    }\r
+\r
+    buildTypes {\r
+        release {\r
+            zipAlignEnabled true     // zip 对齐优化\r
+//            shrinkResources true       // 移除未使用的资源文件\r
+//            signingConfig signingConfigs.key\r
+            minifyEnabled true\r
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\r
+            renderscriptDebuggable = false\r
+            debuggable = false\r
+            jniDebuggable = false\r
+            manifestPlaceholders = [:]\r
+        }\r
+\r
+        debug {\r
+//            signingConfig signingConfigs.key\r
+            // 启用 Android 插件压缩器\r
+//            minifyEnabled true\r
+//            useProguard false\r
+        }\r
+        compileOptions {\r
+            sourceCompatibility JavaVersion.VERSION_1_8\r
+            targetCompatibility JavaVersion.VERSION_1_8\r
+        }\r
+    }\r
+}\r
+\r
+dependencies {\r
+    compile 'com.android.support:support-v4:18.0.0'\r
+}\r
diff --git a/dNSCache/build/.transforms/7c72370c09d54379f48fb03517858be0.bin b/dNSCache/build/.transforms/7c72370c09d54379f48fb03517858be0.bin
new file mode 100644 (file)
index 0000000..47444ea
--- /dev/null
@@ -0,0 +1 @@
+o/classes\r
diff --git a/dNSCache/build/.transforms/7c72370c09d54379f48fb03517858be0/classes/classes.dex b/dNSCache/build/.transforms/7c72370c09d54379f48fb03517858be0/classes/classes.dex
new file mode 100644 (file)
index 0000000..eace692
Binary files /dev/null and b/dNSCache/build/.transforms/7c72370c09d54379f48fb03517858be0/classes/classes.dex differ
diff --git a/dNSCache/build/generated/source/buildConfig/debug/com/sina/util/dnscache/BuildConfig.java b/dNSCache/build/generated/source/buildConfig/debug/com/sina/util/dnscache/BuildConfig.java
new file mode 100644 (file)
index 0000000..be892cb
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * Automatically generated file. DO NOT MODIFY
+ */
+package com.sina.util.dnscache;
+
+public final class BuildConfig {
+  public static final boolean DEBUG = Boolean.parseBoolean("true");
+  public static final String LIBRARY_PACKAGE_NAME = "com.sina.util.dnscache";
+  /**
+   * @deprecated APPLICATION_ID is misleading in libraries. For the library package name use LIBRARY_PACKAGE_NAME
+   */
+  @Deprecated
+  public static final String APPLICATION_ID = "com.sina.util.dnscache";
+  public static final String BUILD_TYPE = "debug";
+  public static final String FLAVOR = "";
+  public static final int VERSION_CODE = -1;
+  public static final String VERSION_NAME = "";
+}
diff --git a/dNSCache/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml b/dNSCache/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..8e11f7b
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
+    package="com.sina.util.dnscache" >\r
+\r
+    <!-- 需要配置的权限 -->\r
+    <uses-permission android:name="android.permission.INTERNET" />\r
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />\r
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />\r
+    <uses-permission android:name="android.permission.WAKE_LOCK" />\r
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />\r
+\r
+    <application android:label="@string/app_name" >\r
+\r
+        <!-- 主要注册一个广播 -->\r
+        <!-- <receiver -->\r
+        <!-- android:name="com.sina.util.networktype.NetworkStateReceiver" -->\r
+        <!-- android:label="NetworkConnection" > -->\r
+        <!-- <intent-filter> -->\r
+        <!-- <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> -->\r
+        <!-- <action android:name="android.intent.action.USER_PRESENT" /> -->\r
+        <!-- </intent-filter> -->\r
+        <!-- </receiver> -->\r
+\r
+    </application>\r
+\r
+</manifest>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output.json b/dNSCache/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output.json
new file mode 100644 (file)
index 0000000..6cfc855
--- /dev/null
@@ -0,0 +1 @@
+[{"outputType":{"type":"AAPT_FRIENDLY_MERGED_MANIFESTS"},"apkData":{"type":"MAIN","splits":[],"versionCode":-1,"enabled":true,"outputFile":"dNSCache-debug.aar","fullName":"debug","baseName":"debug"},"path":"AndroidManifest.xml","properties":{"packageId":"com.sina.util.dnscache","split":""}}]
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/annotation_processor_list/debug/annotationProcessors.json b/dNSCache/build/intermediates/annotation_processor_list/debug/annotationProcessors.json
new file mode 100644 (file)
index 0000000..9e26dfe
--- /dev/null
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt b/dNSCache/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dNSCache/build/intermediates/compile_library_classes/debug/classes.jar b/dNSCache/build/intermediates/compile_library_classes/debug/classes.jar
new file mode 100644 (file)
index 0000000..8a891a6
Binary files /dev/null and b/dNSCache/build/intermediates/compile_library_classes/debug/classes.jar differ
diff --git a/dNSCache/build/intermediates/compile_only_not_namespaced_r_class_jar/debug/R.jar b/dNSCache/build/intermediates/compile_only_not_namespaced_r_class_jar/debug/R.jar
new file mode 100644 (file)
index 0000000..80118d5
Binary files /dev/null and b/dNSCache/build/intermediates/compile_only_not_namespaced_r_class_jar/debug/R.jar differ
diff --git a/dNSCache/build/intermediates/incremental/debug-mergeJavaRes/merge-state b/dNSCache/build/intermediates/incremental/debug-mergeJavaRes/merge-state
new file mode 100644 (file)
index 0000000..89cd654
Binary files /dev/null and b/dNSCache/build/intermediates/incremental/debug-mergeJavaRes/merge-state differ
diff --git a/dNSCache/build/intermediates/incremental/debug-mergeNativeLibs/merge-state b/dNSCache/build/intermediates/incremental/debug-mergeNativeLibs/merge-state
new file mode 100644 (file)
index 0000000..099787d
Binary files /dev/null and b/dNSCache/build/intermediates/incremental/debug-mergeNativeLibs/merge-state differ
diff --git a/dNSCache/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml b/dNSCache/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml
new file mode 100644 (file)
index 0000000..006fe5d
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\main\jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\debug\jniLibs"/></dataSet></merger>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/incremental/mergeDebugShaders/merger.xml b/dNSCache/build/intermediates/incremental/mergeDebugShaders/merger.xml
new file mode 100644 (file)
index 0000000..df37308
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\main\shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\debug\shaders"/></dataSet></merger>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/incremental/packageDebugAssets/merger.xml b/dNSCache/build/intermediates/incremental/packageDebugAssets/merger.xml
new file mode 100644 (file)
index 0000000..09739c7
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\main\assets"/><source path="D:\Snicker\icsupport\dNSCache\build\intermediates\shader_assets\debug\compileDebugShaders\out"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\debug\assets"/></dataSet></merger>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/incremental/packageDebugResources/compile-file-map.properties b/dNSCache/build/intermediates/incremental/packageDebugResources/compile-file-map.properties
new file mode 100644 (file)
index 0000000..1eaa4d5
--- /dev/null
@@ -0,0 +1,7 @@
+#Thu Feb 13 00:47:58 CST 2020\r
+D\:\\Snicker\\icsupport\\dNSCache\\src\\main\\res\\layout\\activity_main.xml=D\:\\Snicker\\icsupport\\dNSCache\\build\\intermediates\\packaged_res\\debug\\layout\\activity_main.xml\r
+D\:\\Snicker\\icsupport\\dNSCache\\src\\main\\res\\drawable-hdpi\\ic_launcher.png=D\:\\Snicker\\icsupport\\dNSCache\\build\\intermediates\\packaged_res\\debug\\drawable-hdpi-v4\\ic_launcher.png\r
+D\:\\Snicker\\icsupport\\dNSCache\\src\\main\\res\\drawable-mdpi\\ic_launcher.png=D\:\\Snicker\\icsupport\\dNSCache\\build\\intermediates\\packaged_res\\debug\\drawable-mdpi-v4\\ic_launcher.png\r
+D\:\\Snicker\\icsupport\\dNSCache\\src\\main\\res\\drawable-xhdpi\\ic_launcher.png=D\:\\Snicker\\icsupport\\dNSCache\\build\\intermediates\\packaged_res\\debug\\drawable-xhdpi-v4\\ic_launcher.png\r
+D\:\\Snicker\\icsupport\\dNSCache\\src\\main\\res\\menu\\menu_main.xml=D\:\\Snicker\\icsupport\\dNSCache\\build\\intermediates\\packaged_res\\debug\\menu\\menu_main.xml\r
+D\:\\Snicker\\icsupport\\dNSCache\\src\\main\\res\\drawable-xxhdpi\\ic_launcher.png=D\:\\Snicker\\icsupport\\dNSCache\\build\\intermediates\\packaged_res\\debug\\drawable-xxhdpi-v4\\ic_launcher.png\r
diff --git a/dNSCache/build/intermediates/incremental/packageDebugResources/merged.dir/values/values.xml b/dNSCache/build/intermediates/incremental/packageDebugResources/merged.dir/values/values.xml
new file mode 100644 (file)
index 0000000..8b673cf
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="action_clear">清除缓存</string>
+    <string name="action_printf_domain">打印域名表</string>
+    <string name="action_printf_ip">打印IP表</string>
+    <string name="action_settings">参数设置</string>
+    <string name="app_name">DNSCache</string>
+    <string name="hello_world">Hello world!</string>
+</resources>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/incremental/packageDebugResources/merger.xml b/dNSCache/build/intermediates/incremental/packageDebugResources/merger.xml
new file mode 100644 (file)
index 0000000..2718748
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\main\res"/><source path="D:\Snicker\icsupport\dNSCache\build\generated\res\rs\debug"/><source path="D:\Snicker\icsupport\dNSCache\build\generated\res\resValues\debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\main\res"><file name="ic_launcher" path="D:\Snicker\icsupport\dNSCache\src\main\res\drawable-hdpi\ic_launcher.png" qualifiers="hdpi-v4" type="drawable"/><file name="ic_launcher" path="D:\Snicker\icsupport\dNSCache\src\main\res\drawable-mdpi\ic_launcher.png" qualifiers="mdpi-v4" type="drawable"/><file name="ic_launcher" path="D:\Snicker\icsupport\dNSCache\src\main\res\drawable-xhdpi\ic_launcher.png" qualifiers="xhdpi-v4" type="drawable"/><file name="ic_launcher" path="D:\Snicker\icsupport\dNSCache\src\main\res\drawable-xxhdpi\ic_launcher.png" qualifiers="xxhdpi-v4" type="drawable"/><file name="activity_main" path="D:\Snicker\icsupport\dNSCache\src\main\res\layout\activity_main.xml" qualifiers="" type="layout"/><file name="menu_main" path="D:\Snicker\icsupport\dNSCache\src\main\res\menu\menu_main.xml" qualifiers="" type="menu"/><file path="D:\Snicker\icsupport\dNSCache\src\main\res\values\strings.xml" qualifiers=""><string name="app_name">DNSCache</string><string name="hello_world">Hello world!</string><string name="action_printf_domain">打印域名表</string><string name="action_printf_ip">打印IP表</string><string name="action_clear">清除缓存</string><string name="action_settings">参数设置</string></file></source><source path="D:\Snicker\icsupport\dNSCache\build\generated\res\rs\debug"/><source path="D:\Snicker\icsupport\dNSCache\build\generated\res\resValues\debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\debug\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Snicker\icsupport\dNSCache\src\debug\res"/></dataSet><mergedItems/></merger>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/AppConfigUtil.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/AppConfigUtil.class
new file mode 100644 (file)
index 0000000..a673e40
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/AppConfigUtil.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/BuildConfig.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/BuildConfig.class
new file mode 100644 (file)
index 0000000..c2e1a4b
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/BuildConfig.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$1.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$1.class
new file mode 100644 (file)
index 0000000..df2d827
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$1.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$2.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$2.class
new file mode 100644 (file)
index 0000000..8ef1b4d
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$2.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$LogUpLoadTask.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$LogUpLoadTask.class
new file mode 100644 (file)
index 0000000..1dfeae4
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$LogUpLoadTask.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$SpeedTestTask.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$SpeedTestTask.class
new file mode 100644 (file)
index 0000000..087b1bd
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$SpeedTestTask.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$UpdateTask.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$UpdateTask.class
new file mode 100644 (file)
index 0000000..a58e0f7
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache$UpdateTask.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache.class
new file mode 100644 (file)
index 0000000..1160fb7
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCache.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$1.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$1.class
new file mode 100644 (file)
index 0000000..2bfa8f1
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$1.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$Data.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$Data.class
new file mode 100644 (file)
index 0000000..b58d62a
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig$Data.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig.class
new file mode 100644 (file)
index 0000000..359354a
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DNSCacheConfig.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DomainInfo.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DomainInfo.class
new file mode 100644 (file)
index 0000000..11d1cca
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/DomainInfo.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/Tools.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/Tools.class
new file mode 100644 (file)
index 0000000..5c236d8
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/Tools.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DBConstants.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DBConstants.class
new file mode 100644 (file)
index 0000000..83a8fa7
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DBConstants.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DNSCacheDatabaseHelper.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DNSCacheDatabaseHelper.class
new file mode 100644 (file)
index 0000000..f2a2ae9
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DNSCacheDatabaseHelper.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DnsCacheManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DnsCacheManager.class
new file mode 100644 (file)
index 0000000..0343201
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/DnsCacheManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/IDnsCache.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/IDnsCache.class
new file mode 100644 (file)
index 0000000..359ae31
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/cache/IDnsCache.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsConfig.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsConfig.class
new file mode 100644 (file)
index 0000000..a7531f2
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsConfig.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager$1.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager$1.class
new file mode 100644 (file)
index 0000000..2493578
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager$1.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager.class
new file mode 100644 (file)
index 0000000..a8829b9
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/DnsManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDns.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDns.class
new file mode 100644 (file)
index 0000000..cd808d7
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDns.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDnsProvider.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDnsProvider.class
new file mode 100644 (file)
index 0000000..52fc135
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IDnsProvider.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser$JavaJSON_SINAHTTPDNS.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser$JavaJSON_SINAHTTPDNS.class
new file mode 100644 (file)
index 0000000..c4e376e
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser$JavaJSON_SINAHTTPDNS.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser.class
new file mode 100644 (file)
index 0000000..6e3ba5b
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/IJsonParser.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns$DNSPodCipher.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns$DNSPodCipher.class
new file mode 100644 (file)
index 0000000..2f55c33
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns$DNSPodCipher.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns.class
new file mode 100644 (file)
index 0000000..ae90f19
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/HttpPodDns.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/LocalDns.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/LocalDns.class
new file mode 100644 (file)
index 0000000..cedb31d
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/LocalDns.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/SinaHttpDns.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/SinaHttpDns.class
new file mode 100644 (file)
index 0000000..4734896
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/SinaHttpDns.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient$UdpDnsInfo.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient$UdpDnsInfo.class
new file mode 100644 (file)
index 0000000..fa83237
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient$UdpDnsInfo.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient.class
new file mode 100644 (file)
index 0000000..8bbbd68
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns$UdnDnsClient.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns.class
new file mode 100644 (file)
index 0000000..c61dc68
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/dnsp/impl/UdpDns.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/FileUtil.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/FileUtil.class
new file mode 100644 (file)
index 0000000..f7e39c6
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/FileUtil.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager$1.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager$1.class
new file mode 100644 (file)
index 0000000..b0081f3
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager$1.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager.class
new file mode 100644 (file)
index 0000000..640fbf7
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/HttpDnsLogManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/IDnsLog.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/IDnsLog.class
new file mode 100644 (file)
index 0000000..cb70c99
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/log/IDnsLog.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/ConnectFailModel.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/ConnectFailModel.class
new file mode 100644 (file)
index 0000000..971cacc
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/ConnectFailModel.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/DomainModel.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/DomainModel.class
new file mode 100644 (file)
index 0000000..9613b01
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/DomainModel.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack$IP.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack$IP.class
new file mode 100644 (file)
index 0000000..d283d6d
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack$IP.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack.class
new file mode 100644 (file)
index 0000000..48e1601
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/HttpDnsPack.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/IpModel.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/IpModel.class
new file mode 100644 (file)
index 0000000..497e007
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/model/IpModel.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/ApacheHttpClientNetworkRequests.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/ApacheHttpClientNetworkRequests.class
new file mode 100644 (file)
index 0000000..7685094
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/ApacheHttpClientNetworkRequests.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/INetworkRequests.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/INetworkRequests.class
new file mode 100644 (file)
index 0000000..cd2bda6
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/INetworkRequests.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/Constants.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/Constants.class
new file mode 100644 (file)
index 0000000..58bdb2e
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/Constants.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$1.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$1.class
new file mode 100644 (file)
index 0000000..945d049
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$1.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$Util.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$Util.class
new file mode 100644 (file)
index 0000000..e120d6b
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager$Util.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager.class
new file mode 100644 (file)
index 0000000..00f2584
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.class
new file mode 100644 (file)
index 0000000..c865a5f
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/IQuery.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/IQuery.class
new file mode 100644 (file)
index 0000000..f93f428
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/IQuery.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/QueryManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/QueryManager.class
new file mode 100644 (file)
index 0000000..11690c1
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/query/QueryManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IPlugIn.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IPlugIn.class
new file mode 100644 (file)
index 0000000..468be48
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IPlugIn.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IScore.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IScore.class
new file mode 100644 (file)
index 0000000..1fda064
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/IScore.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager$IpModelSort.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager$IpModelSort.class
new file mode 100644 (file)
index 0000000..3b3d313
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager$IpModelSort.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager.class
new file mode 100644 (file)
index 0000000..7176ff4
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/PlugInManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/ScoreManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/ScoreManager.class
new file mode 100644 (file)
index 0000000..4108138
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/ScoreManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/ErrNumPlugin.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/ErrNumPlugin.class
new file mode 100644 (file)
index 0000000..094c2ec
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/ErrNumPlugin.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/PriorityPlugin.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/PriorityPlugin.class
new file mode 100644 (file)
index 0000000..e179024
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/PriorityPlugin.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.class
new file mode 100644 (file)
index 0000000..eaaee41
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.class
new file mode 100644 (file)
index 0000000..2eba85b
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.class
new file mode 100644 (file)
index 0000000..7439340
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/BaseSpeedTest.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/BaseSpeedTest.class
new file mode 100644 (file)
index 0000000..27fe6c6
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/BaseSpeedTest.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/ISpeedtest.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/ISpeedtest.class
new file mode 100644 (file)
index 0000000..698c92c
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/ISpeedtest.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager$1.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager$1.class
new file mode 100644 (file)
index 0000000..1a6a62c
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager$1.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager.class
new file mode 100644 (file)
index 0000000..c295a39
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/SpeedtestManager.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest$Ping.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest$Ping.class
new file mode 100644 (file)
index 0000000..bc404ae
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest$Ping.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest.class
new file mode 100644 (file)
index 0000000..bcfa8d8
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/PingTest.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/Socket80Test.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/Socket80Test.class
new file mode 100644 (file)
index 0000000..1deb329
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/speedtest/impl/Socket80Test.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool$DefaultThreadFactory.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool$DefaultThreadFactory.class
new file mode 100644 (file)
index 0000000..9ea5f4b
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool$DefaultThreadFactory.class differ
diff --git a/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool.class b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool.class
new file mode 100644 (file)
index 0000000..94a320e
Binary files /dev/null and b/dNSCache/build/intermediates/javac/debug/classes/com/sina/util/dnscache/thread/RealTimeThreadPool.class differ
diff --git a/dNSCache/build/intermediates/library_java_res/debug/res.jar b/dNSCache/build/intermediates/library_java_res/debug/res.jar
new file mode 100644 (file)
index 0000000..15cb0ec
Binary files /dev/null and b/dNSCache/build/intermediates/library_java_res/debug/res.jar differ
diff --git a/dNSCache/build/intermediates/library_manifest/debug/AndroidManifest.xml b/dNSCache/build/intermediates/library_manifest/debug/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..8e11f7b
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
+    package="com.sina.util.dnscache" >\r
+\r
+    <!-- 需要配置的权限 -->\r
+    <uses-permission android:name="android.permission.INTERNET" />\r
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />\r
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />\r
+    <uses-permission android:name="android.permission.WAKE_LOCK" />\r
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />\r
+\r
+    <application android:label="@string/app_name" >\r
+\r
+        <!-- 主要注册一个广播 -->\r
+        <!-- <receiver -->\r
+        <!-- android:name="com.sina.util.networktype.NetworkStateReceiver" -->\r
+        <!-- android:label="NetworkConnection" > -->\r
+        <!-- <intent-filter> -->\r
+        <!-- <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> -->\r
+        <!-- <action android:name="android.intent.action.USER_PRESENT" /> -->\r
+        <!-- </intent-filter> -->\r
+        <!-- </receiver> -->\r
+\r
+    </application>\r
+\r
+</manifest>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/local_only_symbol_list/debug/parseDebugLibraryResources/R-def.txt b/dNSCache/build/intermediates/local_only_symbol_list/debug/parseDebugLibraryResources/R-def.txt
new file mode 100644 (file)
index 0000000..029dadc
--- /dev/null
@@ -0,0 +1,18 @@
+R_DEF: Internal format may change without notice
+local
+drawable ic_launcher
+id action_clear
+id action_printf_domain
+id action_printf_ip
+id action_settings
+id button
+id editText
+id textView
+layout activity_main
+menu menu_main
+string action_clear
+string action_printf_domain
+string action_printf_ip
+string action_settings
+string app_name
+string hello_world
diff --git a/dNSCache/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt b/dNSCache/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt
new file mode 100644 (file)
index 0000000..6c0736a
--- /dev/null
@@ -0,0 +1,38 @@
+1<?xml version="1.0" encoding="utf-8"?>
+2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+3    package="com.sina.util.dnscache" >
+4
+5    <!-- 需要配置的权限 -->
+6    <uses-permission android:name="android.permission.INTERNET" />
+6-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:24:5-67
+6-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:24:22-64
+7    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+7-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:25:5-79
+7-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:25:22-76
+8    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+8-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:26:5-76
+8-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:26:22-73
+9    <uses-permission android:name="android.permission.WAKE_LOCK" />
+9-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:27:5-68
+9-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:27:22-65
+10    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+10-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:28:5-81
+10-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:28:22-78
+11
+12    <application android:label="@string/app_name" >
+12-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:5:5-21:19
+12-->D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:8:9-41
+13
+14        <!-- 主要注册一个广播 -->
+15        <!-- <receiver -->
+16        <!-- android:name="com.sina.util.networktype.NetworkStateReceiver" -->
+17        <!-- android:label="NetworkConnection" > -->
+18        <!-- <intent-filter> -->
+19        <!-- <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> -->
+20        <!-- <action android:name="android.intent.action.USER_PRESENT" /> -->
+21        <!-- </intent-filter> -->
+22        <!-- </receiver> -->
+23
+24    </application>
+25
+26</manifest>
diff --git a/dNSCache/build/intermediates/merged_java_res/debug/out.jar b/dNSCache/build/intermediates/merged_java_res/debug/out.jar
new file mode 100644 (file)
index 0000000..15cb0ec
Binary files /dev/null and b/dNSCache/build/intermediates/merged_java_res/debug/out.jar differ
diff --git a/dNSCache/build/intermediates/merged_manifests/debug/output.json b/dNSCache/build/intermediates/merged_manifests/debug/output.json
new file mode 100644 (file)
index 0000000..ce58c9f
--- /dev/null
@@ -0,0 +1 @@
+[{"outputType":{"type":"MERGED_MANIFESTS"},"apkData":{"type":"MAIN","splits":[],"versionCode":-1,"enabled":true,"outputFile":"dNSCache-debug.aar","fullName":"debug","baseName":"debug"},"path":"..\\..\\library_manifest\\debug\\AndroidManifest.xml","properties":{"packageId":"com.sina.util.dnscache","split":""}}]
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/packaged-classes/debug/classes.jar b/dNSCache/build/intermediates/packaged-classes/debug/classes.jar
new file mode 100644 (file)
index 0000000..8a891a6
Binary files /dev/null and b/dNSCache/build/intermediates/packaged-classes/debug/classes.jar differ
diff --git a/dNSCache/build/intermediates/packaged_res/debug/drawable-hdpi-v4/ic_launcher.png b/dNSCache/build/intermediates/packaged_res/debug/drawable-hdpi-v4/ic_launcher.png
new file mode 100644 (file)
index 0000000..288b665
Binary files /dev/null and b/dNSCache/build/intermediates/packaged_res/debug/drawable-hdpi-v4/ic_launcher.png differ
diff --git a/dNSCache/build/intermediates/packaged_res/debug/drawable-mdpi-v4/ic_launcher.png b/dNSCache/build/intermediates/packaged_res/debug/drawable-mdpi-v4/ic_launcher.png
new file mode 100644 (file)
index 0000000..6ae570b
Binary files /dev/null and b/dNSCache/build/intermediates/packaged_res/debug/drawable-mdpi-v4/ic_launcher.png differ
diff --git a/dNSCache/build/intermediates/packaged_res/debug/drawable-xhdpi-v4/ic_launcher.png b/dNSCache/build/intermediates/packaged_res/debug/drawable-xhdpi-v4/ic_launcher.png
new file mode 100644 (file)
index 0000000..d4fb7cd
Binary files /dev/null and b/dNSCache/build/intermediates/packaged_res/debug/drawable-xhdpi-v4/ic_launcher.png differ
diff --git a/dNSCache/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/ic_launcher.png b/dNSCache/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/ic_launcher.png
new file mode 100644 (file)
index 0000000..85a6081
Binary files /dev/null and b/dNSCache/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/ic_launcher.png differ
diff --git a/dNSCache/build/intermediates/packaged_res/debug/layout/activity_main.xml b/dNSCache/build/intermediates/packaged_res/debug/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..26e19b8
--- /dev/null
@@ -0,0 +1,27 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".MainActivity" >
+
+    <TextView
+        android:id="@+id/textView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text=" 输入一个需要测试的API URL:" />
+
+    <EditText
+        android:id="@+id/editText"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:text="http://api.weibo.cn/2/remind/unread_count?remind_version=94&amp;ext_all=0&amp;c=android&amp;i=f6fd268&amp;s=7fe80de0&amp;ua=Xiaomi-MI%203W__weibo__5.3.0_alpha1__android__android4.4.4&amp;wm=3333_1001&amp;idc=&amp;v_f=2&amp;from=1052895010&amp;gsid=_2A254Mx_tDeTxGeNM7lMY9ybEzD6IHXVZaRQlrDV6PUJbrdANLVfzkWo8pgH_awAHMa74PMGrs-jUSB8TTg..&amp;lang=zh_CN&amp;skin=default&amp;oldwm=3333_1001&amp;with_settings=1&amp;unread_message=1&amp;with_page_group=1" />
+
+    <Button
+        android:id="@+id/button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="测试" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/packaged_res/debug/menu/menu_main.xml b/dNSCache/build/intermediates/packaged_res/debug/menu/menu_main.xml
new file mode 100644 (file)
index 0000000..503537b
--- /dev/null
@@ -0,0 +1,17 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
+
+    <item android:id="@+id/action_clear" android:title="@string/action_clear"
+        android:orderInCategory="100" />
+
+    <item android:id="@+id/action_printf_domain" android:title="@string/action_printf_domain"
+        android:orderInCategory="100" />
+
+    <item android:id="@+id/action_printf_ip" android:title="@string/action_printf_ip"
+        android:orderInCategory="100" />
+
+    <item android:id="@+id/action_settings" android:title="@string/action_settings"
+        android:orderInCategory="100" />
+
+</menu>
diff --git a/dNSCache/build/intermediates/packaged_res/debug/values/values.xml b/dNSCache/build/intermediates/packaged_res/debug/values/values.xml
new file mode 100644 (file)
index 0000000..8b673cf
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="action_clear">清除缓存</string>
+    <string name="action_printf_domain">打印域名表</string>
+    <string name="action_printf_ip">打印IP表</string>
+    <string name="action_settings">参数设置</string>
+    <string name="app_name">DNSCache</string>
+    <string name="hello_world">Hello world!</string>
+</resources>
\ No newline at end of file
diff --git a/dNSCache/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt b/dNSCache/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt
new file mode 100644 (file)
index 0000000..8865076
--- /dev/null
@@ -0,0 +1,17 @@
+com.sina.util.dnscache
+drawable ic_launcher
+id action_clear
+id action_printf_domain
+id action_printf_ip
+id action_settings
+id button
+id editText
+id textView
+layout activity_main
+menu menu_main
+string action_clear
+string action_printf_domain
+string action_printf_ip
+string action_settings
+string app_name
+string hello_world
diff --git a/dNSCache/build/intermediates/runtime_library_classes/debug/classes.jar b/dNSCache/build/intermediates/runtime_library_classes/debug/classes.jar
new file mode 100644 (file)
index 0000000..8a891a6
Binary files /dev/null and b/dNSCache/build/intermediates/runtime_library_classes/debug/classes.jar differ
diff --git a/dNSCache/build/intermediates/symbols/debug/R.txt b/dNSCache/build/intermediates/symbols/debug/R.txt
new file mode 100644 (file)
index 0000000..edd87b4
--- /dev/null
@@ -0,0 +1,16 @@
+int drawable ic_launcher 0x7f080001
+int id action_clear 0x7f0b0001
+int id action_printf_domain 0x7f0b0002
+int id action_printf_ip 0x7f0b0003
+int id action_settings 0x7f0b0004
+int id button 0x7f0b0005
+int id editText 0x7f0b0006
+int id textView 0x7f0b0007
+int layout activity_main 0x7f0e0001
+int menu menu_main 0x7f0f0001
+int string action_clear 0x7f140001
+int string action_printf_domain 0x7f140002
+int string action_printf_ip 0x7f140003
+int string action_settings 0x7f140004
+int string app_name 0x7f140005
+int string hello_world 0x7f140006
diff --git a/dNSCache/build/outputs/aar/dNSCache-debug.aar b/dNSCache/build/outputs/aar/dNSCache-debug.aar
new file mode 100644 (file)
index 0000000..cdcf1b3
Binary files /dev/null and b/dNSCache/build/outputs/aar/dNSCache-debug.aar differ
diff --git a/dNSCache/build/outputs/logs/manifest-merger-debug-report.txt b/dNSCache/build/outputs/logs/manifest-merger-debug-report.txt
new file mode 100644 (file)
index 0000000..f3a3912
--- /dev/null
@@ -0,0 +1,35 @@
+-- Merging decision tree log ---
+manifest
+ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:2:1-30:12
+INJECTED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:2:1-30:12
+INJECTED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:2:1-30:12
+       package
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:3:5-37
+               INJECTED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml
+               INJECTED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml
+       xmlns:android
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:2:11-69
+application
+ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:5:5-21:19
+       android:label
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:8:9-41
+uses-permission#android.permission.INTERNET
+ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:24:5-67
+       android:name
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:24:22-64
+uses-permission#android.permission.ACCESS_NETWORK_STATE
+ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:25:5-79
+       android:name
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:25:22-76
+uses-permission#android.permission.ACCESS_WIFI_STATE
+ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:26:5-76
+       android:name
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:26:22-73
+uses-permission#android.permission.WAKE_LOCK
+ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:27:5-68
+       android:name
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:27:22-65
+uses-permission#android.permission.WRITE_EXTERNAL_STORAGE
+ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:28:5-81
+       android:name
+               ADDED from D:\Snicker\icsupport\dNSCache\src\main\AndroidManifest.xml:28:22-78
diff --git a/dNSCache/dNSCache.iml b/dNSCache/dNSCache.iml
new file mode 100644 (file)
index 0000000..9e1eb97
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<module external.linked.project.id=":dNSCache" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">\r
+  <component name="FacetManager">\r
+    <facet type="android-gradle" name="Android-Gradle">\r
+      <configuration>\r
+        <option name="GRADLE_PROJECT_PATH" value=":dNSCache" />\r
+        <option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" value="3.5.3" />\r
+        <option name="LAST_KNOWN_AGP_VERSION" value="3.5.3" />\r
+      </configuration>\r
+    </facet>\r
+    <facet type="android" name="Android">\r
+      <configuration>\r
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />\r
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />\r
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />\r
+        <afterSyncTasks>\r
+          <task>generateDebugSources</task>\r
+        </afterSyncTasks>\r
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />\r
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />\r
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />\r
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res;file://$MODULE_DIR$/build/generated/res/resValues/debug" />\r
+        <option name="TEST_RES_FOLDERS_RELATIVE_PATH" value="" />\r
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />\r
+        <option name="PROJECT_TYPE" value="1" />\r
+      </configuration>\r
+    </facet>\r
+  </component>\r
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">\r
+    <output url="file://$MODULE_DIR$/build/intermediates/javac/debug/classes" />\r
+    <output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/classes" />\r
+    <exclude-output />\r
+    <content url="file://$MODULE_DIR$">\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debug/compileDebugRenderscript/out" isTestSource="false" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugAndroidTest/out" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debugAndroidTest/compileDebugAndroidTestAidl/out" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debugAndroidTest/compileDebugAndroidTestRenderscript/out" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugUnitTest/out" isTestSource="true" generated="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />\r
+      <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />\r
+      <excludeFolder url="file://$MODULE_DIR$/build" />\r
+    </content>\r
+    <orderEntry type="jdk" jdkName="Android API 18 Platform" jdkType="Android SDK" />\r
+    <orderEntry type="sourceFolder" forTests="false" />\r
+    <orderEntry type="library" name="Gradle: com.android.support:support-v4:18.0.0@jar" level="project" />\r
+  </component>\r
+</module>
\ No newline at end of file
diff --git a/dNSCache/src/main/AndroidManifest.xml b/dNSCache/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..c2a284f
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.sina.util.dnscache" >
+
+    <application
+
+
+        android:label="@string/app_name" >
+
+        
+        <!-- 主要注册一个广播 -->
+<!--        <receiver-->
+<!--            android:name="com.sina.util.networktype.NetworkStateReceiver"-->
+<!--            android:label="NetworkConnection" >-->
+<!--            <intent-filter>-->
+<!--                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />-->
+<!--                <action android:name="android.intent.action.USER_PRESENT" />-->
+<!--            </intent-filter>-->
+<!--        </receiver>-->
+        
+    </application>
+
+    <!-- 需要配置的权限 -->
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    
+</manifest>
\ No newline at end of file
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/AppConfigUtil.java b/dNSCache/src/main/java/com/sina/util/dnscache/AppConfigUtil.java
new file mode 100644 (file)
index 0000000..a7b2689
--- /dev/null
@@ -0,0 +1,99 @@
+package com.sina.util.dnscache;
+
+import java.io.File;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Environment;
+import android.telephony.TelephonyManager;
+
+public class AppConfigUtil {
+
+    private static Context mContext;
+
+    public static void init(Context ctx) {
+        mContext = ctx;
+    }
+
+    public static Context getApplicationContext() {
+        return mContext.getApplicationContext();
+    }
+
+    /**
+     * 获取缓存文件夹
+     * 
+     * @return
+     */
+    public static File getExternalCacheDir() {
+        File file = mContext.getExternalCacheDir();
+        if (null == file) {
+            file = createExternalCacheDir();
+        }
+        return file;
+    }
+
+    private static File createExternalCacheDir() {
+        File dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
+        File appCacheDir = new File(new File(dataDir, mContext.getPackageName()), "cache");
+        if (!appCacheDir.exists()) {
+            if (!appCacheDir.mkdirs()) {
+                return mContext.getCacheDir();
+            }
+        }
+        return appCacheDir;
+    }
+
+    /**
+     * 返回当前程序版本名
+     * 
+     * @return
+     */
+    public static String getVersionName() {
+        String versionName = "";
+        try {
+            PackageManager pm = mContext.getPackageManager();
+            PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), 0);
+            versionName = pi.versionName;
+            if (versionName == null || versionName.length() <= 0) {
+                return "";
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return versionName;
+    }
+
+    /**
+     * 获取设备id
+     * 
+     * @return
+     */
+    public static String getDeviceId() {
+        TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        String deviceId = tm.getDeviceId();
+        return deviceId;
+    }
+    
+    /**
+     * 获取当前的应用key
+     * @return
+     */
+    public static String getAppKey() {
+        try {
+            ApplicationInfo appInfo = mContext.getPackageManager()  
+                    .getApplicationInfo(mContext.getPackageName(),PackageManager.GET_META_DATA);  
+            appInfo.metaData.getString("meta_name"); 
+            Bundle metaData = appInfo.metaData;
+            if (null != metaData) {
+                String appKey = metaData.getString("DNSCACHE_APP_KEY");
+                return appKey;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/DNSCache.java b/dNSCache/src/main/java/com/sina/util/dnscache/DNSCache.java
new file mode 100644 (file)
index 0000000..798c0d6
--- /dev/null
@@ -0,0 +1,409 @@
+package com.sina.util.dnscache;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.net.NetworkInfo;
+import android.text.TextUtils;
+
+import com.sina.util.dnscache.cache.DnsCacheManager;
+import com.sina.util.dnscache.cache.IDnsCache;
+import com.sina.util.dnscache.dnsp.DnsManager;
+import com.sina.util.dnscache.dnsp.IDns;
+import com.sina.util.dnscache.log.HttpDnsLogManager;
+import com.sina.util.dnscache.model.DomainModel;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.net.ApacheHttpClientNetworkRequests;
+import com.sina.util.dnscache.net.networktype.Constants;
+import com.sina.util.dnscache.net.networktype.NetworkManager;
+import com.sina.util.dnscache.net.networktype.NetworkStateReceiver;
+import com.sina.util.dnscache.query.IQuery;
+import com.sina.util.dnscache.query.QueryManager;
+import com.sina.util.dnscache.score.IScore;
+import com.sina.util.dnscache.score.ScoreManager;
+import com.sina.util.dnscache.speedtest.ISpeedtest;
+import com.sina.util.dnscache.speedtest.SpeedtestManager;
+import com.sina.util.dnscache.thread.RealTimeThreadPool;
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: DNSCache <br>
+ * 类描述: Lib库全局 对外实例对象 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-3-26 下午5:26:04 <br>
+ * 
+ * 修改人: <br>
+ * 修改时间: <br>
+ * 修改备注: <br>
+ * 
+ * @version V1.0
+ */
+@SuppressLint("NewApi")
+public class DNSCache {
+
+    // ///////////////////////////////////////////////////////////////////////////////////
+
+    public static boolean isEnable = true;
+    public static int timer_interval = 60 * 1000;
+    private static DNSCache Instance = null;
+    private static Context sContext;
+    private static Object lock = new Object();
+
+    public IDnsCache dnsCacheManager = null;
+    public IQuery queryManager = null;
+    public IScore scoreManager = null;
+    public IDns dnsManager = null;
+    public ISpeedtest speedtestManager = null;
+
+    public DNSCache(Context ctx) {
+        dnsCacheManager = new DnsCacheManager(ctx);
+        queryManager = new QueryManager(dnsCacheManager);
+        scoreManager = new ScoreManager();
+        dnsManager = new DnsManager();
+        speedtestManager = new SpeedtestManager();
+        startTimer();
+    }
+
+    public static DNSCache getInstance() {
+        if (null == Instance) {
+            synchronized (lock) {
+                if (Instance == null) {
+                    Instance = new DNSCache(sContext);
+                }
+            }
+        }
+        return Instance;
+    }
+
+    public static void Init(Context ctx) {
+        if (null == ctx){
+            throw new RuntimeException("DNSCache Init; context can not be null!!!");
+        }
+        sContext = ctx.getApplicationContext();
+        // 根据配置文件 初始化策略
+        DNSCacheConfig.InitCfg(sContext);
+        NetworkManager.CreateInstance(sContext);
+        AppConfigUtil.init(sContext);
+        NetworkStateReceiver.register(sContext);
+        Instance = null;
+    }
+
+    /**
+     * 预加载逻辑
+     * 
+     * @param domains
+     */
+    public void preLoadDomains(final String[] domains) {
+        for (String domain : domains) {
+//            checkUpdates(domain, true);
+            checkUpdates(domain, false);//disable speed test
+        }
+    }
+
+    public IDnsCache getDnsCacheManager() {
+        return dnsCacheManager;
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * 获取 HttpDNS信息
+     *
+     * @param url
+     *            传入的Url
+     * @return 返回排序后的可直接使用接口
+     */
+    public DomainInfo[] getDomainServerIp(String url) {
+        String host = Tools.getHostName(url);
+        if (isEnable) {
+            if (!TextUtils.isEmpty(host) && Tools.isIPV4(host)) {
+                DomainInfo[] info = new DomainInfo[1];
+                info[0] = new DomainInfo("", url, "");
+                return info;
+            }
+            // 查询domain对应的server ip数组
+            final DomainModel domainModel = queryManager.queryDomainIp(String.valueOf(NetworkManager.getInstance().getSPID()), host);
+
+
+            // 如果本地cache 和 内置数据都没有 返回null,然后马上查询数据
+            if (null == domainModel || domainModel.id == -1) {
+//                this.checkUpdates(host, true);
+                this.checkUpdates(host, false); //disable speed test
+                if (null == domainModel) {
+                    return null;
+                }
+            }
+            
+            HttpDnsLogManager.getInstance().writeLog(HttpDnsLogManager.TYPE_INFO, HttpDnsLogManager.ACTION_INFO_DOMAIN,domainModel.tojson(), true);
+
+            ArrayList<IpModel> result = filterInvalidIp(domainModel.ipModelArr);
+            String[] scoreIpArray = scoreManager.ListToArr(result);
+
+            if (scoreIpArray == null || scoreIpArray.length == 0) {
+                return null; // 排序错误 终端后续流程
+            }
+
+            // 转换成需要返回的数据模型
+            DomainInfo[] domainInfoList = DomainInfo.DomainInfoFactory(scoreIpArray, url, host);
+
+            return domainInfoList;
+        } else {
+            return null;
+        }
+    }
+    /**
+     * 过滤无效ip数据
+     * @param ipModelArr
+     * @return
+     */
+    private ArrayList<IpModel> filterInvalidIp(ArrayList<IpModel> ipModelArr) {
+        ArrayList<IpModel> result = new ArrayList<IpModel>();
+        for (IpModel ipModel : ipModelArr) {
+            if (!("" + SpeedtestManager.MAX_OVERTIME_RTT).equals(ipModel.rtt)) {
+                result.add(ipModel);
+            }
+        }
+        return result;
+    }
+
+    private boolean isSupport(String host) {
+        return (DNSCacheConfig.domainSupportList.size() == 0) || (DNSCacheConfig.domainSupportList.contains(host));
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////////////
+
+    private ConcurrentHashMap<String, UpdateTask> mRunningTasks = new ConcurrentHashMap<String, UpdateTask>();
+
+    /**
+     * 从httpdns 服务器重新拉取数据
+     * 
+     * @param domainModel
+     */
+    private void checkUpdates(String domain, boolean speedTest) {
+        if (isSupport(domain)) {
+            final String host = domain;
+            final boolean needSpeedTest = speedTest;
+            UpdateTask task = mRunningTasks.get(host);
+            if (null == task) {
+                UpdateTask updateTask = new UpdateTask(new Runnable() {
+                    @Override
+                    public void run() {
+                        Thread.currentThread().setName("Get Http Dns Data");
+                        getHttpDnsData(host);
+                        mRunningTasks.remove(host);
+                        if (needSpeedTest) {
+                            RealTimeThreadPool.getInstance().execute(new SpeedTestTask());
+                        }
+                    }
+                });
+                mRunningTasks.put(host, updateTask);
+                updateTask.start();
+            } else {
+                long beginTime = task.getBeginTime();
+                long now = System.currentTimeMillis();
+                // 上次拉取超时,这次再开一个线程继续
+                if (now - beginTime > 30 * 1000) {
+                    task.start();
+                }
+            }
+        }
+    }
+
+    static class UpdateTask {
+
+        public Runnable runnable;
+
+        public long beginTime;
+
+        public UpdateTask(Runnable runnable) {
+            super();
+            this.runnable = runnable;
+            this.beginTime = System.currentTimeMillis();
+        }
+
+        public void start() {
+            Thread thread = new Thread(runnable);
+            thread.start();
+        }
+
+        public long getBeginTime() {
+            return beginTime;
+        }
+    }
+
+    /**
+     * 根据 host 更新数据
+     * 
+     * @param host
+     */
+    private final DomainModel getHttpDnsData(String host) {
+
+        // 获取 httpdns 数据
+        HttpDnsPack httpDnsPack = dnsManager.requestDns(host);
+
+        if (httpDnsPack == null) {
+            return null; // 没有从htppdns服务器获取正确的数据。必须中断下面流程
+        }
+
+        HttpDnsLogManager.getInstance().writeLog(HttpDnsLogManager.TYPE_INFO, HttpDnsLogManager.ACTION_INFO_DOMAIN, httpDnsPack.toJson(),
+                true);
+        // 插入本地 cache
+        DomainModel domainModel = dnsCacheManager.insertDnsCache(httpDnsPack);
+
+        return domainModel;
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * 定时器休眠时间
+     */
+    public final int sleepTime = timer_interval;
+
+    /**
+     * 启动定时器
+     */
+    private void startTimer() {
+        timer = new Timer();
+        timer.schedule(task, 0, sleepTime);
+    }
+
+    /**
+     * 定时器Obj
+     */
+    private Timer timer = null;
+
+    /**
+     * TimerTask 运行时间
+     */
+    public long TimerTaskOldRunTime = 0;
+    /**
+     * 上次测速时间
+     */
+    private long lastSpeedTime;
+    /**
+     * 上次日志上传时间
+     */
+    private long lastLogTime;
+
+    /**
+     * 定时器还多久启动
+     */
+    public long getTimerDelayedStartTime() {
+        return (sleepTime - (System.currentTimeMillis() - TimerTaskOldRunTime)) / 1000;
+    }
+
+    /**
+     * 定时器任务
+     */
+    private TimerTask task = new TimerTask() {
+
+        @Override
+        public void run() {
+            TimerTaskOldRunTime = System.currentTimeMillis();
+            //无网络情况下不执行任何后台任务操作
+            if (NetworkManager.Util.getNetworkType() == Constants.NETWORK_TYPE_UNCONNECTED || NetworkManager.Util.getNetworkType() == Constants.MOBILE_UNKNOWN) {
+                return;
+            }
+            /************************* 更新过期数据 ********************************/
+            Thread.currentThread().setName("HTTP DNS TimerTask");
+            final ArrayList<DomainModel> list = dnsCacheManager.getExpireDnsCache();
+            for (DomainModel model : list) {
+                checkUpdates(model.domain, false);
+            }
+
+            long now = System.currentTimeMillis();
+            /************************* 测速逻辑 ********************************/
+            if (now - lastSpeedTime > SpeedtestManager.time_interval - 3) {
+                lastSpeedTime = now;
+                RealTimeThreadPool.getInstance().execute(new SpeedTestTask());
+            }
+
+            /************************* 日志上报相关 ********************************/
+            now = System.currentTimeMillis();
+            if (HttpDnsLogManager.LOG_UPLOAD_SWITCH && now - lastLogTime > HttpDnsLogManager.time_interval) {
+                lastLogTime = now;
+                // 判断当前是wifi网络才能上传
+                if (NetworkManager.Util.getNetworkType() == Constants.NETWORK_TYPE_WIFI) {
+                    RealTimeThreadPool.getInstance().execute(new LogUpLoadTask());
+                }
+            }
+        }
+    };
+
+    class SpeedTestTask implements Runnable {
+
+        public void run() {
+            ArrayList<DomainModel> list = dnsCacheManager.getAllMemoryCache();
+            updateSpeedInfo(list);
+        }
+
+        private void updateSpeedInfo(ArrayList<DomainModel> list) {
+            for (DomainModel domainModel : list) {
+                ArrayList<IpModel> ipArray = domainModel.ipModelArr;
+                if (ipArray == null || ipArray.size() < 1) {
+                    continue;
+                }
+                for (IpModel ipModel : ipArray) {
+                    int rtt = speedtestManager.speedTest(ipModel.ip, domainModel.domain);
+                    boolean succ = rtt > SpeedtestManager.OCUR_ERROR;
+                    if (succ) {
+                        ipModel.rtt = String.valueOf(rtt);
+                        ipModel.success_num = String.valueOf((Integer.valueOf(ipModel.success_num) + 1));
+                        ipModel.finally_success_time = String.valueOf(System.currentTimeMillis());
+                    } else {
+                        ipModel.rtt = String.valueOf(SpeedtestManager.MAX_OVERTIME_RTT);
+                        ipModel.err_num = String.valueOf((Integer.valueOf(ipModel.err_num) + 1));
+                        ipModel.finally_fail_time = String.valueOf(System.currentTimeMillis());
+                    }
+                }
+                scoreManager.serverIpScore(domainModel);
+                dnsCacheManager.setSpeedInfo(ipArray);
+            }
+        }
+    }
+
+    class LogUpLoadTask implements Runnable {
+        public void run() {
+            File logFile = HttpDnsLogManager.getInstance().getLogFile();
+            if (null == logFile || !logFile.exists()) {
+                return;
+            }
+            boolean succ = false;
+            // upload
+            try {
+                succ = ApacheHttpClientNetworkRequests.upLoadFile(HttpDnsLogManager.LOG_UPLOAD_API, logFile);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            // succ
+            if (succ) {
+                logFile.delete();
+            }
+        }
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * 网络环境发生变化 刷新缓存数据 暂时先不需要 预处理逻辑。 用户直接请求的时候会更新数据。 (会有一次走本地dns ,
+     * 后期优化这个方法,主动请求缓存的数据)
+     * 
+     * @param networkInfo
+     */
+    public void onNetworkStatusChanged(NetworkInfo networkInfo) {
+        if (null != dnsCacheManager) {
+            dnsCacheManager.clearMemoryCache();
+        }
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////////////
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/DNSCacheConfig.java b/dNSCache/src/main/java/com/sina/util/dnscache/DNSCacheConfig.java
new file mode 100644 (file)
index 0000000..9a0121c
--- /dev/null
@@ -0,0 +1,529 @@
+package com.sina.util.dnscache;
+
+import java.util.ArrayList;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONStringer;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import com.sina.util.dnscache.cache.DnsCacheManager;
+import com.sina.util.dnscache.dnsp.DnsConfig;
+import com.sina.util.dnscache.log.HttpDnsLogManager;
+import com.sina.util.dnscache.net.ApacheHttpClientNetworkRequests;
+import com.sina.util.dnscache.net.INetworkRequests;
+import com.sina.util.dnscache.score.PlugInManager;
+import com.sina.util.dnscache.score.ScoreManager;
+import com.sina.util.dnscache.speedtest.SpeedtestManager;
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: DNSCacheConfig <br>
+ * 类描述: Lib库全局 配置文件 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-4-21 下午5:26:04 <br>
+ * 
+ * 修改人: <br>
+ * 修改时间: <br>
+ * 修改备注: <br>
+ * 
+ * @version V1.0
+ */
+public class DNSCacheConfig {
+
+    /**
+     * 调试 开关
+     */
+    public static boolean DEBUG = true;
+    
+    /**
+     * 是否启用云端更新配置策略
+     */
+    private static final boolean ENABLE_UPDATE_CONFIG = false;
+
+    /**
+     * 配置文件更新地址
+     */
+    private static String ConfigText_API = "http://202.108.7.153/config";
+    
+    public static ArrayList<String> domainSupportList = new ArrayList<String>();
+
+    /**
+     * 设置 动态更新配置参数服务器url连接
+     */
+    public static void SetConfigApiUrl(String url) {
+        DNSCacheConfig.ConfigText_API = url;
+    }
+
+    /**
+     * 初始化 配置文件。 步骤:1.获取本地缓存文件,若没有则创建默认配置
+     * 
+     * @param ctx
+     */
+    public static void InitCfg(final Context ctx) {
+        SharedPreferences sharedPreferences = ctx.getSharedPreferences("HttpDNSConstantsJson", Context.MODE_PRIVATE); // 私有数据
+        Data data = null;
+        try {
+               
+            String text = sharedPreferences.getString("ConfigText", "" );
+            
+            if (text == null || text.equals("")) {
+                Tools.log("TAG_NET", "text = " + text);
+                data = Data.createDefault();
+                saveLocalConfigAndSync(ctx, data);
+            }else{
+               data = Data.fromJson(text);
+                syncConfig(data);
+            }
+            
+               
+        } catch (Exception e) {
+            e.printStackTrace();
+            // 上报错误 
+            SharedPreferences.Editor editor = sharedPreferences.edit();
+            editor.putString("ConfigText", "");
+            boolean is = editor.commit();
+            if (is)
+                InitCfg(ctx);
+        }
+        pullConfigFromServer(ctx);
+    }
+
+    /**
+     * 同步各模块配置项 
+     * 
+     * @param data
+     */
+    private static void syncConfig(Data data) {
+       
+        if (null != data) {
+            DNSCache.timer_interval = Integer.valueOf(data.SCHEDULE_TIMER_INTERVAL);
+            SpeedtestManager.time_interval = Integer.valueOf(data.SCHEDULE_SPEED_INTERVAL);
+            HttpDnsLogManager.time_interval = Integer.valueOf(data.SCHEDULE_LOG_INTERVAL);
+            HttpDnsLogManager.sample_rate = Integer.valueOf(data.HTTPDNS_LOG_SAMPLE_RATE);
+            DnsCacheManager.ip_overdue_delay = Integer.valueOf(data.IP_OVERDUE_DELAY);
+            DNSCache.isEnable = data.HTTPDNS_SWITCH.equals("1") ? true : false;
+            
+            DnsConfig.enableSinaHttpDns = data.IS_MY_HTTP_SERVER.equals("1") == true;
+            DnsConfig.enableDnsPod = data.IS_DNSPOD_SERVER.equals("1") == true;
+            DnsConfig.enableUdpDns = data.IS_UDPDNS_SERVER.equals("1") == true;
+            DnsConfig.DNSPOD_SERVER_API = data.DNSPOD_SERVER_API;
+            DnsConfig.UDPDNS_SERVER_API = data.UDPDNS_SERVER_API;
+            
+            //
+            ScoreManager.IS_SORT = data.IS_SORT.equals("1") == true;
+            
+            String SPEEDTEST_PLUGIN_NUM = data.SPEEDTEST_PLUGIN_NUM;
+            if (isNum(SPEEDTEST_PLUGIN_NUM)) {
+                PlugInManager.SpeedTestPluginNum = Float.valueOf(SPEEDTEST_PLUGIN_NUM);
+            }
+            String PRIORITY_PLUGIN_NUM = data.PRIORITY_PLUGIN_NUM;
+            if (isNum(PRIORITY_PLUGIN_NUM)) {
+                PlugInManager.PriorityPluginNum = Float.valueOf(PRIORITY_PLUGIN_NUM);
+            }
+            String SUCCESSNUM_PLUGIN_NUM = data.SUCCESSNUM_PLUGIN_NUM;
+            if (isNum(SUCCESSNUM_PLUGIN_NUM)) {
+                PlugInManager.SuccessNumPluginNum = Float.valueOf(SUCCESSNUM_PLUGIN_NUM);
+            }
+            String ERRNUM_PLUGIN_NUM = data.ERRNUM_PLUGIN_NUM;
+            if (isNum(ERRNUM_PLUGIN_NUM)) {
+                PlugInManager.ErrNumPluginNum = Float.valueOf(ERRNUM_PLUGIN_NUM);
+            }
+            String SUCCESSTIME_PLUGIN_NUM = data.SUCCESSTIME_PLUGIN_NUM;
+            if (isNum(SUCCESSTIME_PLUGIN_NUM)) {
+                PlugInManager.SuccessTimePluginNum = Float.valueOf(SUCCESSTIME_PLUGIN_NUM);
+            }
+            
+            // arraylist
+            domainSupportList.clear();
+            DnsConfig.SINA_HTTPDNS_SERVER_API.clear();
+            
+            domainSupportList.addAll(data.DOMAIN_SUPPORT_LIST);
+            DnsConfig.SINA_HTTPDNS_SERVER_API.addAll(data.HTTPDNS_SERVER_API);
+        }
+    }
+
+    /**
+     * 更新配置文件
+     */
+    private static void pullConfigFromServer(final Context ctx) {
+        if (!ENABLE_UPDATE_CONFIG || ConfigText_API == null || ConfigText_API.equals("")){
+            return;
+        }
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    INetworkRequests netWork = new ApacheHttpClientNetworkRequests();
+                    String url = ConfigText_API + "?k=" + AppConfigUtil.getAppKey() + "&v=" + AppConfigUtil.getVersionName();
+                    String responseStr = netWork.requests(url);
+//                    responseStr = createMockJsonStr();
+                    Data data = Data.fromJson(responseStr);
+                    if (null != data) {
+                        saveLocalConfigAndSync(ctx, data);
+                    }
+                    HttpDnsLogManager.getInstance().writeLog(HttpDnsLogManager.TYPE_INFO, HttpDnsLogManager.ACTION_INFO_CONFIG, responseStr);
+                } catch (Exception e) {
+                    String message = e.toString();
+                    JSONStringer stringer = new JSONStringer();
+                    try {
+                        stringer.object()//
+                        .key("errorMsg").value(message)//
+                        .endObject();
+                    } catch (JSONException e1) {
+                        e1.printStackTrace();
+                    }
+                    HttpDnsLogManager.getInstance().writeLog(HttpDnsLogManager.TYPE_ERROR, HttpDnsLogManager.ACTION_INFO_CONFIG, stringer.toString());
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * 保存本地配置信息。
+     * 
+     * @param ctx
+     * @param configStr
+     */
+    public static void saveLocalConfigAndSync(Context ctx, Data model) {
+        if (null != ctx && null != model) {
+            SharedPreferences sharedPreferences = ctx.getSharedPreferences("HttpDNSConstantsJson", Context.MODE_PRIVATE);
+            SharedPreferences.Editor editor = sharedPreferences.edit();
+            editor.putString("ConfigText", model.toJson());
+            editor.commit();
+            syncConfig(model);
+            Data.Instance = null ; 
+        }
+    }
+
+    /**
+     * 获取本地配置信息。
+     * 
+     * @param ctx
+     * @param configStr
+     */
+    private static Data getLocalConfig() {
+        SharedPreferences sharedPreferences = AppConfigUtil.getApplicationContext().getSharedPreferences("HttpDNSConstantsJson",
+                Context.MODE_PRIVATE);
+        String json = sharedPreferences.getString("ConfigText", "");
+        Data data = Data.fromJson(json);
+        if (null == data) {
+            data = Data.createDefault();
+        }
+        return data;
+    }
+
+    /**
+     * 是否为数字
+     * 
+     * @param str
+     * @return
+     */
+    private static boolean isNum(String str) {
+        return str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
+    }
+
+    public static class Data {
+       
+       public static Data Instance = null;
+       public static Data getInstance(){
+               if( Instance == null ){
+                       Instance = DNSCacheConfig.getLocalConfig() ; 
+               }
+               return Instance ; 
+       }
+       
+       /**
+         * 是否启用udpdns服务器 默认不启用 | 1启用 0不启用
+         */
+        public String IS_UDPDNS_SERVER = "";
+        /**
+         * udp dnsserver的地址
+         */
+        public String UDPDNS_SERVER_API = "";
+       /**
+        * 日志采样率
+        */
+       public String HTTPDNS_LOG_SAMPLE_RATE = "";
+       /**
+        * lib库开关
+        */
+       public String HTTPDNS_SWITCH = "";
+       /**
+        * 测速间隔时间
+        */
+       public String SCHEDULE_SPEED_INTERVAL = "";
+       /**
+        * 日志上传的间隔时间
+        */
+       public String SCHEDULE_LOG_INTERVAL = "";
+       /**
+        * timer轮询器的间隔时间
+        */
+       public String SCHEDULE_TIMER_INTERVAL = "";
+       /**
+        * ip数据过期延迟差值
+        */
+       public String IP_OVERDUE_DELAY = "";
+       /**************************************以上部分是新加配置,共8个********************************************/
+        /**
+         * 是否启用自己家的HTTP_DNS服务器 默认不启用 | 1启用 0不启用
+         */
+        public String IS_MY_HTTP_SERVER = null;
+        /**
+         * 自己家HTTP_DNS服务API地址 使用时直接在字符串后面拼接domain地址 |
+         * 示例(http://202.108.7.153/dns?domain=)+ domain
+         */
+        public ArrayList<String> HTTPDNS_SERVER_API = new ArrayList<String>();
+        /**
+         * 是否启用dnspod服务器 默认不启用 | 1启用 0不启用
+         */
+        public String IS_DNSPOD_SERVER = null;
+        /**
+         * DNSPOD HTTP_DNS 服务器API地址 | 默认(http://119.29.29.29/d?ttl=1&dn=)
+         */
+        public String DNSPOD_SERVER_API = null;
+        /**
+         * DNSPOD 企业级ID配置选项 
+         */
+        public String DNSPOD_ID = null;
+        /**
+         * DNSPOD 企业级KEY配置选项 
+         */
+        public String DNSPOD_KEY = null;
+
+        /**
+         * 是否开启 本地排序插件算法 默认开启 | 1开启 0不开启
+         */
+        public String IS_SORT = null;
+        /**
+         * 速度插件 比重分配值:默认40%
+         */
+        public String SPEEDTEST_PLUGIN_NUM = null;
+        /**
+         * 服务器推荐优先级插件 比重分配:默认30% (需要自家HTTP_DNS服务器支持)
+         */
+        public String PRIORITY_PLUGIN_NUM = null;
+        /**
+         * 历史成功次数计算插件 比重分配:默认10%
+         */
+        public String SUCCESSNUM_PLUGIN_NUM = null;
+        /**
+         * 历史错误次数计算插件 比重分配:默认10%
+         */
+        public String ERRNUM_PLUGIN_NUM = null;
+        /**
+         * 最后一次成功时间计算插件 比重分配:默认10%
+         */
+        public String SUCCESSTIME_PLUGIN_NUM = null;
+        /**
+         * 白名单
+         */
+        public ArrayList<String> DOMAIN_SUPPORT_LIST = new ArrayList<String>();
+
+        /**
+         * 返回配置文件 json
+         */
+        public String toJson() {
+            // 为了节约lib库的大小直接拼接 json 字符串吧,就不适用第三方库了
+            StringBuffer buffer = new StringBuffer();
+            buffer.append("{");
+            buffer.append("\"IS_UDPDNS_SERVER\":" + "\"" + IS_UDPDNS_SERVER + "\",");
+            buffer.append("\"UDPDNS_SERVER_API\":" + "\"" + UDPDNS_SERVER_API + "\",");
+            buffer.append("\"HTTPDNS_LOG_SAMPLE_RATE\":" + "\"" + HTTPDNS_LOG_SAMPLE_RATE + "\",");
+            buffer.append("\"HTTPDNS_SWITCH\":" + "\"" + HTTPDNS_SWITCH + "\",");
+            buffer.append("\"SCHEDULE_LOG_INTERVAL\":" + "\"" + SCHEDULE_LOG_INTERVAL + "\",");
+            buffer.append("\"SCHEDULE_SPEED_INTERVAL\":" + "\"" + SCHEDULE_SPEED_INTERVAL + "\",");
+            buffer.append("\"SCHEDULE_TIMER_INTERVAL\":" + "\"" + SCHEDULE_TIMER_INTERVAL + "\",");
+            buffer.append("\"IP_OVERDUE_DELAY\":" + "\"" + IP_OVERDUE_DELAY + "\",");
+            buffer.append("\"IS_MY_HTTP_SERVER\":" + "\"" + IS_MY_HTTP_SERVER + "\",");
+            buffer.append("\"IS_DNSPOD_SERVER\":" + "\"" + IS_DNSPOD_SERVER + "\",");
+            buffer.append("\"DNSPOD_SERVER_API\":" + "\"" + DNSPOD_SERVER_API + "\",");
+            // 测试阶段暂时先把 dnspod的ID和KEY加上
+            buffer.append("\"DNSPOD_ID\":" + "\"" + DNSPOD_ID + "\",");
+            buffer.append("\"DNSPOD_KEY\":" + "\"" + DNSPOD_KEY + "\",");
+            buffer.append("\"IS_SORT\":" + "\"" + IS_SORT + "\",");
+            buffer.append("\"SPEEDTEST_PLUGIN_NUM\":" + "\"" + SPEEDTEST_PLUGIN_NUM + "\",");
+            buffer.append("\"PRIORITY_PLUGIN_NUM\":" + "\"" + PRIORITY_PLUGIN_NUM + "\",");
+            buffer.append("\"SUCCESSNUM_PLUGIN_NUM\":" + "\"" + SUCCESSNUM_PLUGIN_NUM + "\",");
+            buffer.append("\"ERRNUM_PLUGIN_NUM\":" + "\"" + ERRNUM_PLUGIN_NUM + "\",");
+            buffer.append("\"SUCCESSTIME_PLUGIN_NUM\":" + "\"" + SUCCESSTIME_PLUGIN_NUM + "\",");
+            buffer.append("\"DOMAIN_SUPPORT_LIST\":" + "[");
+            for (int i = 0; i < DOMAIN_SUPPORT_LIST.size(); i++) {
+                buffer.append("\"" + DOMAIN_SUPPORT_LIST.get(i) + "\"" + (i != DOMAIN_SUPPORT_LIST.size() - 1 ? "," : ""));
+            }
+            buffer.append("]");
+            buffer.append(",");
+            buffer.append("\"HTTPDNS_SERVER_API\":" + "[");
+            for (int i = 0; i < HTTPDNS_SERVER_API.size(); i++) {
+                buffer.append("\"" + HTTPDNS_SERVER_API.get(i) + "\"" + (i != HTTPDNS_SERVER_API.size() - 1 ? "," : ""));
+            }
+            buffer.append("]");
+            buffer.append("}");
+            return buffer.toString();
+        }
+
+        public static Data createDefault() {
+            Data model = new Data();
+            model.HTTPDNS_LOG_SAMPLE_RATE = "50";
+            model.HTTPDNS_SWITCH = "1";
+            model.SCHEDULE_LOG_INTERVAL = "3600000";
+            model.SCHEDULE_SPEED_INTERVAL = "60000";
+            model.SCHEDULE_TIMER_INTERVAL = "60000";
+            model.IP_OVERDUE_DELAY = "60";
+            
+            model.IS_MY_HTTP_SERVER = "0";
+            model.HTTPDNS_SERVER_API.add("http://xxx/dns?domain=");
+
+            model.IS_DNSPOD_SERVER = "1";
+            model.DNSPOD_SERVER_API = "http://119.29.29.29/d?ttl=1&dn=";
+            model.DNSPOD_ID = "";
+            model.DNSPOD_KEY = "";
+
+            model.IS_UDPDNS_SERVER = "1";
+            model.UDPDNS_SERVER_API = "114.114.114.114";
+            
+            model.IS_SORT = "1";
+            model.SPEEDTEST_PLUGIN_NUM = "50";
+            model.PRIORITY_PLUGIN_NUM = "50";
+            model.SUCCESSNUM_PLUGIN_NUM = "10";
+            model.ERRNUM_PLUGIN_NUM = "10";
+            model.SUCCESSTIME_PLUGIN_NUM = "10";
+
+            return model;
+        }
+
+        public static Data fromJson(String json) {
+            Data model = createDefault();
+            try {
+                JSONObject jsonObj = new JSONObject(json);
+                //new
+                if (jsonObj.isNull("HTTPDNS_LOG_SAMPLE_RATE") == false) {
+                    model.HTTPDNS_LOG_SAMPLE_RATE = jsonObj.getString("HTTPDNS_LOG_SAMPLE_RATE");
+                }
+                if (jsonObj.isNull("HTTPDNS_SWITCH") == false) {
+                    model.HTTPDNS_SWITCH = jsonObj.getString("HTTPDNS_SWITCH");
+                }
+                if (jsonObj.isNull("SCHEDULE_LOG_INTERVAL") == false) {
+                    model.SCHEDULE_LOG_INTERVAL = jsonObj.getString("SCHEDULE_LOG_INTERVAL");
+                }
+                if (jsonObj.isNull("SCHEDULE_SPEED_INTERVAL") == false) {
+                    model.SCHEDULE_SPEED_INTERVAL = jsonObj.getString("SCHEDULE_SPEED_INTERVAL");
+                }
+                if (jsonObj.isNull("SCHEDULE_TIMER_INTERVAL") == false) {
+                    model.SCHEDULE_TIMER_INTERVAL = jsonObj.getString("SCHEDULE_TIMER_INTERVAL");
+                }
+                if (jsonObj.isNull("IP_OVERDUE_DELAY") == false) {
+                    model.IP_OVERDUE_DELAY = jsonObj.getString("IP_OVERDUE_DELAY");
+                }
+                if (jsonObj.isNull("IS_UDPDNS_SERVER") == false) {
+                    model.IS_UDPDNS_SERVER = jsonObj.getString("IS_UDPDNS_SERVER");
+                }
+                if (jsonObj.isNull("UDPDNS_SERVER_API") == false) {
+                    model.UDPDNS_SERVER_API = jsonObj.getString("UDPDNS_SERVER_API");
+                }
+                //----------------------------------------
+                // httpdns
+                if (jsonObj.isNull("IS_MY_HTTP_SERVER") == false) {
+                    model.IS_MY_HTTP_SERVER = jsonObj.getString("IS_MY_HTTP_SERVER");
+                }
+                // dnspod
+                if (jsonObj.isNull("IS_DNSPOD_SERVER") == false) {
+                    model.IS_DNSPOD_SERVER = jsonObj.getString("IS_DNSPOD_SERVER");
+                }
+
+                if (jsonObj.isNull("DNSPOD_SERVER_API") == false) {
+                    model.DNSPOD_SERVER_API = jsonObj.getString("DNSPOD_SERVER_API");
+                }
+                if (jsonObj.isNull("DNSPOD_ID") == false) {
+                    model.DNSPOD_ID = jsonObj.getString("DNSPOD_ID");
+                }
+                if (jsonObj.isNull("DNSPOD_KEY") == false) {
+                    model.DNSPOD_KEY = jsonObj.getString("DNSPOD_KEY");
+                }
+
+                // sort
+                if (jsonObj.isNull("IS_SORT") == false) {
+                    String IS_SORT = jsonObj.getString("IS_SORT");
+                    model.IS_SORT = IS_SORT;
+                }
+                if (jsonObj.isNull("SPEEDTEST_PLUGIN_NUM") == false) {
+                    model.SPEEDTEST_PLUGIN_NUM = jsonObj.getString("SPEEDTEST_PLUGIN_NUM");
+                }
+                if (jsonObj.isNull("PRIORITY_PLUGIN_NUM") == false) {
+                    model.PRIORITY_PLUGIN_NUM = jsonObj.getString("PRIORITY_PLUGIN_NUM");
+                }
+                if (jsonObj.isNull("SUCCESSNUM_PLUGIN_NUM") == false) {
+                    model.SUCCESSNUM_PLUGIN_NUM = jsonObj.getString("SUCCESSNUM_PLUGIN_NUM");
+                }
+                if (jsonObj.isNull("ERRNUM_PLUGIN_NUM") == false) {
+                    model.ERRNUM_PLUGIN_NUM = jsonObj.getString("ERRNUM_PLUGIN_NUM");
+                }
+                if (jsonObj.isNull("SUCCESSTIME_PLUGIN_NUM") == false) {
+                    model.SUCCESSTIME_PLUGIN_NUM = jsonObj.getString("SUCCESSTIME_PLUGIN_NUM");
+                }
+
+                // 白名单
+                model.DOMAIN_SUPPORT_LIST.clear();
+                if (jsonObj.isNull("DOMAIN_SUPPORT_LIST") == false) {
+                    JSONArray jsonArr = jsonObj.getJSONArray("DOMAIN_SUPPORT_LIST");
+                    for (int i = 0; i < jsonArr.length(); i++) {
+                        String temp = jsonArr.getString(i);
+                        model.DOMAIN_SUPPORT_LIST.add(temp);
+                    }
+                }
+                
+                // 新浪httpdns服务地址
+                model.HTTPDNS_SERVER_API.clear();
+                if (jsonObj.isNull("HTTPDNS_SERVER_API") == false) {
+                    JSONArray jsonArr = jsonObj.getJSONArray("HTTPDNS_SERVER_API");
+                    for (int i = 0; i < jsonArr.length(); i++) {
+                        String temp = jsonArr.getString(i);
+                        model.HTTPDNS_SERVER_API.add(temp);
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                model = null;
+            }
+            return model;
+        }
+    }
+    //FOR TEST !!!
+    static String createMockJsonStr() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("{");
+        buffer.append("\"HTTPDNS_LOG_SAMPLE_RATE\":" + "\"" + 10 + "\",");
+        buffer.append("\"HTTPDNS_SWITCH\":" + "\"" + 1 + "\",");
+        buffer.append("\"SCHEDULE_LOG_INTERVAL\":" + "\"" + 60 * 60 * 1000 + "\",");
+        buffer.append("\"SCHEDULE_SPEED_INTERVAL\":" + "\"" + 10 * 1000 + "\",");
+        buffer.append("\"SCHEDULE_TIMER_INTERVAL\":" + "\"" + 10 * 1000 + "\",");
+        buffer.append("\"IS_MY_HTTP_SERVER\":" + "\"" + 1 + "\",");
+        buffer.append("\"IS_SORT\":" + "\"" + 1 + "\",");
+        buffer.append("\"SPEEDTEST_PLUGIN_NUM\":" + "\"" + 50 + "\",");
+        buffer.append("\"PRIORITY_PLUGIN_NUM\":" + "\"" + 50 + "\",");
+        
+        ArrayList<String> whiteList = new ArrayList<String>();
+        whiteList.add("api.camera.weibo.com");
+        whiteList.add("ww4.sinaimg.cn");
+        whiteList.add("api.weibo.cn");
+        whiteList.add("m.weibo.cn");
+        buffer.append("\"DOMAIN_SUPPORT_LIST\":" + "[");
+        for (int i = 0; i < whiteList.size(); i++) {
+            buffer.append("\"" + whiteList.get(i) + "\"" + (i != whiteList.size() - 1 ? "," : ""));
+        }
+        buffer.append("]");
+        buffer.append(",");
+        buffer.append("\"HTTPDNS_SERVER_API\":" + "[");
+        for (int i = 0; i < 1; i++) {
+            buffer.append("\"" + "http://202.108.7.153/dns?domain=" + "\"");
+        }
+        buffer.append("]");
+        buffer.append("}");
+        return buffer.toString();
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/DomainInfo.java b/dNSCache/src/main/java/com/sina/util/dnscache/DomainInfo.java
new file mode 100644 (file)
index 0000000..8b5b5f7
--- /dev/null
@@ -0,0 +1,132 @@
+package com.sina.util.dnscache;
+
+
+/**
+*
+* 项目名称: DNSCache <br>
+* 类名称: DomainInfo <br>
+* 类描述: 为使用者封装的数据模型 <br>
+* 创建人: fenglei <br>
+* 创建时间: 2015-4-21 下午5:26:04 <br>
+* 
+* 修改人:  <br>
+* 修改时间:  <br>
+* 修改备注:  <br>
+* 
+* @version V1.0
+*/
+public class DomainInfo {
+
+    /**
+     * 工场方法
+     *
+     * @param ip
+     * @param url
+     * @param host
+     * @return
+     */
+    public static DomainInfo DomainInfoFactory(String ip, String url, String host){
+
+        url = Tools.getIpUrl(url, host, ip) ;
+
+        return new DomainInfo( "" , url , host);
+    }
+
+    /**
+     * 工场方法
+     * @param serverIpArray
+     * @param url
+     * @param host
+     * @return
+     */
+    public static DomainInfo[] DomainInfoFactory(String[] serverIpArray, String url, String host){
+
+        DomainInfo[] domainArr = new DomainInfo[serverIpArray.length];
+
+        for( int i = 0 ; i < serverIpArray.length ; i++  ){
+
+            domainArr[i] = DomainInfoFactory( serverIpArray[i], url , host );
+        }
+
+        return domainArr ;
+    }
+
+
+    /**
+     * 构造函数
+     * @param id
+     * @param url
+     * @param host
+     */
+    public DomainInfo(String id, String url, String host){
+
+        this.id = id ;
+        this.url = url ;
+        this.host = host ;
+
+        this.startTime = String.valueOf( System.currentTimeMillis() );
+    }
+
+    /**
+     * id
+     */
+    public String id = null;
+
+    /**
+     * 可以直接使用的url  已经替换了host为ip
+     */
+    public String url = null;
+
+    /**
+     * 需要设置到 http head 里面的主机头
+     */
+    public String host = "";
+
+
+
+    /**
+     * 返回的内容体
+     */
+    public String data = null ;
+
+
+    /**
+     * 开始请求的时间
+     */
+    public String startTime = null ;
+
+
+    /**
+     * 请求结束的时间 请求超时 结束时间为null
+     */
+    public String stopTime = null ;
+
+
+    /**
+     * 请求的状态值 200 \ 404 \ 500 等
+     */
+    public String code = null ;
+
+
+
+
+    /**
+     * 返回 url 信息
+     * @return
+     */
+    public String toString(){
+
+        String str = "DomainInfo: \n" ;
+        str += "id = " + id + "\n" ;
+        str += "url = " + url + "\n" ;
+        str += "host = " + host + "\n" ;
+        str += "data = " + data + "\n" ;
+        str += "startTime = " + startTime + "\n" ;
+        str += "stopTime = " + stopTime + "\n" ;
+        str += "code = " + code + "\n" ;
+
+        return str ;
+    }
+
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/Tools.java b/dNSCache/src/main/java/com/sina/util/dnscache/Tools.java
new file mode 100644 (file)
index 0000000..79b0b0e
--- /dev/null
@@ -0,0 +1,241 @@
+package com.sina.util.dnscache;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.ListIterator;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.json.JSONException;
+import org.json.JSONStringer;
+
+import android.annotation.SuppressLint;
+import android.util.Log;
+
+import com.sina.util.dnscache.model.IpModel;
+
+/**
+*
+* 项目名称: DNSCache <br>
+* 类名称: Tools <br>
+* 类描述: 一些常用的小方法 <br>
+* 创建人: fenglei <br>
+* 创建时间: 2015-4-21 下午5:26:04 <br>
+* 
+* 修改人:  <br>
+* 修改时间:  <br>
+* 修改备注:  <br>
+* 
+* @version V1.0
+*/
+public class Tools {
+
+    /**
+     * 从 url 中截取 domain
+     * @param url
+     * @return
+     */
+    public static String getHostName(String url){
+
+        if (url == null)
+            return "";
+
+        url = url.trim();
+        String host = url.toLowerCase();
+        int end;
+
+        if (host.startsWith("http://")) {
+            end = url.indexOf("/", 8);
+            if (end > 7) {
+                host = url.substring(7, end);
+            } else {
+                host = url.substring(7);
+            }
+
+        } else if (host.startsWith("https://")) {
+            end = url.indexOf("/", 9);
+            if (end > 8) {
+                host = url.substring(8, end);
+            } else {
+                host = url.substring(8);
+            }
+        } else {
+            end = url.indexOf("/", 1);
+            if (end > 1) {
+                host = url.substring(0, url.indexOf("/", 1));
+            } else {
+                host = url;
+            }
+        }
+
+        return host;
+    }
+
+
+    /**
+     * 转换url 主机头为ip地址
+     * @param url 原url
+     * @param host 主机头
+     * @param ip 服务器ip
+     * @return
+     */
+    public static String getIpUrl(String url, String host, String ip ){
+
+       if( url == null ){
+               Tools.log("TAG", "URL NULL") ;
+       }
+       if( host == null ){
+               Tools.log("TAG", "host NULL") ;
+       }
+       if( ip == null ){
+               Tools.log("TAG", "ip NULL") ;
+       }
+       
+       if( url == null || host == null || ip == null ) return url ;
+       
+        String ipUrl = url.replaceFirst(host, ip);
+
+        return ipUrl ;
+    }
+
+
+
+//    /**
+//     * 将ip转换成整形
+//     */
+//    public static long parseIpAddress(String ipAddress) {
+//        if (ipAddress == null || ipAddress.equals("0") || TextUtils.isEmpty(ipAddress)) {
+//            return 0;
+//        }
+//        ipAddress = ipAddress.trim();
+//        long[] ip = new long[4];
+//        // 先找到IP地址字符串中.的位置
+//        int position1 = ipAddress.indexOf(".");
+//        int position2 = ipAddress.indexOf(".", position1 + 1);
+//        int position3 = ipAddress.indexOf(".", position2 + 1);
+//        // 将每个.之间的字符串转换成整型
+//        try {
+//            ip[0] = Long.parseLong(ipAddress.substring(0, position1));
+//            ip[1] = Long.parseLong(ipAddress.substring(position1 + 1, position2));
+//            ip[2] = Long.parseLong(ipAddress.substring(position2 + 1, position3));
+//            ip[3] = Long.parseLong(ipAddress.substring(position3 + 1));
+//        } catch (NumberFormatException e) {
+//
+//        }
+//        return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
+//    }
+//
+//    /**
+//     * 将整形ip转成成字符串ip地址
+//     * @param longIp
+//     * @return
+//     */
+//    public static String longToIP(long longIp) {
+//        StringBuffer sb = new StringBuffer("");
+//        // 直接右移24位
+//        sb.append(String.valueOf((longIp >>> 24)));
+//        sb.append(".");
+//        // 将高8位置0,然后右移16位
+//        sb.append(String.valueOf((longIp & 0x00FFFFFF) >>> 16));
+//        sb.append(".");
+//        // 将高16位置0,然后右移8位
+//        sb.append(String.valueOf((longIp & 0x0000FFFF) >>> 8));
+//        sb.append(".");
+//        // 将高24位置0
+//        sb.append(String.valueOf((longIp & 0x000000FF)));
+//        return sb.toString();
+//    }
+
+    
+       @SuppressLint("SimpleDateFormat")
+       public static String getStringDateShort(long time) {
+               Date currentTime = new Date(time);
+               SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+               String dateString = formatter.format(currentTime);
+               return dateString;
+       }
+       
+       public static String getStringDateShort(String time) {
+               return getStringDateShort( Long.valueOf(time) );
+       }
+       
+       public static void log( String tag, String msg ){
+               if( DNSCacheConfig.DEBUG == false ) return ; 
+               Log.d(tag, msg) ; 
+       }
+       /**
+        * 随机排序算法
+        * @param list
+        * @return
+        */
+    public static void randomSort(ArrayList<IpModel> list) {
+        ArrayList<IpModel> temp = new ArrayList<IpModel>();
+        temp.addAll(list);
+        int count = temp.size();
+        IpModel[] array = new IpModel[count];
+        Random rand = new Random();
+        for (int i = 0; i < count; i++) {
+            int num = rand.nextInt(count - i);
+            array[i] = temp.remove(num);
+        }
+        int i = 0;
+        // 下面这种写法,是为了不引起list的并发异常
+        ListIterator<IpModel> it = list.listIterator();
+        while (it.hasNext()) {
+            it.next();
+            it.set(array[i++]);
+        }
+    }
+    
+    public String generateJsonStrFromMap(HashMap<String, String> map) {
+        JSONStringer jsonStringer = new JSONStringer();
+        try {
+            jsonStringer = jsonStringer.object();
+            Set<Entry<String, String>> entrySet = map.entrySet();
+            for (Entry<String, String> entry : entrySet) {
+                jsonStringer = jsonStringer.key(entry.getKey()).value(entry.getValue());
+            }
+            jsonStringer = jsonStringer.endObject();
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return "{}";
+        }
+        return jsonStringer.toString();
+    }
+    /**
+     * 判断该host是否是为 ipv4 格式。
+     * @param host 支持加端口验证
+     * @return
+     */
+    public static boolean isIPV4(String host) {
+        long begin = System.currentTimeMillis();
+        host = host.trim();
+        if (host.contains(":")) {
+            String[] array = host.split(":");
+            if (null != array && array.length == 2) {
+                host = array[0];
+                host = host.trim();
+            }
+        } else {
+            if (null == host || host.length() < 7 || host.length() > 15 || "".equals(host)) {
+                return false;
+            }
+        }
+        String rexp = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." //
+                + "(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." //
+                + "(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."//
+                + "(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
+        Pattern pat = Pattern.compile(rexp);
+        Matcher mat = pat.matcher(host);
+        boolean ipAddress = mat.find();
+        long end = System.currentTimeMillis();
+        Tools.log("Tools:", "regular time spend : " + (end - begin) + "ms");
+        return ipAddress;
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/cache/DBConstants.java b/dNSCache/src/main/java/com/sina/util/dnscache/cache/DBConstants.java
new file mode 100644 (file)
index 0000000..3095acb
--- /dev/null
@@ -0,0 +1,211 @@
+package com.sina.util.dnscache.cache;
+
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: DBConstants <br>
+ * 类描述: 数据库名、表明、列明 相关常量定义 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-3-26 下午3:54:59 <br>
+ * 
+ * 修改人:  <br>
+ * 修改时间:  <br>
+ * 修改备注:  <br>
+ * 
+ * @version V1.0
+ */
+public interface DBConstants {
+       
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+       /**
+        * db 数据库名字 
+        */
+       public static final String DATABASE_NAME = "dns_ip_info.db" ; 
+       /**
+        * db 版本
+        */
+       public static final int DATABASE_VERSION = 4 ; 
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       
+       
+       
+       /**
+        * domain表名称、列名定义
+        */
+       public static final String TABLE_NAME_DOMAIN = "domain" ; 
+       /**
+        * domain 自增id
+        */
+       public static final String DOMAIN_COLUMN_ID = "id";
+       /**
+        * 域名
+        */
+       public static final String DOMAIN_COLUMN_DOMAIN = "domain" ;
+       /**
+        * 运营商
+        */
+       public static final String DOMAIN_COLUMN_SP = "sp" ;
+       /**
+        * 域名过期时间
+        */
+       public static final String DOMAIN_COLUMN_TTL = "ttl" ;
+    /**
+     * 最后查询时间
+     */
+    public static final String DOMAIN_COLUMN_TIME = "time" ;
+
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+       
+       
+       /**
+        * ip表名称、列名定义
+        */
+       public static final String TABLE_NAME_IP = "ip" ;
+       /**
+        * ip 自增id
+        */
+       public static final String IP_COLUMN_ID = "id" ;
+       /**
+        * domain 关联id
+        */
+       public static final String IP_COLUMN_DOMAIN_ID = "d_id" ; 
+       /**
+        * 服务器 ip地址
+        */
+       public static final String IP_COLUMN_IP = "ip" ; 
+       /**
+        * ip服务器对应的端口
+        */
+       public static final String IP_COLUMN_PORT = "port" ;
+       /**
+        * ip服务器对应的sp运营商
+        */
+       public static final String IP_COLUMN_SP = "sp";
+       /**
+        * ip服务器对应域名过期时间
+        */
+       public static final String IP_COLUMN_TTL = "ttl";
+       /**
+        * ip服务器优先级-排序算法策略使用
+        */
+       public static final String IP_COLUMN_PRIORITY = "priority" ;
+       /**
+        * ip服务器访问延时时间(可用ping或http发送空包实现)。单位ms
+        */
+       public static final String IP_COLUMN_RTT = "rtt" ;
+       /**
+        * ip服务器链接产生的成功数
+        */
+       public static final String IP_COLUMN_SUCCESS_NUM = "success_num" ;
+       /**
+        * ip服务器链接产生的错误数
+        */
+       public static final String IP_COLUMN_ERR_NUM = "err_num" ;
+       /**
+        * ip服务器最后成功链接时间
+        */
+       public static final String IP_COLUMN_FINALLY_SUCCESS_TIME = "finally_success_time" ; 
+       /**
+        * ip服务器最后失败链接时间
+        */
+       public static final String IP_COLUMN_FINALLY_FAIL_TIME = "finally_fail_time" ; 
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+       
+       
+       
+       /**
+        * 链接失败表名称、列定义(主要用来上报通知异常)
+        */
+       public static final String TABLE_NAME_CONNECT_FAIL = "connect_fail" ;
+       /**
+        * 链接失败表 自曾id
+        */
+       public static final String CONNECT_FAIL_ID = "id" ;
+       /**
+        * 链接失败的ip地址
+        */
+       public static final String CONNECT_FAIL_IP = "ip" ;
+       /**
+        * 链接失败服务器的端口号
+        */
+       public static final String CONNECT_FAIL_PORT = "port" ; 
+       /**
+        * 链接失败的错误代码,(一般都是http的错误代码)
+        */
+       public static final String CONNECT_FAIL_ERRCODE = "errcode" ;
+       /**
+        * 链接失败时本地网络类型
+        */
+       public static final String CONNECT_FAIL_NETWORK_TYPE = "network_type" ;
+       /**
+        * 链接失败时如果是手机运营商,则统计运营商sp—code(为了重现现场收集数据)
+        */
+       public static final String CONNECT_FAIL_SPCODE = "spcode" ; 
+       /**
+        * 链接该服务器总共的错误次数
+        */
+       public static final String CONNECT_FAIL_COUNT = "count" ;
+       /**
+        * 链接该服务器最后失败时间
+        */
+       public static final String CONNECT_FAIL_FINALLY_TIME = "finally_time" ;
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+       
+       /**
+        * 创建 domain 表 sql 语句
+        */
+       public static  final String CREATE_DOMAIN_TABLE_SQL = 
+                       "CREATE TABLE " + TABLE_NAME_DOMAIN + " (" + 
+                                       DOMAIN_COLUMN_ID + " INTEGER PRIMARY KEY," +
+                                       DOMAIN_COLUMN_DOMAIN + " TEXT," +
+                                       DOMAIN_COLUMN_SP + " TEXT," +
+                                       DOMAIN_COLUMN_TTL + " TEXT," +
+                    DOMAIN_COLUMN_TIME + " TEXT" +
+                       ");";
+       
+       /**
+        * 创建 ip 表 sql 语句
+        */
+       public static final String CREATE_IP_TEBLE_SQL = 
+                       "CREATE TABLE " + TABLE_NAME_IP + " (" +
+                                       IP_COLUMN_ID + " INTEGER PRIMARY KEY," +
+                                       IP_COLUMN_DOMAIN_ID + " INTEGER," + 
+                                       IP_COLUMN_IP + " INTEGER," + 
+                                       IP_COLUMN_PORT + " INTEGER," +
+                                       IP_COLUMN_SP + " TEXT," +
+                                       IP_COLUMN_TTL + " TEXT," +
+                                       IP_COLUMN_PRIORITY + " INTEGER," +
+                                       IP_COLUMN_RTT + " INTEGER," +
+                                       IP_COLUMN_SUCCESS_NUM + " INTEGER," +
+                                       IP_COLUMN_ERR_NUM + " INTEGER," +
+                                       IP_COLUMN_FINALLY_SUCCESS_TIME + " TEXT," +
+                                       IP_COLUMN_FINALLY_FAIL_TIME + " TEXT" +
+                       ");";
+       
+       /**
+        * 创建 connect_fail 表 sql 语句
+        */
+       public static final String CREATE_CONNECT_FAIL_TABLE_SQL = 
+                       "CREATE TABLE " + TABLE_NAME_CONNECT_FAIL + " (" + 
+                                       CONNECT_FAIL_ID + " INTEGER PRIMARY KEY," +
+                                       CONNECT_FAIL_IP + " TEXT," +
+                                       CONNECT_FAIL_PORT + " INGEGER," +
+                                       CONNECT_FAIL_ERRCODE + " TEXT," +
+                                       CONNECT_FAIL_NETWORK_TYPE + " TEXT," +
+                                       CONNECT_FAIL_SPCODE + " TEXT," +
+                                       CONNECT_FAIL_COUNT + " INGEGER," +
+                                       CONNECT_FAIL_FINALLY_TIME + " TEXT" +
+                       ");" ;
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/cache/DNSCacheDatabaseHelper.java b/dNSCache/src/main/java/com/sina/util/dnscache/cache/DNSCacheDatabaseHelper.java
new file mode 100644 (file)
index 0000000..416b3e5
--- /dev/null
@@ -0,0 +1,584 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.cache;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import com.sina.util.dnscache.model.DomainModel;
+import com.sina.util.dnscache.model.IpModel;
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: DNSCacheDatabaseHelper <br>
+ * 类描述: 缓存数据库 创建、更新、删除、增删改查相关操作 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-3-26 下午4:04:23 <br>
+ * 
+ * 修改人:  <br>
+ * 修改时间:  <br>
+ * 修改备注:  <br>
+ * 
+ * @version V1.0
+ */
+public class DNSCacheDatabaseHelper extends SQLiteOpenHelper implements DBConstants{
+
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       
+    /**
+     * 资源锁
+     */
+    private final static byte synLock[] = new byte[1];
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    /**
+     * 构造函数
+     * @param context
+     */
+    public DNSCacheDatabaseHelper(Context context) {
+               super(context, DATABASE_NAME, null, DATABASE_VERSION);
+               // TODO Auto-generated constructor stub
+       }
+
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * 创建数据库
+     * 
+     * 残酷的现实告诉我们,创建多个表时,要分开多次执行db.execSQL方法!!
+     */
+       @Override
+       public void onCreate(SQLiteDatabase db) {
+               // TODO Auto-generated method stub
+               //Log.d("DB", "onCreate") ;
+               db.execSQL(CREATE_DOMAIN_TABLE_SQL);
+               db.execSQL(CREATE_IP_TEBLE_SQL);
+               db.execSQL(CREATE_CONNECT_FAIL_TABLE_SQL);
+       }
+
+       /**
+        * 数据库版本更新策略(直接放弃旧表)
+        */
+       @Override
+       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+               // TODO Auto-generated method stub
+               //Log.d("DB", "onUpgrade") ;
+        if (oldVersion != newVersion) {
+            // 其它情况,直接放弃旧表.
+            db.beginTransaction();
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_DOMAIN + ";");
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_IP + ";");
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_CONNECT_FAIL + ";");
+            db.setTransactionSuccessful();
+            db.endTransaction();
+            onCreate(db);
+        }
+       }
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       
+       /**
+        * 添加一条新的记录 。如果域名重复删除旧数据。
+        *
+        * @param url
+        * @param sp
+        * @param model
+        * @return
+        */
+    public DomainModel addDomainModel(String url, String sp, DomainModel model) {
+        synchronized (synLock) {
+            // 过滤重复数据
+            ArrayList<DomainModel> domainList = (ArrayList<DomainModel>) QueryDomainInfo(model.domain, model.sp);
+            if (domainList != null && domainList.size() > 0) {
+                //之所以删除该记录是为了保证 与过期ip数据断开关联关系。
+                //比如:第一次拉下来的是1、2、3ip数据。第二次拉下来是4、5、6ip数据。那么1、2、3关联的did就会失效。 即:1、2、3记录成为无效数据
+                deleteDomainInfo(domainList);
+            }
+            SQLiteDatabase db = getWritableDatabase();
+            ContentValues cv = new ContentValues();
+            try {
+                db.beginTransaction();
+                cv.put(DOMAIN_COLUMN_DOMAIN, model.domain);
+                cv.put(DOMAIN_COLUMN_SP, model.sp);
+                cv.put(DOMAIN_COLUMN_TTL, model.ttl);
+                cv.put(DOMAIN_COLUMN_TIME, model.time);
+                model.id = db.insert(TABLE_NAME_DOMAIN, null, cv);
+                for (int i = 0; i < model.ipModelArr.size(); i++) {
+                    IpModel temp = model.ipModelArr.get(i);
+                    // 更新内存中IP表中的d_id字段
+                    IpModel oldModel = getIpModel(temp.ip, sp);
+                    IpModel ipModel = null;
+                    // 若数据库中无此条数据,则插入一条
+                    if (oldModel == null) {
+                        ipModel = temp;
+                        ipModel.d_id = model.id;
+                        ipModel.id = addIpModel(ipModel);
+                    } else {
+                        ipModel = oldModel;
+                        ipModel.d_id = model.id;
+                        // 若数据库中存在此条数据,则更新对应的domainId即可
+                        updateIpInfo(ipModel);
+                    }
+                    model.ipModelArr.remove(i);
+                    model.ipModelArr.add(i, ipModel);
+                }
+                db.setTransactionSuccessful();
+            } catch (Exception e) {
+                e.printStackTrace();
+                // 上报错误
+            } finally {
+                db.endTransaction();
+                db.close();
+            }
+            return model;
+        }
+    }
+       
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       
+       /**
+        * 根据url 获取缓存domain
+        * 
+        * @param domain
+        * @param sp
+        * @return
+        */
+       public List<DomainModel> QueryDomainInfo(String domain, String sp){
+
+               synchronized (synLock) {
+                       List<DomainModel> list = new ArrayList<DomainModel>() ;
+               StringBuilder sql = new StringBuilder();
+               sql.append("SELECT * FROM ");
+               sql.append(TABLE_NAME_DOMAIN);
+               sql.append(" WHERE ");
+               sql.append(DOMAIN_COLUMN_DOMAIN);
+               sql.append(" =? ");
+               sql.append(" AND ");
+               sql.append(DOMAIN_COLUMN_SP);
+               sql.append(" =? ;");
+               SQLiteDatabase db = getReadableDatabase();
+               Cursor cursor = null;
+                       try {
+                               cursor = db.rawQuery(sql.toString(), new String[] { domain, sp });
+                               if (cursor != null && cursor.getCount() > 0) {
+                                       cursor.moveToFirst();
+                                       do {
+                                               DomainModel model = new DomainModel() ;
+                                               model.id = cursor.getInt(cursor.getColumnIndex(DOMAIN_COLUMN_ID));
+                                               model.domain = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_DOMAIN));
+                                               model.sp = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_SP));
+                                               model.ttl = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_TTL));
+                        model.time = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_TIME));
+                                               model.ipModelArr = (ArrayList<IpModel>) QueryIpModelInfo(model) ; 
+                                               list.add(model) ;
+                       } while (cursor.moveToNext());
+                               }
+       
+                       } catch (Exception e) {
+                               // TODO: handle exception
+                               e.printStackTrace();
+                       } finally {
+                               cursor.close();
+                               db.close() ;
+               }
+                       return list ; 
+               }
+       }
+       
+       /**
+        * 通过url获取服务器ip信息
+        * 根据 domainModel 获取Ipmodel 对象。 
+        * @param domainModel
+        * @return
+        */
+       private List<IpModel> QueryIpModelInfo( DomainModel domainModel ){
+               
+               // 内部方法 不需要加锁
+                       List<IpModel> list = new ArrayList<IpModel>() ; 
+               StringBuilder sql = new StringBuilder();
+               sql.append("SELECT * FROM ");
+               sql.append(TABLE_NAME_IP);
+               sql.append(" WHERE ");
+               sql.append(IP_COLUMN_DOMAIN_ID);
+               sql.append(" =? ;");
+               SQLiteDatabase db = getReadableDatabase();
+               Cursor cursor = null;
+               try {
+                       cursor = db.rawQuery(sql.toString(), new String[] { String.valueOf( domainModel.id ) });
+                       if (cursor != null && cursor.getCount() > 0) {
+                               cursor.moveToFirst();
+                               do{
+                                       IpModel ip = new IpModel() ; 
+                                       ip.id = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_ID));
+                                       ip.d_id = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_DOMAIN_ID));
+                                       ip.ip = cursor.getString(cursor.getColumnIndex(IP_COLUMN_IP));
+//                        ip.ip = String.valueOf( Tools.longToIP( Long.parseLong( ip.ip ) ) );
+                                       ip.port = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_PORT));
+                                       ip.sp = cursor.getString(cursor.getColumnIndex(IP_COLUMN_SP));
+                                       ip.ttl = cursor.getString(cursor.getColumnIndex(IP_COLUMN_TTL));
+                                       ip.priority = cursor.getString(cursor.getColumnIndex(IP_COLUMN_PRIORITY));
+                                       ip.rtt = cursor.getString(cursor.getColumnIndex(IP_COLUMN_RTT));
+                                       ip.success_num = cursor.getString(cursor.getColumnIndex(IP_COLUMN_SUCCESS_NUM));
+                                       ip.err_num = cursor.getString(cursor.getColumnIndex(IP_COLUMN_ERR_NUM));
+                                       ip.finally_success_time = cursor.getString(cursor.getColumnIndex(IP_COLUMN_FINALLY_SUCCESS_TIME));
+                                       ip.finally_fail_time = cursor.getString(cursor.getColumnIndex(IP_COLUMN_FINALLY_FAIL_TIME));
+                                       list.add(ip) ;
+                               }while(cursor.moveToNext());
+                       }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       } finally {
+                               cursor.close();
+                               db.close() ;
+               }
+
+               return list ;
+       }
+       
+    /**
+     * 根据 服务器 ip 获取数据库的数据集
+     *
+     * @param serverIp
+     * @return
+     */
+    private IpModel getIpModel(String serverIp, String sp){
+
+       ArrayList<IpModel> list = new ArrayList<IpModel>();
+
+        synchronized (synLock) {
+
+            StringBuilder sql = new StringBuilder();
+            sql.append("SELECT * FROM ");
+            sql.append(TABLE_NAME_IP);
+            sql.append(" WHERE ");
+            sql.append(IP_COLUMN_IP);
+            sql.append(" =? ");
+               sql.append(" AND ");
+               sql.append(DOMAIN_COLUMN_SP);
+               sql.append(" =? ;");
+               
+            SQLiteDatabase db = getWritableDatabase();
+            Cursor cursor = null;
+            try {
+                cursor = db.rawQuery(sql.toString(), new String[]{serverIp, sp});
+                if (cursor != null && cursor.getCount() > 0) {
+                    cursor.moveToFirst();
+                    do {
+                        IpModel ip = new IpModel();
+                        ip.id = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_ID));
+                        ip.d_id = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_DOMAIN_ID));
+                        ip.ip = cursor.getString(cursor.getColumnIndex(IP_COLUMN_IP));
+                        ip.port = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_PORT));
+                        ip.sp = cursor.getString(cursor.getColumnIndex(IP_COLUMN_SP));
+                        ip.ttl = cursor.getString(cursor.getColumnIndex(IP_COLUMN_TTL));
+                        ip.priority = cursor.getString(cursor.getColumnIndex(IP_COLUMN_PRIORITY));
+                        ip.rtt = cursor.getString(cursor.getColumnIndex(IP_COLUMN_RTT));
+                        ip.success_num = cursor.getString(cursor.getColumnIndex(IP_COLUMN_SUCCESS_NUM));
+                        ip.err_num = cursor.getString(cursor.getColumnIndex(IP_COLUMN_ERR_NUM));
+                        ip.finally_success_time = cursor.getString(cursor.getColumnIndex(IP_COLUMN_FINALLY_SUCCESS_TIME));
+                        ip.finally_fail_time = cursor.getString(cursor.getColumnIndex(IP_COLUMN_FINALLY_FAIL_TIME));
+                        list.add(ip);
+                    } while (cursor.moveToNext());
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                cursor.close();
+                //db.close();
+            }
+        }
+
+        // 排除下重复的IP 理论上是不会出现重复IP的, 多线程同时写数据库有锁。
+        if( list.size() > 1 ){
+               for( int i = 0 ; i < list.size() - 1 ; i++ ){
+                       IpModel ipModel = list.get(i);
+                       deleteIpServer(ipModel.id) ; 
+               } 
+        }
+
+        return list.size() > 0 ? list.get(list.size() - 1) : null ;
+    }
+       
+       /**
+        * 根据域名id 删除域名相关信息
+        */
+       private void deleteDomainInfo(long domain_id){
+               
+               synchronized (synLock) {
+                       SQLiteDatabase db = getWritableDatabase();
+                       try {
+                                db.delete(TABLE_NAME_DOMAIN, DOMAIN_COLUMN_ID + " = ?", new String[]{String.valueOf(domain_id)} ) ;
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       } finally {
+                   db.close();
+               }
+               }
+       }
+
+//    /**
+//     * 根据域名id 删除服务器相关信息
+//     * @param domain_id
+//     */
+//    private void deleteIpInfo(long domain_id){
+//
+//        synchronized (synLock) {
+//            SQLiteDatabase db = getWritableDatabase();
+//            try {
+//                db.delete(TABLE_NAME_IP, IP_COLUMN_DOMAIN_ID + " = ?", new String[]{String.valueOf(domain_id)} ) ;
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//            } finally {
+//                db.close();
+//            }
+//        }
+//    }
+    
+    /**
+     * 根据 ID 删除服务器信息
+     * @param ip
+     */
+    private void deleteIpServer(long id){
+
+        synchronized (synLock) {
+            SQLiteDatabase db = getWritableDatabase();
+            try {
+                db.delete(TABLE_NAME_IP, IP_COLUMN_ID + " = ?", new String[]{String.valueOf(id)} ) ;
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                db.close();
+            }
+        }
+    }
+
+
+       /**
+        * 删除域名相关信息
+        */
+       public void deleteDomainInfo(DomainModel domainModel){
+               deleteDomainInfo( domainModel.id) ;
+       }
+       
+       /**
+        * 删除域名相关信息
+        */
+       public void deleteDomainInfo(ArrayList<DomainModel> domainModelArr){
+               for( DomainModel temp : domainModelArr )
+                       deleteDomainInfo( temp.id) ;
+       }
+       
+       
+    /**
+     * 清除缓存数据
+     */
+       public void clear() {
+           synchronized (synLock) {
+               SQLiteDatabase db = getWritableDatabase();
+               try {
+                   db.delete(TABLE_NAME_DOMAIN, null, null);
+                   db.delete(TABLE_NAME_IP, null, null);
+                   db.delete(TABLE_NAME_CONNECT_FAIL, null, null);
+               } catch (Exception e) {
+                   e.printStackTrace();
+               } finally {
+                   db.close();
+               }
+        }
+       }
+
+
+       /**
+        * 返回 domain  表信息
+        */
+       public ArrayList<DomainModel> getAllTableDomain(boolean appendIpInfo) {
+           ArrayList<DomainModel> list = new ArrayList<DomainModel>();
+           synchronized (synLock) {
+               StringBuilder sql = new StringBuilder();
+               sql.append("SELECT * FROM ");
+               sql.append(TABLE_NAME_DOMAIN);
+               sql.append(" ; ");
+               SQLiteDatabase db = getReadableDatabase();
+               Cursor cursor = null;
+               try {
+                   cursor = db.rawQuery(sql.toString(), null);
+                   if (cursor != null && cursor.getCount() > 0) {
+                       cursor.moveToFirst();
+                       do {
+                           DomainModel model = new DomainModel();
+                           model.id = cursor.getInt(cursor.getColumnIndex(DOMAIN_COLUMN_ID));
+                           model.domain = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_DOMAIN));
+                           model.sp = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_SP));
+                           model.ttl = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_TTL));
+                           model.time = cursor.getString(cursor.getColumnIndex(DOMAIN_COLUMN_TIME));
+                           if (appendIpInfo) {
+                            model.ipModelArr = (ArrayList<IpModel>) QueryIpModelInfo(model);
+                        }
+                           list.add(model);
+                       } while (cursor.moveToNext());
+                   }
+               } catch (Exception e) {
+                   // TODO: handle exception
+                   e.printStackTrace();
+               } finally {
+                   cursor.close();
+                   db.close();
+               }
+           }
+           return list;
+       }
+    /**
+     * 返回 domain  表信息
+     */
+    public ArrayList<DomainModel> getAllTableDomain() {
+        return getAllTableDomain(false);
+    }
+
+
+    /**
+     * 返回 ip 表信息
+     */
+    public ArrayList<IpModel> getTableIP(){
+        synchronized (synLock) {
+               ArrayList<IpModel> list = new ArrayList<IpModel>();
+            StringBuilder sql = new StringBuilder();
+            sql.append("SELECT * FROM ");
+            sql.append(TABLE_NAME_IP);
+            sql.append(" ; ");
+
+            SQLiteDatabase db = getReadableDatabase();
+            Cursor cursor = null;
+            try {
+                cursor = db.rawQuery(sql.toString(), null);
+                if (cursor != null && cursor.getCount() > 0) {
+                    cursor.moveToFirst();
+                    do {
+                        IpModel ip = new IpModel();
+                        ip.id = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_ID));
+                        ip.d_id = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_DOMAIN_ID));
+                        ip.ip = cursor.getString(cursor.getColumnIndex(IP_COLUMN_IP));
+                        ip.port = cursor.getInt(cursor.getColumnIndex(IP_COLUMN_PORT));
+                        ip.sp = cursor.getString(cursor.getColumnIndex(IP_COLUMN_SP));
+                        ip.ttl = cursor.getString(cursor.getColumnIndex(IP_COLUMN_TTL));
+                        ip.priority = cursor.getString(cursor.getColumnIndex(IP_COLUMN_PRIORITY));
+                        ip.rtt = cursor.getString(cursor.getColumnIndex(IP_COLUMN_RTT));
+                        ip.success_num = cursor.getString(cursor.getColumnIndex(IP_COLUMN_SUCCESS_NUM));
+                        ip.err_num = cursor.getString(cursor.getColumnIndex(IP_COLUMN_ERR_NUM));
+                        ip.finally_success_time = cursor.getString(cursor.getColumnIndex(IP_COLUMN_FINALLY_SUCCESS_TIME));
+                        ip.finally_fail_time = cursor.getString(cursor.getColumnIndex(IP_COLUMN_FINALLY_FAIL_TIME));
+                        list.add(ip);
+                    } while (cursor.moveToNext());
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                cursor.close();
+                db.close();
+            }
+            return list ; 
+        }
+    }
+    /**
+     * 向数据库中新增一条ip记录
+     * @param model
+     * @return
+     */
+    public long addIpModel(IpModel model) {
+        synchronized (synLock) {
+            SQLiteDatabase db = getWritableDatabase();
+            ContentValues cv = new ContentValues();
+            cv.put(IP_COLUMN_DOMAIN_ID, model.d_id);
+            cv.put(IP_COLUMN_IP, model.ip);
+            cv.put(IP_COLUMN_PORT, model.port);
+            cv.put(IP_COLUMN_PRIORITY, model.priority);
+            cv.put(IP_COLUMN_SP, model.sp);
+
+            cv.put(IP_COLUMN_RTT, model.rtt);
+            cv.put(IP_COLUMN_FINALLY_FAIL_TIME, model.finally_fail_time);
+            cv.put(IP_COLUMN_FINALLY_SUCCESS_TIME, model.finally_success_time);
+            cv.put(IP_COLUMN_SUCCESS_NUM, model.success_num);
+            cv.put(IP_COLUMN_ERR_NUM, model.err_num);
+            cv.put(IP_COLUMN_TTL, model.ttl);
+            return db.insert(TABLE_NAME_IP, null, cv);
+        }
+    }
+    
+    /**
+     * 更新数据库中的一条ip记录
+     * @param model
+     * @return
+     */
+    private void updateIpInfo(IpModel model) {
+        synchronized (synLock) {
+            SQLiteDatabase db = getWritableDatabase();
+            ContentValues cv = new ContentValues();
+            StringBuilder where = new StringBuilder();
+            where.append(IP_COLUMN_ID);
+            where.append(" = ? ");
+            cv.put(IP_COLUMN_DOMAIN_ID, model.d_id);
+            cv.put(IP_COLUMN_IP, model.ip);
+            cv.put(IP_COLUMN_PORT, model.port);
+            cv.put(IP_COLUMN_PRIORITY, model.priority);
+            cv.put(IP_COLUMN_SP, model.sp);
+
+            cv.put(IP_COLUMN_RTT, model.rtt);
+            cv.put(IP_COLUMN_FINALLY_FAIL_TIME, model.finally_fail_time);
+            cv.put(IP_COLUMN_FINALLY_SUCCESS_TIME, model.finally_success_time);
+            cv.put(IP_COLUMN_SUCCESS_NUM, model.success_num);
+            cv.put(IP_COLUMN_ERR_NUM, model.err_num);
+            cv.put(IP_COLUMN_TTL, model.ttl);
+            String[] args = new String[] { String.valueOf(model.id) };
+            db.update(TABLE_NAME_IP, cv, where.toString(), args);
+        }
+    }
+    
+    /**
+     * 批量更新ip表数据
+     * @param model
+     * @return
+     */
+    public void updateIpInfo(List<IpModel> ipModels) {
+        synchronized (synLock) {
+            SQLiteDatabase db = getWritableDatabase();
+            db.beginTransaction();
+            try {
+                for (IpModel model : ipModels) {
+                    ContentValues cv = new ContentValues();
+                    StringBuilder where = new StringBuilder();
+                    where.append(IP_COLUMN_ID);
+                    where.append(" = ? ");
+                    cv.put(IP_COLUMN_DOMAIN_ID, model.d_id);
+                    cv.put(IP_COLUMN_IP, model.ip);
+                    cv.put(IP_COLUMN_PORT, model.port);
+                    cv.put(IP_COLUMN_PRIORITY, model.priority);
+                    cv.put(IP_COLUMN_SP, model.sp);
+                    
+                    cv.put(IP_COLUMN_RTT, model.rtt);
+                    cv.put(IP_COLUMN_FINALLY_FAIL_TIME, model.finally_fail_time);
+                    cv.put(IP_COLUMN_FINALLY_SUCCESS_TIME, model.finally_success_time);
+                    cv.put(IP_COLUMN_SUCCESS_NUM, model.success_num);
+                    cv.put(IP_COLUMN_ERR_NUM, model.err_num);
+                    cv.put(IP_COLUMN_TTL, model.ttl);
+                    String[] args = new String[] { String.valueOf(model.id) };
+                    db.update(TABLE_NAME_IP, cv, where.toString(), args);
+                }
+                db.setTransactionSuccessful();
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally{
+                db.endTransaction();
+                db.close();
+            }
+        }
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/cache/DnsCacheManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/cache/DnsCacheManager.java
new file mode 100644 (file)
index 0000000..5027aed
--- /dev/null
@@ -0,0 +1,251 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.cache;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+
+import com.sina.util.dnscache.model.DomainModel;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.model.IpModel;
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: DnsCacheManager <br>
+ * 类描述: Dnd缓存层管理类 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-3-26 下午6:10:10 <br>
+ * 
+ * 修改人:  <br>
+ * 修改时间:  <br>
+ * 修改备注:  <br>
+ * 
+ * @version V1.0
+ */
+public class DnsCacheManager extends DNSCacheDatabaseHelper implements IDnsCache{
+
+    public DnsCacheManager(Context context) {
+               super(context);
+               db = new DNSCacheDatabaseHelper(context) ;
+       }
+
+    /**
+     * 数据库操作类
+     */
+    private DNSCacheDatabaseHelper db = null ; 
+    
+       /**
+     * 缓存初始容量值
+     */
+    private final int INIT_SIZE = 8;
+
+    /**
+     * 缓存最大容量值
+     */
+    private final int MAX_CACHE_SIZE = 32;
+
+    /**
+     * 延迟差值,单位s
+     */
+    public static int ip_overdue_delay = 20 ;
+
+    /**
+     * 缓存链表
+     */
+       @SuppressLint("NewApi")
+       private ConcurrentHashMap<String, DomainModel> data = new ConcurrentHashMap<String, DomainModel>(INIT_SIZE, MAX_CACHE_SIZE);
+
+
+    /////////////////////////////////////////////////////////////////////////////////////////////
+
+       /**
+        * 获取url缓存
+        * @param url
+        * @return
+        */
+    @Override
+       public DomainModel getDnsCache(String sp, String url){
+
+       
+               DomainModel model = data.get(url) ;
+               
+               if( model == null ){
+                       //缓存中没有从数据库中查找
+                       ArrayList<DomainModel> list = (ArrayList<DomainModel>) db.QueryDomainInfo(url, sp ) ;
+                       if( list != null && list.size() != 0){
+                               model = list.get( list.size() - 1 ) ;
+                       }
+                       
+                       //查询到数据 添加到缓存中
+               if( model != null )addMemoryCache(url, model) ;
+                       
+               }
+
+               if( model != null){
+                       //检测是否过期  
+            if( isExpire(model, ip_overdue_delay) ){
+                model = null ;
+            }
+               }
+
+               return model ; 
+       }
+
+
+    /**
+     * 插入本地 cache 缓存
+     *
+     * @param dnsPack
+     * @return
+     */
+    public DomainModel insertDnsCache(HttpDnsPack dnsPack){
+
+        DomainModel domainModel = new DomainModel() ;
+        domainModel.domain = dnsPack.domain ;
+        domainModel.sp = dnsPack.localhostSp ;
+        domainModel.time = String.valueOf(System.currentTimeMillis());
+
+        domainModel.ipModelArr = new ArrayList<IpModel>();
+
+        int domainTTL = 60 ;
+        for( HttpDnsPack.IP temp : dnsPack.dns ){
+
+            IpModel ipModel = new IpModel() ;
+            ipModel.ip = temp.ip ;
+            ipModel.ttl = temp.ttl ;
+            ipModel.priority = temp.priority ;
+
+            ipModel.port = 80 ;
+            ipModel.sp = domainModel.sp ;
+            
+            domainModel.ipModelArr.add(ipModel) ;
+
+            domainTTL = Math.min(domainTTL, Integer.valueOf(ipModel.ttl));
+
+        }
+
+        domainModel.ttl = String.valueOf(domainTTL);
+
+        if( domainModel != null && domainModel.ipModelArr != null && domainModel.ipModelArr.size() > 0){
+               // 插入数据库
+               domainModel = super.addDomainModel(dnsPack.domain,dnsPack.localhostSp,domainModel) ;
+               // 插入内存缓存
+               addMemoryCache( domainModel.domain, domainModel );
+        }
+
+        return domainModel ;
+    }
+
+    /**
+     * 获取即将过期的 domain 数据
+     * @return
+     */
+    @Override
+       public ArrayList<DomainModel> getExpireDnsCache() {
+
+               ArrayList<DomainModel> listDomain = new ArrayList<DomainModel>();
+
+               for (Entry<String, DomainModel> entry : data.entrySet()) {
+                       DomainModel temp = data.get(entry.getKey());
+                       if (isExpire(temp)) {
+                               listDomain.add(temp);
+                       }
+               }
+
+               return listDomain;
+       }
+
+
+    /**
+     * 获取缓存中全部的 DomainModel数据
+     */
+    public ArrayList<DomainModel> getAllMemoryCache() {
+       ArrayList<DomainModel> list = new ArrayList<DomainModel>() ; 
+               for (Entry<String, DomainModel> entry : data.entrySet()) {
+                       DomainModel temp = data.get(entry.getKey());
+                       list.add(temp) ; 
+               }
+       return list; 
+    }    
+    
+    /**
+     * 清除全部缓存
+     */
+    public void clear(){
+        super.clear();
+        data.clear();
+    }
+    
+    /**
+     * 清除内存缓存
+     */
+    public void clearMemoryCache(){
+        data.clear();
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////////////
+
+
+    /**
+        * 添加url缓存
+        * @param model
+        */
+       public void addMemoryCache(String url, DomainModel model) {
+
+               if( model == null ) return ; 
+               if( model.ipModelArr == null ) return ; 
+               if( model.ipModelArr.size() <= 0 ) return ; 
+               for( IpModel ipModel : model.ipModelArr ){
+                       if( ipModel == null ) return ; 
+               }
+               
+               // 检测下缓存中是否存在, 如果存在删除旧数据在添加
+               DomainModel temp = data.get(url);
+               if (temp != null) {
+                       data.remove(url);
+               }
+
+               data.put(url, model);
+       }
+
+
+    /**
+     * 检测是否过期,提前3秒刷一下
+     * @param domainModel
+     * @return
+     */
+    private boolean isExpire(DomainModel domainModel) {
+        return isExpire(domainModel, -3);
+    }
+
+    /**
+     * 检测是否过期
+     * 
+     * @param domainModel
+     * @return
+     */
+    private boolean isExpire(DomainModel domainModel, long difference) {
+        long queryTime = Long.parseLong(domainModel.time) / 1000;
+        long ttl = Long.parseLong(domainModel.ttl);
+        long newTime = System.currentTimeMillis() / 1000;
+        if ((newTime - queryTime) > (ttl + difference)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void setSpeedInfo(List<IpModel> ipModels) {
+        updateIpInfo(ipModels);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////////////
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/cache/IDnsCache.java b/dNSCache/src/main/java/com/sina/util/dnscache/cache/IDnsCache.java
new file mode 100644 (file)
index 0000000..0223788
--- /dev/null
@@ -0,0 +1,95 @@
+package com.sina.util.dnscache.cache;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sina.util.dnscache.model.DomainModel;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.model.IpModel;
+
+/**
+*
+* 项目名称: DNSCache <br>
+* 类名称: IDnsCache <br>
+* 类描述: 缓存层对外接口 <br>
+* 创建人: fenglei <br>
+* 创建时间: 2015-3-26 下午6:12:10 <br>
+* 
+* 修改人:  <br>
+* 修改时间:  <br>
+* 修改备注:  <br>
+* 
+* @version V1.0
+*/
+public interface IDnsCache {
+
+    /**
+     * 获取 domain 缓存
+     * @param sp
+     * @param domain
+     * @return
+     */
+    public DomainModel getDnsCache( String sp, String domain ) ;
+
+
+    /**
+     * 插入一条缓存记录
+     * @param dnsPack
+     * @return
+     */
+    public DomainModel insertDnsCache(HttpDnsPack dnsPack) ;
+
+    
+    /**
+     * 批量更新测速后信息,保证事务的原子性。即保持一个域名下的所有ip都同时修改。
+     * @param ipModels
+     */
+    public void setSpeedInfo(List<IpModel> ipModels) ;
+
+
+    /**
+     * 获取即将过期的domain信息
+     * @return
+     */
+    public ArrayList<DomainModel> getExpireDnsCache() ;
+    
+    /**
+     * 内存中 增加缓存信息
+     * @param url
+     * @param model
+     */
+    public void addMemoryCache(String url, DomainModel model) ;
+
+
+    /**
+     * 清除全部缓存数据
+     */
+    public void clear();
+    
+    
+    /**
+     * 清除内存缓存
+     */
+    public void clearMemoryCache() ;
+    
+    /**
+     * 获取缓存中全部的 DomainModel数据
+     * @return
+     */
+    public ArrayList<DomainModel> getAllMemoryCache() ;
+
+
+    /**
+     * 获取数据库 domain 表,默认不追加ip表的数据
+     */
+    public ArrayList<DomainModel> getAllTableDomain();
+    
+    public ArrayList<DomainModel> getAllTableDomain(boolean appendIpinfo);
+
+
+    /**
+     * 获取数据库 ip 表
+     */
+    public ArrayList<IpModel> getTableIP() ;
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/DnsConfig.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/DnsConfig.java
new file mode 100644 (file)
index 0000000..346781a
--- /dev/null
@@ -0,0 +1,52 @@
+package com.sina.util.dnscache.dnsp;
+
+import java.util.ArrayList;
+
+/**
+*
+* 项目名称: DNSCache <br>
+* 类名称: HttpDnsConfig <br>
+* 类描述: HTTPDNS 接口配置类 <br>
+* 创建人: fenglei <br>
+* 创建时间: 2015-4-15 下午9:10:10 <br>
+* 
+* 修改人:  <br>
+* 修改时间:  <br>
+* 修改备注:  <br>
+* 
+* @version V1.0
+*/
+public class DnsConfig {
+
+       /**
+        * 是否使用 自己的httpdns 服务器
+        */
+       public static boolean enableSinaHttpDns = true ; 
+       
+       /**
+        * DNSPOD http dns 开端
+        */
+       public static boolean enableDnsPod = true ; 
+       
+       /**
+        * DNSPOD http dns 开端
+        */
+       public static boolean enableUdpDns = true ; 
+       
+    /**
+     * httpdns 服务器地址
+     */
+    public static ArrayList<String> SINA_HTTPDNS_SERVER_API = new ArrayList<String>();
+    
+    /**
+     * DNSPOD 服务器地址
+     */
+    public static String DNSPOD_SERVER_API = "" ;
+    
+    /**
+     * dns 服务器地址
+     */
+    public static String UDPDNS_SERVER_API = "" ;
+    
+    
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/DnsManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/DnsManager.java
new file mode 100644 (file)
index 0000000..6825c3f
--- /dev/null
@@ -0,0 +1,79 @@
+package com.sina.util.dnscache.dnsp;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import com.sina.util.dnscache.DNSCacheConfig;
+import com.sina.util.dnscache.Tools;
+import com.sina.util.dnscache.dnsp.impl.HttpPodDns;
+import com.sina.util.dnscache.dnsp.impl.LocalDns;
+import com.sina.util.dnscache.dnsp.impl.SinaHttpDns;
+import com.sina.util.dnscache.dnsp.impl.UdpDns;
+import com.sina.util.dnscache.log.HttpDnsLogManager;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.net.networktype.NetworkManager;
+
+public class DnsManager implements IDns {
+
+    ArrayList<IDnsProvider> mDnsProviders = new ArrayList<IDnsProvider>();
+    private ArrayList<String> debugInfo = new ArrayList<String>();
+
+    public DnsManager() {
+        mDnsProviders.add(new SinaHttpDns());
+        mDnsProviders.add(new HttpPodDns());
+        mDnsProviders.add(new UdpDns());
+        mDnsProviders.add(new LocalDns());
+    }
+
+    @Override
+    public HttpDnsPack requestDns(String domain) {
+        Collections.sort(mDnsProviders, new Comparator<IDnsProvider>() {
+            @Override
+            public int compare(IDnsProvider lhs, IDnsProvider rhs) {
+                if (lhs == null || rhs == null) {
+                    return 0;
+                } else {
+                    // 按照降序排序
+                    return rhs.getPriority() - lhs.getPriority();
+                }
+            }
+        });
+        for (IDnsProvider dp : mDnsProviders) {
+            Tools.log("TAG", "访问" + dp.getClass().getSimpleName() + "接口开始," + "\n优先级是:" + dp.getPriority() + "\n该模块是否开启:" + dp.isActivate()
+                    + "\n该模块的API地址是:" + dp.getServerApi());
+            if (dp.isActivate()) {
+                HttpDnsPack dnsPack = dp.requestDns(domain);
+                Tools.log("TAG", "访问" + dp.getClass().getSimpleName() + "接口结束," + "\n返回的结果是:" + dnsPack);
+                if (null != dnsPack) {
+                    if (DNSCacheConfig.DEBUG) {
+                        if (null != debugInfo) {
+                            debugInfo.add(dnsPack.rawResult + "[from:" + dp.getClass().getSimpleName() + "]");
+                        }
+                    }
+                    
+                    dnsPack.localhostSp = NetworkManager.getInstance().getSPID() ;
+                       if( !dnsPack.device_sp.equals( dnsPack.localhostSp ) ){
+                               HttpDnsLogManager.getInstance().writeLog(HttpDnsLogManager.TYPE_ERROR, HttpDnsLogManager.ACTION_ERR_SPINFO, dnsPack.toJson() );
+                       }
+                    
+                    return dnsPack;
+                }
+            }
+        }
+
+        HttpDnsLogManager.getInstance().writeLog(HttpDnsLogManager.TYPE_ERROR, HttpDnsLogManager.ACTION_ERR_DOMAININFO, "{\"domain\":" + "\"" + domain + "\"}" );
+        
+        return null;
+    }
+
+    @Override
+    public ArrayList<String> getDebugInfo() {
+        return debugInfo;
+    }
+
+    @Override
+    public void initDebugInfo() {
+        debugInfo = new ArrayList<String>();
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IDns.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IDns.java
new file mode 100644 (file)
index 0000000..3b54141
--- /dev/null
@@ -0,0 +1,28 @@
+package com.sina.util.dnscache.dnsp;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.HttpDnsPack;
+
+public interface IDns {
+
+    /**
+     * 请求dns server,解析该domain域名
+     * @param domain
+     * @return
+     */
+    public HttpDnsPack requestDns(String domain) ;
+    
+    /**
+     * debug调试信息
+     * @return
+     */
+    public ArrayList<String> getDebugInfo() ;
+
+    /**
+     * 初始化debug信息
+     * @return
+     */
+    public void initDebugInfo() ;
+
+}
\ No newline at end of file
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IDnsProvider.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IDnsProvider.java
new file mode 100644 (file)
index 0000000..cd8a6fe
--- /dev/null
@@ -0,0 +1,31 @@
+package com.sina.util.dnscache.dnsp;
+
+import com.sina.util.dnscache.model.HttpDnsPack;
+
+public interface IDnsProvider {
+
+    /**
+     * 请求dns server,返回指定的域名解析信息
+     * @return
+     */
+    public HttpDnsPack requestDns(String domain) ;
+    
+    /**
+     * 被执行的优先级
+     * @return
+     */
+    public int getPriority();
+    
+    /**
+     * 是否是激活状态
+     * @return
+     */
+    public boolean isActivate();
+    
+    
+    /**
+     * 获取dns server的地址
+     * @return
+     */
+    public String getServerApi();
+}
\ No newline at end of file
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IJsonParser.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/IJsonParser.java
new file mode 100644 (file)
index 0000000..d2610e5
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.dnsp;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import com.sina.util.dnscache.model.HttpDnsPack;
+
+/**
+ *
+ * 项目名称: DNSCache 类名称: IJsonParser 类描述: 创建人: fenglei 创建时间: 2015-3-30 下午3:37:05
+ * 
+ * 修改人: 修改时间: 修改备注:
+ * 
+ * @version V1.0
+ */
+public interface IJsonParser {
+
+    public HttpDnsPack JsonStrToObj(String jsonStr) throws Exception;
+
+    public class JavaJSON_SINAHTTPDNS implements IJsonParser {
+
+        @Override
+        public HttpDnsPack JsonStrToObj(String jsonStr) throws Exception {
+            HttpDnsPack dnsPack = new HttpDnsPack();
+            JSONObject jsonObj = new JSONObject(jsonStr);
+            dnsPack.rawResult = jsonStr;
+            dnsPack.domain = jsonObj.getString("domain");
+            dnsPack.device_ip = jsonObj.getString("device_ip");
+            dnsPack.device_sp = jsonObj.getString("device_sp");
+
+            JSONArray jsonarray = jsonObj.getJSONArray("dns");
+            dnsPack.dns = new HttpDnsPack.IP[jsonarray.length()];
+            for (int i = 0; i < dnsPack.dns.length; i++) {
+                JSONObject tempJsonObj = new JSONObject(jsonarray.getString(i));
+                dnsPack.dns[i] = new HttpDnsPack.IP();
+                dnsPack.dns[i].ip = tempJsonObj.getString("ip");
+                dnsPack.dns[i].ttl = tempJsonObj.getString("ttl");
+                dnsPack.dns[i].priority = tempJsonObj.getString("priority");
+            }
+            return dnsPack;
+        }
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/HttpPodDns.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/HttpPodDns.java
new file mode 100644 (file)
index 0000000..6deb74b
--- /dev/null
@@ -0,0 +1,176 @@
+package com.sina.util.dnscache.dnsp.impl;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.sina.util.dnscache.DNSCacheConfig;
+import com.sina.util.dnscache.Tools;
+import com.sina.util.dnscache.dnsp.DnsConfig;
+import com.sina.util.dnscache.dnsp.IDnsProvider;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.net.ApacheHttpClientNetworkRequests;
+import com.sina.util.dnscache.net.networktype.NetworkManager;
+
+public class HttpPodDns implements IDnsProvider {
+
+    private ApacheHttpClientNetworkRequests netWork;
+
+    public HttpPodDns() {
+        netWork = new ApacheHttpClientNetworkRequests();
+    }
+
+    @Override
+    public HttpDnsPack requestDns(String domain) {
+        // 如果新浪自家的服务器没有拿到数据,或者数据有问题,则使用 dnspod 提供的接口获取数据
+        String jsonDataStr = null;
+        HttpDnsPack dnsPack = null;
+
+        String dnspod_httpdns_api_url = DnsConfig.DNSPOD_SERVER_API + DNSPodCipher.Encryption(domain);
+        jsonDataStr = netWork.requests(dnspod_httpdns_api_url);
+        if (jsonDataStr == null || jsonDataStr.equals(""))
+            return null; // 如果dnspod 也没提取到数据 则返回空
+
+        jsonDataStr = DNSPodCipher.Decryption(jsonDataStr);
+
+        dnsPack = new HttpDnsPack();
+        try {
+            String IP_TTL[] = jsonDataStr.split(",");
+            String IPArr[] = IP_TTL[0].split(";");
+            String TTL = IP_TTL[1];
+            dnsPack.rawResult = jsonDataStr;
+            dnsPack.domain = domain;
+            dnsPack.device_ip = NetworkManager.Util.getLocalIpAddress();
+            dnsPack.device_sp = NetworkManager.getInstance().getSPID() ; 
+
+            dnsPack.dns = new HttpDnsPack.IP[IPArr.length];
+            for (int i = 0; i < IPArr.length; i++) {
+                dnsPack.dns[i] = new HttpDnsPack.IP();
+                dnsPack.dns[i].ip = IPArr[i];
+                dnsPack.dns[i].ttl = TTL;
+                dnsPack.dns[i].priority = "0";
+            }
+        } catch (Exception e) {
+            dnsPack = null;
+        }
+        return dnsPack;
+    }
+
+    @Override
+    public boolean isActivate() {
+        return DnsConfig.enableDnsPod;
+    }
+
+    static class DNSPodCipher {
+
+        public static String Encryption(String domain) {
+
+            if (DNSCacheConfig.Data.getInstance().DNSPOD_ID == null || DNSCacheConfig.Data.getInstance().DNSPOD_ID.equals(""))
+                return domain;
+
+            if (DNSCacheConfig.Data.getInstance().DNSPOD_KEY == null || DNSCacheConfig.Data.getInstance().DNSPOD_KEY.equals(""))
+                return domain;
+
+            try {
+                // 初始化密钥
+                SecretKeySpec keySpec = new SecretKeySpec(DNSCacheConfig.Data.getInstance().DNSPOD_KEY.getBytes("utf-8"), "DES");
+                // 选择使用 DES 算法,ECB 方式,填充方式为 PKCS5Padding
+                Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
+                // 初始化
+                cipher.init(Cipher.ENCRYPT_MODE, keySpec);
+                // 获取加密后的字符串
+                byte[] encryptedString = cipher.doFinal(domain.getBytes("utf-8"));
+
+                Tools.log("TAG_NET", bytesToHexString(encryptedString));
+
+                return bytesToHexString(encryptedString) + "&id=" + DNSCacheConfig.Data.getInstance().DNSPOD_ID;
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            return "";
+        }
+
+        public static String Decryption(String data) {
+
+            if (DNSCacheConfig.Data.getInstance().DNSPOD_ID == null || DNSCacheConfig.Data.getInstance().DNSPOD_ID.equals(""))
+                return data;
+
+            if (DNSCacheConfig.Data.getInstance().DNSPOD_KEY == null || DNSCacheConfig.Data.getInstance().DNSPOD_KEY.equals(""))
+                return data;
+
+            try {
+                // 初始化密钥
+                SecretKeySpec keySpec = new SecretKeySpec(DNSCacheConfig.Data.getInstance().DNSPOD_KEY.getBytes("utf-8"), "DES");
+                // 选择使用 DES 算法,ECB 方式,填充方式为 PKCS5Padding
+                Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
+                // 初始化
+                cipher.init(Cipher.DECRYPT_MODE, keySpec);
+                // 获取解密后的字符串
+                byte[] decryptedString = cipher.doFinal(hexStringToBytes(data));
+
+                Tools.log("TAG_NET", new String(decryptedString));
+
+                return new String(decryptedString);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            return "";
+        }
+
+        public static String bytesToHexString(byte[] src) {
+            StringBuilder stringBuilder = new StringBuilder("");
+            if (src == null || src.length <= 0) {
+                return null;
+            }
+            for (int i = 0; i < src.length; i++) {
+                int v = src[i] & 0xFF;
+                String hv = Integer.toHexString(v);
+                if (hv.length() < 2) {
+                    stringBuilder.append(0);
+                }
+                stringBuilder.append(hv);
+            }
+            return stringBuilder.toString();
+        }
+
+        public static byte[] hexStringToBytes(String hexString) {
+            if (hexString == null || hexString.equals("")) {
+                return null;
+            }
+            hexString = hexString.toUpperCase();
+            int length = hexString.length() / 2;
+            char[] hexChars = hexString.toCharArray();
+            byte[] d = new byte[length];
+            for (int i = 0; i < length; i++) {
+                int pos = i * 2;
+                d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
+            }
+            return d;
+        }
+
+        /**
+         * Convert char to byte
+         * 
+         * @param c
+         *            char
+         * @return byte
+         */
+        private static byte charToByte(char c) {
+            return (byte) "0123456789ABCDEF".indexOf(c);
+        }
+
+    }
+
+    @Override
+    public String getServerApi() {
+        return DnsConfig.DNSPOD_SERVER_API;
+    }
+
+    @Override
+    public int getPriority() {
+        return 8;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/LocalDns.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/LocalDns.java
new file mode 100644 (file)
index 0000000..b90e019
--- /dev/null
@@ -0,0 +1,65 @@
+package com.sina.util.dnscache.dnsp.impl;
+
+import java.net.InetAddress;
+
+import com.sina.util.dnscache.dnsp.IDnsProvider;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.net.networktype.NetworkManager;
+
+public class LocalDns implements IDnsProvider {
+
+    @Override
+    public HttpDnsPack requestDns(String domain) {
+        try {
+            InetAddress[] addresses = InetAddress.getAllByName(domain);
+            String[] ipList = new String[addresses.length];
+            for (int i = 0; i < addresses.length; i++) {
+                ipList[i] = addresses[i].getHostAddress();
+            }
+            if (null != ipList && ipList.length > 0) {
+                HttpDnsPack dnsPack = new HttpDnsPack();
+                String IPArr[] = ipList;
+                String TTL = "60";
+                dnsPack.domain = domain;
+                dnsPack.device_ip = NetworkManager.Util.getLocalIpAddress();
+                dnsPack.device_sp = NetworkManager.getInstance().getSPID() ;
+                dnsPack.rawResult = "domain:" + domain + ";\nipArray:";
+                dnsPack.dns = new HttpDnsPack.IP[IPArr.length];
+                for (int i = 0; i < IPArr.length; i++) {
+                    String ip = IPArr[i];
+                    if (i == IPArr.length - 1) {
+                        //去掉最后的逗号
+                        dnsPack.rawResult += (ip);
+                    } else {
+                        dnsPack.rawResult += (ip + ",");
+                    }
+                    dnsPack.dns[i] = new HttpDnsPack.IP();
+                    dnsPack.dns[i].ip = ip;
+                    dnsPack.dns[i].ttl = TTL;
+                    dnsPack.dns[i].priority = "0";
+                }
+                return dnsPack;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    @Override
+    public int getPriority() {
+        return 0;
+    }
+
+    @Override
+    public boolean isActivate() {
+        return true;
+    }
+
+    @Override
+    public String getServerApi() {
+        return null;
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/SinaHttpDns.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/SinaHttpDns.java
new file mode 100644 (file)
index 0000000..fe2452e
--- /dev/null
@@ -0,0 +1,75 @@
+package com.sina.util.dnscache.dnsp.impl;
+
+import java.util.ArrayList;
+
+import android.text.TextUtils;
+
+import com.sina.util.dnscache.dnsp.DnsConfig;
+import com.sina.util.dnscache.dnsp.IDnsProvider;
+import com.sina.util.dnscache.dnsp.IJsonParser;
+import com.sina.util.dnscache.dnsp.IJsonParser.JavaJSON_SINAHTTPDNS;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.net.ApacheHttpClientNetworkRequests;
+
+public class SinaHttpDns implements IDnsProvider{
+
+    private ApacheHttpClientNetworkRequests netWork;
+    private JavaJSON_SINAHTTPDNS jsonObj;
+    private String usingServerApi = "";
+    public SinaHttpDns() {
+        netWork = new ApacheHttpClientNetworkRequests();
+        jsonObj = new IJsonParser.JavaJSON_SINAHTTPDNS();
+    }
+
+    @Override
+    public HttpDnsPack requestDns(String domain) {
+        String jsonDataStr = null;
+        HttpDnsPack dnsPack = null;
+        ArrayList<String> serverApis = new ArrayList<String>();
+        serverApis.addAll(DnsConfig.SINA_HTTPDNS_SERVER_API);
+        while (null == dnsPack && serverApis.size() > 0) {
+            try {
+                String api = "";
+                int index = serverApis.indexOf(usingServerApi);
+                if (index != -1) {
+                    api = serverApis.remove(index);
+                } else {
+                    api = serverApis.remove(0);
+                }
+                String sina_httpdns_api_url = api + domain;
+                jsonDataStr = netWork.requests(sina_httpdns_api_url);
+                dnsPack = jsonObj.JsonStrToObj(jsonDataStr);
+                usingServerApi = api;
+            } catch (Exception e) {
+                e.printStackTrace();
+                usingServerApi = "";
+            }
+        }
+        return dnsPack;
+    }
+
+    @Override
+    public boolean isActivate() {
+        return DnsConfig.enableSinaHttpDns;
+    }
+    
+
+    @Override
+    public String getServerApi() {
+        String serverApi = "";
+        if (!TextUtils.isEmpty(usingServerApi)) {
+            serverApi = usingServerApi;
+        } else {
+            boolean yes = DnsConfig.SINA_HTTPDNS_SERVER_API.size() > 0;
+            if (yes) {
+                serverApi = DnsConfig.SINA_HTTPDNS_SERVER_API.get(0);
+            }
+        }
+        return serverApi;
+    }
+
+    @Override
+    public int getPriority() {
+        return 10;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/UdpDns.java b/dNSCache/src/main/java/com/sina/util/dnscache/dnsp/impl/UdpDns.java
new file mode 100644 (file)
index 0000000..4e130da
--- /dev/null
@@ -0,0 +1,208 @@
+package com.sina.util.dnscache.dnsp.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketTimeoutException;
+
+import com.sina.util.dnscache.dnsp.DnsConfig;
+import com.sina.util.dnscache.dnsp.IDnsProvider;
+import com.sina.util.dnscache.dnsp.impl.UdpDns.UdnDnsClient.UdpDnsInfo;
+import com.sina.util.dnscache.model.HttpDnsPack;
+import com.sina.util.dnscache.net.networktype.NetworkManager;
+
+public class UdpDns implements IDnsProvider {
+
+    @Override
+    public HttpDnsPack requestDns(String domain) {
+        try {
+            UdpDnsInfo info = UdnDnsClient.query(DnsConfig.UDPDNS_SERVER_API, domain);
+            if (null != info && info.ips.length > 0) {
+                HttpDnsPack dnsPack = new HttpDnsPack();
+                String IPArr[] = info.ips;
+                String TTL = String.valueOf(info.ttl);
+                dnsPack.rawResult = "domain : " + domain + "\n" + info.toString();
+                dnsPack.domain = domain;
+                dnsPack.device_ip = NetworkManager.Util.getLocalIpAddress();
+                dnsPack.device_sp = NetworkManager.getInstance().getSPID();
+
+                dnsPack.dns = new HttpDnsPack.IP[IPArr.length];
+                for (int i = 0; i < IPArr.length; i++) {
+                    dnsPack.dns[i] = new HttpDnsPack.IP();
+                    dnsPack.dns[i].ip = IPArr[i];
+                    dnsPack.dns[i].ttl = TTL;
+                    dnsPack.dns[i].priority = "0";
+                }
+                return dnsPack;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    static class UdnDnsClient {
+        private final static int TIME_OUT = 2000;
+        private final static int PORT = 53;
+        private final static int BUF_SIZE = 1024;
+
+        static class UdpDnsInfo {
+            public int ttl;
+            public String[] ips;
+
+            @Override
+            public String toString() {
+                StringBuilder info = new StringBuilder();
+                info.append("ttl : " + ttl + "\n");
+                info.append("ipArray : ");
+                if (null != ips) {
+                    for (String ip : ips) {
+                        info.append(ip + ",");
+                    }
+                } else {
+                    info.append("null   ");
+                }
+                return info.toString();
+            }
+        }
+
+        private static UdpDnsInfo query(String dnsServerIP, String domainName) throws SocketTimeoutException, IOException {
+            UdpDnsInfo info = new UdpDnsInfo();
+            DatagramSocket socket = new DatagramSocket(0);
+            socket.setSoTimeout(TIME_OUT);
+
+            ByteArrayOutputStream outBuf = new ByteArrayOutputStream(BUF_SIZE);
+            DataOutputStream output = new DataOutputStream(outBuf);
+            encodeDNSMessage(output, domainName);
+
+            InetAddress host = InetAddress.getByName(dnsServerIP);
+            DatagramPacket request = new DatagramPacket(outBuf.toByteArray(), outBuf.size(), host, PORT);
+
+            socket.send(request);
+
+            byte[] inBuf = new byte[BUF_SIZE];
+            ByteArrayInputStream inBufArray = new ByteArrayInputStream(inBuf);
+            DataInputStream input = new DataInputStream(inBufArray);
+            DatagramPacket response = new DatagramPacket(inBuf, inBuf.length);
+
+            socket.receive(response);
+
+            decodeDNSMessage(input, info);
+
+            socket.close();
+            return info;
+        }
+
+        private static void encodeDNSMessage(DataOutputStream output, String domainName) throws IOException {
+            // transaction id
+            output.writeShort(1);
+            // flags
+            output.writeShort(0x100);
+            // number of queries
+            output.writeShort(1);
+            // answer, auth, other
+            output.writeShort(0);
+            output.writeShort(0);
+            output.writeShort(0);
+
+            encodeDomainName(output, domainName);
+
+            // query type
+            output.writeShort(1);
+            // query class
+            output.writeShort(1);
+
+            output.flush();
+        }
+
+        private static void encodeDomainName(DataOutputStream output, String domainName) throws IOException {
+            for (String label : domainName.split("\\.")) {
+                output.writeByte((byte) label.length());
+                output.write(label.getBytes());
+            }
+            output.writeByte(0);
+        }
+
+        private static void decodeDNSMessage(DataInputStream input, UdpDnsInfo info) throws IOException {
+            // header
+            // transaction id
+            input.skip(2);
+            // flags
+            input.skip(2);
+            // number of queries
+            input.skip(2);
+            // answer, auth, other
+            short numberOfAnswer = input.readShort();
+            input.skip(2);
+            input.skip(2);
+
+            // question record
+            skipDomainName(input);
+            // query type
+            input.skip(2);
+            // query class
+            input.skip(2);
+
+            // answer records
+            for (int i = 0; i < numberOfAnswer; i++) {
+                input.mark(1);
+                byte ahead = input.readByte();
+                input.reset();
+                if ((ahead & 0xc0) == 0xc0) {
+                    // compressed name
+                    input.skip(2);
+                } else {
+                    skipDomainName(input);
+                }
+
+                // query type
+                short type = input.readShort();
+                // query class
+                input.skip(2);
+                // ttl
+                int ttl = input.readInt();
+                info.ttl = ttl;
+                short addrLen = input.readShort();
+                info.ips = new String[1];
+                if (type == 1 && addrLen == 4) {
+                    int addr = input.readInt();
+                    info.ips[0] = (longToIp(addr));
+                } else {
+                    input.skip(addrLen);
+                }
+            }
+        }
+
+        private static void skipDomainName(DataInputStream input) throws IOException {
+            byte labelLength = 0;
+            do {
+                labelLength = input.readByte();
+                input.skip(labelLength);
+            } while (labelLength != 0);
+        }
+
+        private static String longToIp(long ip) {
+            return ((ip >> 24) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + (ip & 0xFF);
+        }
+    }
+
+    @Override
+    public boolean isActivate() {
+        return DnsConfig.enableUdpDns;
+    }
+
+    @Override
+    public String getServerApi() {
+        return DnsConfig.UDPDNS_SERVER_API;
+    }
+
+    @Override
+    public int getPriority() {
+        return 7;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/log/FileUtil.java b/dNSCache/src/main/java/com/sina/util/dnscache/log/FileUtil.java
new file mode 100644 (file)
index 0000000..ced07e9
--- /dev/null
@@ -0,0 +1,124 @@
+package com.sina.util.dnscache.log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.os.Environment;
+import android.os.StatFs;
+
+/**
+ * 文件操作工具类
+ * 
+ * @author xingyu10
+ *
+ */
+public class FileUtil {
+
+    /**
+     * 判断SD卡是否还有可用空间,小于10M为不可用
+     * 
+     * @return
+     */
+    public static boolean haveFreeSpaceInSD() {
+        if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
+            StatFs st = new StatFs(Environment.getExternalStorageDirectory().getPath());
+            int blockSize = st.getBlockSize();
+            long available = st.getAvailableBlocks();
+            long availableSize = (blockSize * available);
+            if (availableSize < 1024 * 1024 * 10) {// //sd卡空间如果小于10M,就认为sd卡空间不足
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 获取SD卡的路径
+     * 
+     * @return
+     */
+    public static String getSDPath() {
+        return Environment.getExternalStorageDirectory().getPath();
+    }
+
+    /**
+     * 写文件内容,一次只写一行
+     * 
+     * @param file 目标文件
+     * @param append 是否追加
+     * @param line 一行字符串
+     */
+    public static void writeFileLine(File file, boolean append, String line) {
+        FileWriter writer = null;
+        try {
+            if (!file.exists()) {
+                file.createNewFile();
+            }
+            writer = new FileWriter(file, append);
+            String lineSeparator = System.getProperty("line.separator");
+            writer.write(line + lineSeparator);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (null != writer) {
+                try {
+                    writer.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    /**
+     * 调整文件行数
+     * @param file 目标文件
+     * @param maxSize 最大的文件大小
+     * @param factor 缩容因子,每次缩容的百分比
+     */
+    public static void adjustFileSize(File file, int maxSize, float factor) {
+        if (null == file || !file.exists()) {
+            return;
+        }
+        if (file.length() < maxSize) {
+            return;
+        }
+        BufferedReader reader = null;
+        List<String> result = new ArrayList<String>();
+        FileWriter writer = null;
+        try {
+            reader = new BufferedReader(new FileReader(file));
+            String line = null;
+            while ((line = reader.readLine()) != null) {
+                result.add(line);
+            }
+            file.delete();
+            file.createNewFile();
+
+            writer = new FileWriter(file, true);
+            String lineSeparator = System.getProperty("line.separator");
+            int size = result.size();
+            int startPos = (int) (size * factor);
+            for (int i = startPos; i < size; i++) {
+                writer.write(result.get(i) + lineSeparator);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            if (file.exists()) {
+                file.delete();
+            }
+        } finally {
+            try {
+                reader.close();
+                writer.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/log/HttpDnsLogManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/log/HttpDnsLogManager.java
new file mode 100644 (file)
index 0000000..c959860
--- /dev/null
@@ -0,0 +1,198 @@
+package com.sina.util.dnscache.log;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.json.JSONException;
+import org.json.JSONStringer;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+
+import com.sina.util.dnscache.AppConfigUtil;
+
+public class HttpDnsLogManager implements IDnsLog {
+
+    /**
+     * 配置文件更新地址
+     */
+    public static String LOG_UPLOAD_API = "";
+    
+    public static final boolean LOG_UPLOAD_SWITCH = false; 
+    
+    public static int sample_rate = 50;
+    /**
+     * 错误类型
+     */
+    public static final int TYPE_ERROR = 1;
+    /**
+     * 调试信息类型
+     */
+    public static final int TYPE_INFO = 2;
+    /**
+     * 测速类型
+     */
+    public static final int TYPE_SPEED = 3;
+    /**
+     * 日志文件的最大容量。8MB
+     */
+    private static final int DEFAULT_MAX_SIZE = 8 * 1024 * 1024;
+    /**
+     * 调整因子。取值大于0小于1
+     */
+    private static final float DEFAULT_FACTOR = 0.5f;
+    /**
+     * 日志文件
+     */
+    private File mLogFile;
+
+    private static HttpDnsLogManager mDnsLogManager;
+
+    /**
+     * 调试信息分类中的domain信息
+     */
+    public static final String ACTION_INFO_DOMAIN = "httpdns_domaininfo";
+    /**
+     * 调试信息分类中的pack信息
+     */
+    public static final String ACTION_INFO_PACK = "httpdns_packinfo";
+    
+    /**
+     * 调试信息分类中的config信息
+     */
+    public static final String ACTION_INFO_CONFIG = "httpdns_configinfo";
+    
+    /**
+     * 设备sp 和 server识别出口sp 不一致错误信息
+     */
+    public static final String ACTION_ERR_SPINFO = "httpdns_errspinfo";
+
+    /**
+     * 设备sp 和 server识别出口sp 不一致错误信息
+     */
+    public static final String ACTION_ERR_DOMAININFO = "httpdns_errdomaininfo";
+    
+    
+    
+    private static final Object lock = new Object();
+    private static Handler mLogHandler;
+    /**设置日志上报的间隔为1小时*/
+    public static long time_interval = 1 * 60 * 60 * 1000;
+
+    public static HttpDnsLogManager getInstance() {
+
+        if (null == mDnsLogManager) {
+            synchronized (lock) {
+                if (null == mDnsLogManager) {
+                    HandlerThread ht = new HandlerThread("logThread");
+                    ht.start();
+                    Looper looper = ht.getLooper();
+                    mLogHandler = new Handler(looper);
+                    mDnsLogManager = new HttpDnsLogManager();
+                }
+            }
+        }
+        return mDnsLogManager;
+    }
+
+    private HttpDnsLogManager() {
+        tryCreateLogFile();
+    }
+
+    private void tryCreateLogFile() {
+        if (FileUtil.haveFreeSpaceInSD()) {
+            mLogFile = new File(AppConfigUtil.getExternalCacheDir(), "httpdns.log");
+            if (null != mLogFile && !mLogFile.exists()) {
+                try {
+                    mLogFile.createNewFile();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        } else {
+            mLogFile = null;
+        }
+    }
+
+    private void adjustFileSize(File file) {
+        FileUtil.adjustFileSize(file, DEFAULT_MAX_SIZE, DEFAULT_FACTOR);
+    }
+
+    @Override
+    public File getLogFile() {
+        synchronized (lock) {
+            return mLogFile;
+        }
+    }
+
+    @Override
+    public boolean deleteLogFile() {
+        synchronized (lock) {
+            if (null != mLogFile) {
+                return mLogFile.delete();
+            }
+            return false;
+        }
+    }
+
+    private String generateJsonStr(int type, String action, String body) {
+        JSONStringer jsonStringer = new JSONStringer();
+        try {
+            jsonStringer.object()//
+                    .key("type").value(type)//
+                    .key("action").value(action)//
+                    .key("content").value(body)//
+                    .key("versionName").value(AppConfigUtil.getVersionName())//
+                    .key("did").value(AppConfigUtil.getDeviceId())//
+                    .key("appkey").value(AppConfigUtil.getAppKey())//
+                    .key("timestamp").value(System.currentTimeMillis())//
+                    .endObject();
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return "{}";
+        }
+        return jsonStringer.toString();
+    }
+
+    @Override
+    public void writeLog(int type, String action, String body) {
+        writeLog(type, action, body, false);
+    }
+    
+    @Override
+    public void writeLog(final int type, final String action, final String body, final boolean enableSample) {
+        writeLog(type, action, body, enableSample, -1);
+    }
+
+    @Override
+    public void writeLog(final int type, final String action, final String body, final boolean enableSample, final int sampleRate) {
+        mLogHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                synchronized (lock) {
+                    // 做一个采样操作
+                    boolean succ = true;
+                    if (enableSample) {
+                        if (sampleRate == -1) {
+                            succ = (int) (Math.random() * sample_rate) == 0;
+                        } else {
+                            succ = (int) (Math.random() * sampleRate) == 0;
+                        }
+                    }
+                    if (succ) {
+                        if (null != mLogFile && !mLogFile.exists()) {
+                            tryCreateLogFile();
+                        }
+                        if (null == mLogFile) {
+                            return;
+                        }
+                        adjustFileSize(mLogFile);
+                        String line = generateJsonStr(type, action, body);
+                        FileUtil.writeFileLine(mLogFile, true, line);
+                    }
+                }
+            }
+        });
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/log/IDnsLog.java b/dNSCache/src/main/java/com/sina/util/dnscache/log/IDnsLog.java
new file mode 100644 (file)
index 0000000..332a271
--- /dev/null
@@ -0,0 +1,34 @@
+package com.sina.util.dnscache.log;
+
+import java.io.File;
+
+public interface IDnsLog {
+
+    /**
+     * 记录日志
+     * 
+     * @param type
+     *            日志类型
+     * @param body
+     *            日志信息,建议用json字符串
+     */
+    void writeLog(int type, String action, String body);
+
+    void writeLog(int type, String action, String body, boolean enableSample);
+    
+    void writeLog(int type, String action, String body, boolean enableSample, int sampleRate);
+    
+    /**
+     * 获取日志文件
+     * 
+     * @return
+     */
+    File getLogFile();
+
+    /**
+     * 删除文件
+     * 
+     * @return
+     */
+    boolean deleteLogFile();
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/model/ConnectFailModel.java b/dNSCache/src/main/java/com/sina/util/dnscache/model/ConnectFailModel.java
new file mode 100644 (file)
index 0000000..fa3ecc4
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.model;
+
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: ConnectFailModel <br>
+ * 类描述: 链接异常数据模型 - 对应connect_fail表 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-3-26 下午5:26:04 <br>
+ * 
+ * 修改人:  <br>
+ * 修改时间:  <br>
+ * 修改备注:  <br>
+ * 
+ * @version V1.0
+ */
+public class ConnectFailModel {
+       
+       public ConnectFailModel(){} 
+       
+       /**
+        * 链接失败表 自曾id <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_ID 字段 <br>
+        */
+       public int id = -1 ; 
+       
+       /**
+        * 链接失败的ip地址 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_IP 字段 <br>
+        */
+       public int ip = -1 ; 
+       
+       /**
+        * 链接失败服务器的端口号 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_PORT 字段 <br>
+        */
+       public int port = -1 ; 
+       
+       /**
+        * 链接失败的错误代码,(一般都是http的错误代码) <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_ERRCODE 字段 <br>
+        */
+       public String errcode = "" ; 
+       
+       /**
+        * 链接失败时本地网络类型 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_NETWORK_TYPE 字段 <br>
+        */
+       public String network_type = "" ; 
+       
+       /**
+        * 链接失败时如果是手机运营商,则统计运营商sp—code(为了重现现场收集数据) <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_SPCODE 字段 <br>
+        */
+       public String spcode = "" ; 
+       
+       /**
+        * 链接该服务器总共的错误次数 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_COUNT 字段 <br>
+        */
+       public String count = "" ; 
+       
+       /**
+        * 链接该服务器最后失败时间 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_FINALLY_TIME 字段 <br>
+        */
+       public String finally_tiem = "" ; 
+       
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/model/DomainModel.java b/dNSCache/src/main/java/com/sina/util/dnscache/model/DomainModel.java
new file mode 100644 (file)
index 0000000..b978e54
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.model;
+
+import java.util.ArrayList;
+
+import org.json.JSONException;
+import org.json.JSONStringer;
+
+import com.sina.util.dnscache.AppConfigUtil;
+import com.sina.util.dnscache.DNSCacheConfig;
+import com.sina.util.dnscache.Tools;
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: DomainModel <br>
+ * 类描述: 域名数据模型 - 对应domain表 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-3-26 下午5:04:01 <br>
+ * 
+ * 修改人:  <br>
+ * 修改时间:  <br>
+ * 修改备注: <br>
+ * 
+ * @version V1.0
+ */
+public class DomainModel {
+
+       
+       public DomainModel(){}
+       
+       /**
+        * 自增id <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } DOMAIN_COLUMN_ID 字段 <br>
+        */
+       public long id = -1 ;
+       
+       /**
+        * 域名 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } DOMAIN_COLUMN_DOMAIN 字段 <br>
+        */
+       public String domain = "" ; 
+       
+       /**
+        * 运营商 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } DOMAIN_COLUMN_SP 字段 <br>
+        */
+       public String sp = "" ; 
+       
+       /**
+        * 域名过期时间 <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } DOMAIN_COLUMN_TTL 字段 <br>
+        */
+       public String ttl = "0" ;
+
+    /**
+     * 域名最后查询时间 <br>
+     *
+     * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } DOMAIN_COLUMN_TIME 字段 <br>
+     */
+    public String time = "0" ;
+
+
+
+
+    /**
+        * 域名关联的ip数组 <br>
+        */
+       public ArrayList<IpModel> ipModelArr = null ; 
+
+
+
+    public String toString(){
+        String str = "" ;
+        str += "域名ID = " + id + "\n" ;
+        str += "域名 = " + domain + "\n" ;
+        str += "运营商ID = " + sp + "\n" ;
+        str += "域名过期时间: = " + ttl + "\n" ;
+        str += "域名最后查询时间:" + Tools.getStringDateShort(time) + "\n" ;
+        if( ipModelArr != null && ipModelArr.size() > 0 ){
+            for( IpModel temp : ipModelArr ){
+               if( temp == null ) continue ; 
+                str += "-- " + temp.toString() ;
+            }
+        }
+
+        str += "------------------------------------------------------\n\n";
+        return str ;
+    }
+
+    public String tojson(){
+        JSONStringer jsonStringer = new JSONStringer();
+        try {
+            StringBuilder ipmodelStr = new StringBuilder();
+            ipmodelStr.append("[");
+            if (null != ipModelArr) {
+                for (IpModel ipModel : ipModelArr) {
+                    ipmodelStr.append(ipModel.toJson() + ",");
+                }
+            }
+            if (ipmodelStr.toString().endsWith(",")) {
+                ipmodelStr.deleteCharAt(ipmodelStr.length() - 1);
+            }
+            ipmodelStr.append("]");
+            
+            jsonStringer.object()//
+                    .key("domain").value(domain)//
+                    .key("sp").value(sp)//
+                    .key("ttl").value(ttl)//
+                    .key("time").value(time)//
+                    .key("ipModelArr").value(ipmodelStr.toString())//
+                    .endObject();
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return "{}";
+        }
+        return jsonStringer.toString();
+    }
+}
\ No newline at end of file
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/model/HttpDnsPack.java b/dNSCache/src/main/java/com/sina/util/dnscache/model/HttpDnsPack.java
new file mode 100644 (file)
index 0000000..936f7da
--- /dev/null
@@ -0,0 +1,151 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.model;
+
+import org.json.JSONException;
+import org.json.JSONStringer;
+
+/**
+ *
+ * 项目名称: DNSCache 类名称: HttpDnsPack 类描述:
+ * 将httpdns返回的数据封装一层,方便日后httpdns接口改动不影响数据库模型。 并且该接口还会标识httpdns错误之后的一些信息用来上报 创建人:
+ * fenglei 创建时间: 2015-3-30 上午11:20:11
+ * 
+ * 修改人: 修改时间: 修改备注:
+ * 
+ * @version V1.0
+ */
+public class HttpDnsPack {
+
+    /**
+     * httpdns 接口返回字段 域名信息
+     */
+    public String domain = "";
+
+    /**
+     * httpdns 接口返回字段 请求的设备ip(也可能是sp的出口ip)
+     */
+    public String device_ip = "";
+
+    /**
+     * httpdns 接口返回字段 请求的设备sp运营商
+     */
+    public String device_sp = "";
+
+    /**
+     * httpdns 接口返回的a记录。(目前不包含cname别名信息)
+     */
+    public IP[] dns = null;
+
+    /**
+     * 本机识别的sp运营商,手机卡下运营商正常,wifi下为ssid名字
+     */
+    public String localhostSp = "";
+
+    /**
+     * httpdns 接口返回的原始信息
+     */
+    public String rawResult;
+
+    /**
+     * 打印该类相关变量信息
+     */
+    public String toString() {
+
+        String str = "HttpDnsPack class \n";
+        str += "domain:" + domain + "\n";
+        str += "device_ip:" + device_ip + "\n";
+        str += "device_sp:" + device_sp + "\n";
+
+        if (dns != null) {
+            str += "-------------------\n";
+            for (int i = 0; i < dns.length; i++) {
+                str += "dns[" + i + "]:" + dns[i] + "\n";
+            }
+            str += "-------------------\n";
+        }
+
+        return str;
+    }
+
+    /**
+     * A记录相关字段信息
+     */
+    public static class IP {
+
+        /**
+         * A记录IP
+         */
+        public String ip = "";
+
+        /**
+         * 域名A记录过期时间
+         */
+        public String ttl = "";
+
+        /**
+         * 服务器推荐使用的A记录 级别从0-10
+         */
+        public String priority = "";
+
+
+        /**
+         * 打印该类信息
+         */
+        public String toString() {
+            String str = "IP class \n";
+            str += "ip:" + ip + "\n";
+            str += "ttl:" + ttl + "\n";
+            str += "priority:" + priority + "\n";
+            return str;
+        }
+
+        public String toJson() {
+            JSONStringer jsonStringer = new JSONStringer();
+            try {
+                jsonStringer.object()//
+                        .key("ip").value(ip)//
+                        .key("ttl").value(ttl)//
+                        .key("priority").value(priority)//
+                        .endObject();
+            } catch (JSONException e) {
+                e.printStackTrace();
+                return "{}";
+            }
+            return jsonStringer.toString();
+        }
+
+    }
+
+    public String toJson() {
+        JSONStringer jsonStringer = new JSONStringer();
+        try {
+            StringBuilder ipArrayStr = new StringBuilder();
+            ipArrayStr.append("[");
+            if (null != dns) {
+                for (IP ip : dns) {
+                    ipArrayStr.append(ip.toJson() + ",");
+                }
+            }
+            if (ipArrayStr.toString().endsWith(",")) {
+                ipArrayStr.deleteCharAt(ipArrayStr.length() - 1);
+            }
+            ipArrayStr.append("]");
+
+            jsonStringer.object()//
+                    .key("domain").value(domain)//
+                    .key("device_ip").value(device_ip)//
+                    .key("device_sp").value(device_sp)//
+                    .key("localhostSp").value(localhostSp)//
+                    .key("rawResult").value(rawResult)//
+                    .key("ipArray").value(ipArrayStr.toString())//
+                    .endObject();
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return "{}";
+        }
+        return jsonStringer.toString();
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/model/IpModel.java b/dNSCache/src/main/java/com/sina/util/dnscache/model/IpModel.java
new file mode 100644 (file)
index 0000000..5cd663f
--- /dev/null
@@ -0,0 +1,165 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.model;
+
+import org.json.JSONException;
+import org.json.JSONStringer;
+
+import com.sina.util.dnscache.Tools;
+
+
+/**
+ *
+ * 项目名称: DNSCache <br>
+ * 类名称: IpModel <br>
+ * 类描述: ip数据模型 - 对应ip表 <br>
+ * 创建人: fenglei <br>
+ * 创建时间: 2015-3-26 下午5:23:06 <br>
+ * 
+ * 修改人:  <br>
+ * 修改时间:  <br>
+ * 修改备注:  <br>
+ * 
+ * @version V1.0
+ */
+public class IpModel {
+       
+       public IpModel(){}
+       
+       /**
+        * 自增id <br>
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_ID }字段 <br>
+        */
+       public long id = -1 ; 
+       
+       /**
+        * domain id 关联id
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_DOMAIN_ID }字段 <br>
+        */
+       public long d_id = -1 ; 
+       
+       /**
+        * 服务器ip地址
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_PORT }字段 <br>
+        */
+       public String ip = "" ;
+       
+       /**
+        * ip服务器对应的端口
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_PORT }字段 <br>
+        */
+       public int port = -1 ; 
+       
+       /**
+        * ip服务器对应的sp运营商
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_SP }字段 <br>
+        */
+       public String sp = "" ; 
+       
+       /**
+        * ip过期时间
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_TTL }字段 <br>
+        */
+       public String ttl = "0" ; 
+       
+       /**
+        * ip服务器优先级-排序算法策略使用
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_PRIORITY }字段 <br>
+        */
+       public String priority = "0" ; 
+       /**
+        * 访问ip服务器的往返时延
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_PRIORITY }}字段 <br>
+        */
+       public String rtt = "0" ; 
+       
+       /**
+        * ip服务器链接产生的成功数
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_SUCCESS_NUM }字段 <br>
+        */
+       public String success_num = "0" ; 
+       
+       /**
+        * ip服务器链接产生的错误数
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_ERR_NUM }字段 <br>
+        */
+       public String err_num = "0" ; 
+       
+       /**
+        * ip服务器最后成功链接时间
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_FINALLY_SUCCESS_TIME }字段 <br>
+        */
+       public String finally_success_time = "0" ; 
+       
+       /**
+        * ip服务器最后失败链接时间
+        * 
+        * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants#IP_COLUMN_FINALLY_FAIL_TIME }字段 <br>
+        */
+       public String finally_fail_time = "0" ; 
+
+
+       
+       /**
+        * 评估体系 评分分值
+        */
+       public float grade = 0 ; 
+       
+
+    public String toString(){
+
+        String str = "*\n" ;
+
+        str += "-- 服务器id = " + id + "\n" ;
+        str += "-- 服务器ip = " + ip + "\n" ;
+        str += "-- 域名ID索引 = " + d_id + "\n" ;
+        str += "-- 服务器端口 = " + port + "\n" ;
+        str += "-- 运营商 = " + sp + "\n" ;
+        str += "-- 过期时间 = " + ttl + "\n" ;
+        str += "-- 优先级 = " + priority + "\n" ;
+        str += "-- 访问ip服务器的往返时延 = " + rtt + "\n" ;
+        str += "-- 历史成功次数 = " + success_num + "\n" ;
+        str += "-- 历史错误次数 = " + err_num + "\n" ;
+        str += "-- 最后一次访问成功时间 = " + Tools.getStringDateShort(finally_success_time) + "\n" ;
+        str += "-- 最后一次访问失败时间 = " + Tools.getStringDateShort(finally_fail_time) + "\n" ;
+        str += "-- 系统对服务器的评分 = " + grade + "\n" ;
+        str += "\n" ;
+        
+        return str ;
+    }
+    
+    public String toJson(){
+        JSONStringer jsonStringer = new JSONStringer();
+        try {
+            jsonStringer.object()//
+                    .key("id").value(id)//
+                    .key("d_id").value(d_id)//
+                    .key("ip").value(ip)//
+                    .key("port").value(port)//
+                    .key("ttl").value(ttl)//
+                    .key("priority").value(priority)//
+                    .key("success_num").value(success_num)//
+                    .key("err_num").value(err_num)//
+                    .key("finally_success_time").value(finally_success_time)//
+                    .key("finally_fail_time").value(finally_fail_time)//
+                    .endObject();
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return "{}";
+        }
+        return jsonStringer.toString();
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/net/ApacheHttpClientNetworkRequests.java b/dNSCache/src/main/java/com/sina/util/dnscache/net/ApacheHttpClientNetworkRequests.java
new file mode 100644 (file)
index 0000000..9b2d3d5
--- /dev/null
@@ -0,0 +1,266 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.net;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.params.ConnManagerParams;
+import org.apache.http.conn.params.ConnPerRouteBean;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
+import com.sina.util.dnscache.Tools;
+
+/**
+ * 
+ * 项目名称: DNSCache 类名称: ApacheHttpClientNetworkRequests 
+ * 类描述: 轻量级的网络请求库 
+ * 创建人: fenglei 
+ * 使用 Apache HttpClient 实现网络请求 
+ * 创建时间: 2015-3-30 上午11:50:49
+ * 
+ * 修改人: xingyu10 
+ * 修改时间: 2015-9-9 
+ * 修改备注: HTTPS不进行域名校验
+ * 
+ * @version V2.0
+ */
+public class ApacheHttpClientNetworkRequests implements INetworkRequests {
+    private static final int SOCKET_OPERATION_TIMEOUT = 60 * 1000;
+    private static final int CONNECTION_TIMEOUT = 30 * 1000;
+    private static final int SOCKET_BUFFER_SIZE = 8192;
+
+    public String requests(String url) {
+        return requests(url, "");
+    }
+
+    public static HttpClient newInstance() {
+        HttpParams params = new BasicHttpParams();
+        // 不自动处理重定向请求
+        params.setParameter(ClientPNames.HANDLE_REDIRECTS, false);
+        HttpConnectionParams.setStaleCheckingEnabled(params, true);
+        HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
+        HttpConnectionParams.setSoTimeout(params, SOCKET_OPERATION_TIMEOUT);
+        HttpConnectionParams.setSocketBufferSize(params, SOCKET_BUFFER_SIZE);
+        HttpConnectionParams.setTcpNoDelay(params, true);
+        ConnManagerParams.setMaxTotalConnections(params, 50);
+        ConnPerRouteBean connPerRoute = new ConnPerRouteBean();
+        connPerRoute.setDefaultMaxPerRoute(4);
+        ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);
+
+        SchemeRegistry schemeRegistry = new SchemeRegistry();
+        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+        SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
+        socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+        schemeRegistry.register(new Scheme("https", socketFactory, 443));
+        ClientConnectionManager manager = new ThreadSafeClientConnManager(params, schemeRegistry);
+        return new DefaultHttpClient(manager, params);
+    }
+
+    @Override
+    public String requests(String url, String host) {
+        HashMap<String, String> map = null;
+        if (host == null || host.equals("")) {
+            map = null;
+        } else {
+            map = new HashMap<String, String>();
+            map.put("host", host);
+        }
+
+        return requests(url, map);
+    }
+
+    @Override
+    public String requests(String url, HashMap<String, String> head) {
+
+        String result = null;
+        BufferedReader reader = null;
+
+        try {
+            HttpClient client = newInstance();
+            HttpGet request = new HttpGet();
+
+            if (head != null) {
+                for (Entry<String, String> entry : head.entrySet()) {
+                    Tools.log("TAG", "" + entry.getKey() + "  -  " + entry.getValue());
+                    request.addHeader(entry.getKey(), entry.getValue());
+                }
+            }
+
+            request.setURI(new URI(url));
+            HttpResponse response = client.execute(request);
+
+            reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+
+            StringBuffer strBuffer = new StringBuffer("");
+            String line = null;
+
+            while ((line = reader.readLine()) != null) {
+                strBuffer.append(line);
+            }
+            result = strBuffer.toString();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                    reader = null;
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public byte[] requestsByteArr(String url, HashMap<String, String> head) {
+
+        byte[] result = null;
+
+        try {
+            HttpClient client = newInstance();
+            HttpGet request = new HttpGet();
+
+            if (head != null) {
+                for (Entry<String, String> entry : head.entrySet()) {
+                    Tools.log("TAG", "" + entry.getKey() + "  -  " + entry.getValue());
+                    request.addHeader(entry.getKey(), entry.getValue());
+                }
+            }
+
+            request.setURI(new URI(url));
+            HttpResponse response = client.execute(request);
+
+            result = readStream(response.getEntity().getContent());
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+        }
+
+        return result;
+    }
+
+    /*
+     * 得到图片字节流 数组大小
+     */
+    public static byte[] readStream(InputStream inStream) {
+
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+
+        try {
+            byte[] buffer = new byte[1024];
+            int len = 0;
+            while ((len = inStream.read(buffer)) != -1) {
+                outStream.write(buffer, 0, len);
+            }
+            outStream.close();
+            inStream.close();
+
+        } catch (Exception e) {
+        }
+
+        Tools.log("TAG", "outStream.toByteArray()=" + outStream.toByteArray());
+
+        return outStream.toByteArray();
+    }
+
+    public static boolean upLoadFile(String url, File file) {
+        boolean result = false;
+        try {
+            if (null == url || null == file || !file.exists() || file.length() < 1) {
+                return false;
+            }
+            /**
+             * 第一部分
+             */
+            URL urlObj = new URL(url);
+            HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
+
+            /**
+             * 设置关键值
+             */
+            con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式
+            con.setDoInput(true);
+            con.setDoOutput(true);
+            con.setUseCaches(false); // post方式不能使用缓存
+
+            // 设置请求头信息
+            con.setRequestProperty("Connection", "Keep-Alive");
+            con.setRequestProperty("Charset", "UTF-8");
+
+            // 设置边界
+            String BOUNDARY = "----------" + System.currentTimeMillis();
+            con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
+
+            // 请求正文信息
+
+            // 第一部分:
+            StringBuilder sb = new StringBuilder();
+            sb.append("--"); // ////////必须多两道线
+            sb.append(BOUNDARY);
+            sb.append("\r\n");
+            sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"\r\n");
+            sb.append("Content-Type:application/octet-stream\r\n\r\n");
+
+            byte[] head = sb.toString().getBytes("utf-8");
+
+            // 获得输出流
+            OutputStream out = new DataOutputStream(con.getOutputStream());
+            out.write(head);
+
+            // 文件正文部分
+            DataInputStream in = new DataInputStream(new FileInputStream(file));
+            int bytes = 0;
+            byte[] bufferOut = new byte[1024];
+            while ((bytes = in.read(bufferOut)) != -1) {
+                out.write(bufferOut, 0, bytes);
+            }
+            in.close();
+
+            // 结尾部分
+            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
+            out.write(foot);
+            out.flush();
+            out.close();
+
+            int statusCode = con.getResponseCode();
+            if (statusCode == 200) {
+                result = true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/net/INetworkRequests.java b/dNSCache/src/main/java/com/sina/util/dnscache/net/INetworkRequests.java
new file mode 100644 (file)
index 0000000..d4aef2b
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 
+ */
+package com.sina.util.dnscache.net;
+
+import java.util.HashMap;
+
+/**
+ *
+ * 项目名称: DNSCache
+ * 类名称: INetworkRequests
+ * 类描述: 由于该工程是一个辅助lib 尽量复用项目工程里在使用的网络库。
+ * 创建人: fenglei
+ * 创建时间: 2015-3-30 上午11:34:07
+ * 
+ * 修改人:
+ * 修改时间: 
+ * 修改备注:
+ * 
+ * @version V1.0
+ */
+public interface INetworkRequests {
+
+       /**
+        * 请求网络接口
+        * @return 返回url数据内容
+        */
+       public String requests(String url) ;
+
+    /**
+     * 请求网络接口 (带host访问)
+     *
+     * @return 返回url数据内容
+     */
+    public String requests(String url, String host) ;
+    
+    /**
+     * 请求网络接口 (多个head访问)
+     *
+     * @return 返回url数据内容
+     */
+    public String requests(String url, HashMap<String, String> head) ;
+    
+    /**
+     * 请求网络接口 (多个head访问)
+     *
+     * @return 返回url数据内容
+     */
+    public byte[] requestsByteArr(String url, HashMap<String, String> head) ;
+       
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/Constants.java b/dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/Constants.java
new file mode 100644 (file)
index 0000000..977a2f2
--- /dev/null
@@ -0,0 +1,102 @@
+package com.sina.util.dnscache.net.networktype;
+
+public class Constants {
+
+       // //网络类型////
+
+       /**
+        * 无网络
+        */
+       public final static short NETWORK_TYPE_UNCONNECTED = -1;
+       /**
+        * 未知网络
+        */
+       public final static short NETWORK_TYPE_UNKNOWN = 0;
+       /**
+        * WIFI网络
+        */
+       public final static short NETWORK_TYPE_WIFI = 1;
+       /**
+        * 2G网络
+        */
+       public final static short NETWORK_TYPE_2G = 2;
+       /**
+        * 3G网络
+        */
+       public final static short NETWORK_TYPE_3G = 3;
+       /**
+        * 4G网络
+        */
+       public final static short NETWORK_TYPE_4G = 4;
+
+       // //网络运营商标识码///
+
+       /**
+        * 未知运营商
+        */
+       public final static int MOBILE_UNKNOWN = 0 ; // 未知运营商
+       /**
+        * mobile-中国电信
+        */
+       public final static int MOBILE_TELCOM = 3 ; // 中国电信
+       /**
+        * mobile-中国联通
+        */
+       public final static int MOBILE_UNICOM = 5; // 中国联通
+       /**
+        * mobile-中国移动
+        */
+       public final static int MOBILE_CHINAMOBILE = 4; // 中国移动
+
+
+       // 有时间可以把网络类型常量定义方式改成自学习模式,就不用每次有新发现的类型在重新填写。
+
+       public final static String NETWORK_TYPE_TO_STR(int type) {
+               String str = "";
+               switch (type) {
+               case NETWORK_TYPE_UNCONNECTED:
+                       str = "无网络";
+                       break;
+               case NETWORK_TYPE_UNKNOWN:
+                       str = "未知网络";
+                       break;
+               case NETWORK_TYPE_WIFI:
+                       str = "WIFI网络";
+                       break;
+               case NETWORK_TYPE_2G:
+                       str = "2G网络";
+                       break;
+               case NETWORK_TYPE_3G:
+                       str = "3G网络";
+                       break;
+               case NETWORK_TYPE_4G:
+                       str = "4G网络";
+                       break;
+               }
+               return str;
+       }
+
+       public final static String SP_TO_STR(int type) {
+
+               String str = "";
+
+               switch (type) {
+               case MOBILE_UNKNOWN:
+                       str = "未知运营商";
+                       break;
+               case MOBILE_TELCOM:
+                       str = "中国电信";
+                       break;
+               case MOBILE_UNICOM:
+                       str = "中国联通";
+                       break;
+               case MOBILE_CHINAMOBILE:
+                       str = "中国移动 ";
+                       break;
+               }
+               
+               return str;
+
+       }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/NetworkManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/NetworkManager.java
new file mode 100644 (file)
index 0000000..b4170aa
--- /dev/null
@@ -0,0 +1,346 @@
+package com.sina.util.dnscache.net.networktype;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.apache.http.conn.util.InetAddressUtils;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.telephony.TelephonyManager;
+
+
+@SuppressLint("NewApi")
+public class NetworkManager extends Constants{
+
+       // ///////////////////////////////////////////////////////////////////////////////////
+
+       private static NetworkManager Instance = null;
+
+       public NetworkManager() { }
+
+       public static NetworkManager CreateInstance(Context context) {
+               
+               setContext(context) ;
+               
+               if (Instance == null) {
+                       Instance = new NetworkManager();
+                       Instance.Init();
+               }
+               return Instance;
+       }
+       
+       public static NetworkManager getInstance() {
+               return Instance;
+       }
+
+       // ///////////////////////////////////////////////////////////////////////////////////
+
+    private static Context sContext;
+
+    public static void setContext(Context ctx) {
+        Context app = ctx.getApplicationContext();
+        if (sContext == app) {
+            return;
+        }
+        sContext = app;
+    }
+       
+       // ///////////////////////////////////////////////////////////////////////////////////
+
+       /**
+        * 当前网络类型
+        */
+       public int NETWORK_TYPE = -1111;
+
+       /**
+        * 当前网络类型名字
+        */
+       public String NETWORK_TYPE_STR = "-1111";
+
+       /**
+        * 当前SP类型
+        */
+       public int SP_TYPE = -1111;
+
+       /**
+        * 当前SP类型名字
+        */
+       public String SP_TYPE_STR = "-1111";
+
+       // ///////////////////////////////////////////////////////////////////////////////////
+
+       /**
+        * IP地址
+        */
+       public String IP_ADDRESS = "-1111";
+
+       /**
+        * MAC地址
+        */
+       public String MACADDRESS = "-1111";
+
+       // ///////////////////////////////////////////////////////////////////////////////////
+
+       /**
+        * 公网IP
+        */
+       public String NETWORK_IP_ADDRESS = "-1111";
+       
+       
+       // ///////////////////////////////////////////////////////////////////////////////////
+
+       
+       /**
+        * 初始化网络环境信息数据,可重复
+        */
+       public void Init() {
+
+               new Thread(new Runnable() {
+                       public void run() {
+                               // TODO Auto-generated method stub
+                               
+                               Thread.currentThread().setName("Net Work Manager Init"); 
+                               
+                               NETWORK_TYPE = Util.getNetworkType() ; 
+                               
+                               switch( NETWORK_TYPE ){
+                               
+                               case Constants.NETWORK_TYPE_UNCONNECTED:
+                               case Constants.NETWORK_TYPE_UNKNOWN:
+                                       break;
+                                       
+                               case Constants.NETWORK_TYPE_WIFI:
+                                       IP_ADDRESS = Util.getLocalIpAddress();
+                                       MACADDRESS = Util.getRouteMac() ;
+                                       SP_TYPE = Util.getWifiSp();
+                                       break;
+                                       
+                               case Constants.NETWORK_TYPE_2G:
+                               case Constants.NETWORK_TYPE_3G:
+                               case Constants.NETWORK_TYPE_4G:
+                                       SP_TYPE = Util.getSP();
+                                       break;
+                               }
+                               
+                               NETWORK_TYPE_STR = Constants.NETWORK_TYPE_TO_STR(NETWORK_TYPE) ;
+                               
+                               if( NETWORK_TYPE != NETWORK_TYPE_WIFI){
+                                       SP_TYPE_STR = Constants.SP_TO_STR(SP_TYPE) ;
+                               }else{
+                                       SP_TYPE_STR = Util.getWifiSSID(NetworkManager.sContext) ;
+                               }
+                               
+                               
+                       }
+               }).start();
+               
+       }
+       
+       
+       public String toString(){
+               String str = "" ;
+               
+               str += "当前网络类型ID:" + NETWORK_TYPE + "\n" ;  
+               str += "当前网络类型名字:" + NETWORK_TYPE_STR + "\n\n" ; 
+               
+               str += "当前服务商类型ID:" + SP_TYPE + "\n" ; 
+               str += "当前服务商类型名字:" + SP_TYPE_STR + "\n\n" ; 
+               
+               str += "内网IP:" + IP_ADDRESS + "\n" ; 
+               str += "公网IP:" + NETWORK_IP_ADDRESS + "\n" ; 
+               str += "当前MAC:" + MACADDRESS + "\n\n" ; 
+               
+               return str ; 
+       }
+       
+       
+       /**
+        * 获取 sp id
+        * @return
+        */
+       public String getSPID(){
+               if( NETWORK_TYPE == NETWORK_TYPE_WIFI ){
+                       return SP_TYPE_STR;
+               }
+               return String.valueOf( SP_TYPE ) ; 
+       }
+       
+
+       public static class Util {
+               
+               /**
+                * 获取本机IP函数
+                */
+               public static String getLocalIpAddress() {
+                       try {
+                               String ipv4;
+                               ArrayList<NetworkInterface> mylist = Collections.list(NetworkInterface.getNetworkInterfaces());
+                               for (NetworkInterface ni : mylist) {
+                                       ArrayList<InetAddress> iaList = Collections.list(ni.getInetAddresses());
+                                       for (InetAddress address : iaList) {
+                                               if (!address.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ipv4 = address.getHostAddress())) {
+                                                       return ipv4;
+                                               }
+                                       }
+                               }
+                       } catch (SocketException ex) {
+                               ex.printStackTrace() ;
+                       }
+                       return "0";
+               }
+               
+               /**
+                * 获取本机MAC地址
+                */
+           public static String getRouteMac() {
+               try {
+                   WifiManager wifiManager = (WifiManager) sContext.getSystemService(Context.WIFI_SERVICE);
+                   WifiInfo wifiInfo = wifiManager.getConnectionInfo();
+                   if (wifiInfo == null) {
+                       return "0";
+                   }
+                   return wifiInfo.getBSSID();
+               } catch (SecurityException e) {
+                       e.printStackTrace();
+               }
+               return "0";
+           }
+
+           
+           /**
+            * 获取运营商代码
+            */
+           public static int getSP() {
+
+               int code = Constants.MOBILE_UNKNOWN;
+
+               if (sContext != null) {
+
+                   try {
+                       TelephonyManager telManager = (TelephonyManager) sContext.getSystemService(Context.TELEPHONY_SERVICE);
+                       String operator = telManager.getSimOperator();
+
+                       if (operator != null) {
+                           if (operator.equals("46000") || operator.equals("46002")
+                                   || operator.equals("46007") || operator.equals("46020")) {
+
+                               /** 中国移动 */
+                               code = Constants.MOBILE_CHINAMOBILE;
+                           } else if (operator.equals("46001") || operator.equals("46006")) {
+
+                               /** 中国联通 */
+                               code = Constants.MOBILE_UNICOM;
+                           } else if (operator.equals("46003") || operator.equals("46005")) {
+
+                               /** 中国电信 */
+                               code = Constants.MOBILE_TELCOM;
+                           }
+
+                       }
+                   } catch (Exception e) {
+                       
+                       e.printStackTrace();
+                   }
+               }
+
+               return code;
+           }
+           
+           
+           /**
+            * 获取自定义当前联网类型
+            *
+            * @return 网络类型。-1为网络不可用;0为未知网络;1为WIFI;2为2G;3为3G;4为4G
+            */
+           public static int getNetworkType() {
+
+               try {
+
+                   if (sContext != null) {
+
+                       ConnectivityManager connectivity = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+                       if (connectivity == null) {
+                           return Constants.NETWORK_TYPE_UNKNOWN;
+                       }
+
+                       NetworkInfo activeNetInfo = connectivity.getActiveNetworkInfo();
+                       if (activeNetInfo == null) {
+                           return Constants.NETWORK_TYPE_UNCONNECTED;
+                       }
+
+                       if (!activeNetInfo.isAvailable() || !activeNetInfo.isConnected()) {
+                           return Constants.NETWORK_TYPE_UNCONNECTED;
+                       }
+
+                       if (activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
+                           return Constants.NETWORK_TYPE_WIFI;
+                           
+                       } else if (activeNetInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
+                               
+                           switch (activeNetInfo.getSubtype()) {
+                               case TelephonyManager.NETWORK_TYPE_CDMA:// ~ 14-64 kbps
+                               case TelephonyManager.NETWORK_TYPE_IDEN:// ~25 kbps
+                               case TelephonyManager.NETWORK_TYPE_1xRTT:// ~ 50-100 kbps
+                               case TelephonyManager.NETWORK_TYPE_EDGE:// ~ 50-100 kbps
+                               case TelephonyManager.NETWORK_TYPE_GPRS:// ~ 100 kbps
+                                   return Constants.NETWORK_TYPE_2G;
+
+                               case TelephonyManager.NETWORK_TYPE_EVDO_0:// ~ 400-1000 kbps
+                               case TelephonyManager.NETWORK_TYPE_UMTS:// ~ 400-7000 kbps
+                               case TelephonyManager.NETWORK_TYPE_EVDO_A:// ~ 600-1400 kbps
+                               case TelephonyManager.NETWORK_TYPE_HSPA:// ~ 700-1700 kbps
+                               case TelephonyManager.NETWORK_TYPE_HSUPA:// ~ 1-23 Mbps
+                               case TelephonyManager.NETWORK_TYPE_HSDPA:// ~ 2-14 Mbps
+                               case 15: // 对应TelephonyManager.NETWORK_TYPE_HSPAP: 在api level 13下没有此值,但存在此网络类型,下面直接用数值代替
+                                   return Constants.NETWORK_TYPE_3G;
+                                   
+                               case 13: // 对应TelephonyManager.NETWORK_TYPE_LTE
+                                   return Constants.NETWORK_TYPE_4G;
+                                   
+                               case TelephonyManager.NETWORK_TYPE_UNKNOWN:
+                               default:
+                                   return Constants.NETWORK_TYPE_UNKNOWN;
+                           }
+                       } else {
+                           return Constants.NETWORK_TYPE_UNKNOWN;
+                       }
+                   }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+               return Constants.NETWORK_TYPE_UNCONNECTED;
+           }
+           
+           /**
+            * 获取wifi运营商
+            * @return
+            */
+           public static int getWifiSp(){
+               
+               return 0 ; 
+           }
+        
+           /**
+            * 获取WifiSSID
+            * @param context
+            * @return
+            */
+           public static String getWifiSSID(Context context){
+               WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+               WifiInfo info = wifiMgr.getConnectionInfo();
+               String wifiId = info != null ? info.getSSID() : null;
+               return wifiId ;
+           }
+           
+       }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.java b/dNSCache/src/main/java/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.java
new file mode 100644 (file)
index 0000000..2d022b0
--- /dev/null
@@ -0,0 +1,53 @@
+package com.sina.util.dnscache.net.networktype;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.text.TextUtils;
+
+import com.sina.util.dnscache.DNSCache;
+
+public class NetworkStateReceiver extends BroadcastReceiver {
+
+       public String TAG = "TAG_NET" ; 
+       
+       @Override
+       public void onReceive(Context context, Intent intent) {
+
+               String action = intent.getAction();
+               if (TextUtils.equals(action, ConnectivityManager.CONNECTIVITY_ACTION)) {
+                   NetworkInfo networkInfo = getActiveNetwork(context);
+                       if( networkInfo != null ){ 
+                               
+                               // 刷新网络环境
+                               if( NetworkManager.getInstance() != null ) {
+                                       NetworkManager.getInstance().Init(); 
+                                       if( DNSCache.getInstance() != null ){
+                                               DNSCache.getInstance().onNetworkStatusChanged(networkInfo); 
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public static NetworkInfo getActiveNetwork(Context context) {
+               if (context == null)
+                       return null;
+               ConnectivityManager mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+               if (mConnMgr == null)
+                       return null;
+
+               NetworkInfo aActiveInfo = mConnMgr.getActiveNetworkInfo(); // 获取活动网络连接信息
+               return aActiveInfo;
+       }
+       
+    public static void register(Context context) {
+        IntentFilter mFilter = new IntentFilter();
+        mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        context.registerReceiver(new NetworkStateReceiver(), mFilter);
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/query/IQuery.java b/dNSCache/src/main/java/com/sina/util/dnscache/query/IQuery.java
new file mode 100644 (file)
index 0000000..ed9014c
--- /dev/null
@@ -0,0 +1,25 @@
+package com.sina.util.dnscache.query;
+
+import com.sina.util.dnscache.model.DomainModel;
+
+/**
+*
+* 项目名称: DNSCache <br>
+* 类名称: IQuery <br>
+* 类描述: 查询模块 对外接口 <br>
+* 创建人: fenglei <br>
+* 创建时间: 2015-4-15 下午5:23:06 <br>
+* 
+* 修改人:  <br>
+* 修改时间:  <br>
+* 修改备注:  <br>
+* 
+* @version V1.0
+*/
+public interface IQuery {
+
+    public DomainModel queryDomainIp(String sp, String host) ;
+
+    
+    public DomainModel getCacheDomainIp(String sp, String host) ;
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/query/QueryManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/query/QueryManager.java
new file mode 100644 (file)
index 0000000..be13e9a
--- /dev/null
@@ -0,0 +1,109 @@
+package com.sina.util.dnscache.query;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.cache.IDnsCache;
+import com.sina.util.dnscache.model.DomainModel;
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.speedtest.SpeedtestManager;
+
+/**
+*
+* 项目名称: DNSCache <br>
+* 类名称: QueryManager <br>
+* 类描述: 查询模块管理类 <br>
+* 创建人: fenglei <br>
+* 创建时间: 2015-4-15 下午5:23:06 <br>
+* 
+* 修改人:  <br>
+* 修改时间:  <br>
+* 修改备注:  <br>
+* 
+* @version V1.0
+*/
+public class QueryManager implements IQuery {
+
+    private IDnsCache dnsCache = null ;
+
+    public QueryManager( IDnsCache dnsCache ){
+
+        this.dnsCache = dnsCache ;
+    }
+
+    /**
+     * 根据host名字查询server ip
+     * @return
+     */
+    @Override
+    public DomainModel queryDomainIp(String sp, String host) {
+
+        // 从缓存中查询,如果为空 情况有两种 1:没有缓存数据 2:数据过期
+        DomainModel domainModel = getCacheDomainIp(sp, host);
+
+        // 如果缓存是无效数据,则取local返回
+        if (inValidData(domainModel)) {
+            
+            String[] ipList = null;
+            try {
+                InetAddress[] addresses = InetAddress.getAllByName(host);
+                ipList = new String[addresses.length];
+                for (int i = 0; i < addresses.length; i++) {
+                    ipList[i] = addresses[i].getHostAddress();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            if (null != ipList) {
+                domainModel = new DomainModel();
+                domainModel.id = -1;
+                domainModel.domain = host;
+                domainModel.sp = sp;
+                domainModel.ttl = "60";
+                domainModel.time = String.valueOf(System.currentTimeMillis());
+                domainModel.ipModelArr = new ArrayList<IpModel>();
+                for (int i = 0; i < ipList.length; i++) {
+                    domainModel.ipModelArr.add(new IpModel());
+                    domainModel.ipModelArr.get(i).ip = ipList[i];
+                    domainModel.ipModelArr.get(i).sp = sp;
+                }
+                dnsCache.addMemoryCache(host, domainModel);
+            }
+        }
+        return domainModel;
+    }
+    
+    /**
+     * 是否是无效数据。判断依据:
+     * 1.domainModel为null
+     * 2.domainModel.ipModelArr == null
+     * 3.domainModel.ipModelArr.size() == 0
+     * 4.domainModel.ipModelArr的rtt都是计算都出错,即都不通
+     * @param domainModel
+     * @return
+     */
+    private boolean inValidData(DomainModel domainModel) {
+        if (domainModel == null || domainModel.ipModelArr == null || domainModel.ipModelArr.size() == 0) {
+            return true;
+        }
+        ArrayList<IpModel> ips = domainModel.ipModelArr;
+        for (IpModel ipModel : ips) {
+            //只要有一个是通的,就认为是有效数据
+            if (!("" + SpeedtestManager.MAX_OVERTIME_RTT).equals(ipModel.rtt)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 从缓存层获取获取数据
+     * @param sp
+     * @param host
+     * @return
+     */
+    public DomainModel getCacheDomainIp(String sp, String host){
+       return dnsCache.getDnsCache(sp, host) ;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/IPlugIn.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/IPlugIn.java
new file mode 100644 (file)
index 0000000..f5bf36b
--- /dev/null
@@ -0,0 +1,18 @@
+package com.sina.util.dnscache.score;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.IpModel;
+
+
+public interface IPlugIn {
+
+       /**
+        * 插件实现计算分值的方法
+        */
+       public abstract void run( ArrayList<IpModel> list );
+       
+       abstract float getWeight();
+       
+       abstract boolean isActivated();
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/IScore.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/IScore.java
new file mode 100644 (file)
index 0000000..985e204
--- /dev/null
@@ -0,0 +1,16 @@
+package com.sina.util.dnscache.score;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.DomainModel;
+import com.sina.util.dnscache.model.IpModel;
+
+/**
+ * Created by fenglei on 15/4/21.
+ */
+public interface IScore {
+
+    public String[] serverIpScore(DomainModel domainModel) ;
+    
+    public String[] ListToArr( ArrayList<IpModel> list) ; 
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/PlugInManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/PlugInManager.java
new file mode 100644 (file)
index 0000000..7964d71
--- /dev/null
@@ -0,0 +1,63 @@
+package com.sina.util.dnscache.score;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.score.plugin.ErrNumPlugin;
+import com.sina.util.dnscache.score.plugin.PriorityPlugin;
+import com.sina.util.dnscache.score.plugin.SpeedTestPlugin;
+import com.sina.util.dnscache.score.plugin.SuccessNumPlugin;
+import com.sina.util.dnscache.score.plugin.SuccessTimePlugin;
+
+public class PlugInManager {
+
+    public ArrayList<IPlugIn> plugIn = new ArrayList<IPlugIn>();
+
+    public static float SpeedTestPluginNum = 40;
+    public static float PriorityPluginNum = 60;
+    public static float SuccessNumPluginNum = 10;
+    public static float ErrNumPluginNum = 10;
+    public static float SuccessTimePluginNum = 10;
+
+    public PlugInManager() {
+
+        plugIn.add(new SpeedTestPlugin()); // 速度插件
+        plugIn.add(new PriorityPlugin()); // 优先级推荐插件
+        plugIn.add(new SuccessNumPlugin());
+        plugIn.add(new ErrNumPlugin()); // 历史错误次数插件
+        plugIn.add(new SuccessTimePlugin());
+    }
+
+    public void run(ArrayList<IpModel> list) {
+        if (list == null || list.size() == 0) {
+            return;
+        }
+        //恢复得分为0
+        for (IpModel temp : list) {
+            if (null != temp) {
+                temp.grade = 0;
+            } else {
+                return;
+            }
+        }
+        for (IPlugIn plug : plugIn) {
+            if (plug.isActivated()) {
+                plug.run(list);
+            }
+        }
+        ipModelSort(list);
+    }
+
+    public void ipModelSort(ArrayList<IpModel> list) {
+        Collections.sort(list, new IpModelSort());
+    }
+
+    class IpModelSort implements Comparator<IpModel> {
+        @Override
+        public int compare(IpModel lhs, IpModel rhs) {
+            return (int) (rhs.grade - lhs.grade);
+        }
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/ScoreManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/ScoreManager.java
new file mode 100644 (file)
index 0000000..1786fa9
--- /dev/null
@@ -0,0 +1,55 @@
+package com.sina.util.dnscache.score;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.Tools;
+import com.sina.util.dnscache.model.DomainModel;
+import com.sina.util.dnscache.model.IpModel;
+
+/**
+ *
+ * 对 ip 进行排序
+ *
+ * Created by fenglei on 15/4/21.
+ */
+public class ScoreManager implements IScore {
+       
+       /**
+        * 是否开启排序开关
+        */
+       public static boolean IS_SORT = true ; 
+       
+       private PlugInManager plugInManager = new PlugInManager() ;
+       
+       @Override
+       public String[] serverIpScore(DomainModel domainModel) {
+
+               String[] IpArr = null ;
+
+        // 数据库中得数据,进行排序 , 当ipmodelSize 大于1个的时候在参与排序
+        if (domainModel.ipModelArr.size() > 1) {
+            if (IS_SORT) {
+                plugInManager.run(domainModel.ipModelArr);
+            } else {
+                Tools.randomSort(domainModel.ipModelArr);
+            }
+        }
+               
+               // 转换数据格式
+               IpArr = ListToArr(domainModel.ipModelArr) ; 
+
+               return IpArr;
+       }
+       
+       public String[] ListToArr( ArrayList<IpModel> list){
+               if(list == null || list.size() == 0  ) return null ; 
+               String[] IpArr = new String[list.size()];
+               for (int i = 0; i < list.size(); i++) {
+                       if( list.get(i) == null ) continue ; 
+                       IpArr[i] = list.get(i).ip;
+               }
+               return IpArr ;
+       }
+       
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/ErrNumPlugin.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/ErrNumPlugin.java
new file mode 100644 (file)
index 0000000..d75c145
--- /dev/null
@@ -0,0 +1,46 @@
+package com.sina.util.dnscache.score.plugin;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.score.IPlugIn;
+import com.sina.util.dnscache.score.PlugInManager;
+
+public class ErrNumPlugin implements IPlugIn {
+
+    @Override
+    public void run(ArrayList<IpModel> list) {
+        // 查找到最大错误数
+        float MAX_ERRNUM = 0;
+        for (IpModel temp : list) {
+            if (temp.err_num == null || temp.err_num.equals(""))
+                continue;
+            float err_num = Float.parseFloat(temp.err_num);
+            MAX_ERRNUM = Math.max(MAX_ERRNUM, err_num);
+        }
+        // 计算比值
+        if (MAX_ERRNUM == 0) {
+            return;
+        }
+        float bi = getWeight() / MAX_ERRNUM;
+        // 计算得分
+        for (IpModel temp : list) {
+            if (temp.err_num == null || temp.err_num.equals("")){
+                continue;
+            }
+            float err_num = Float.parseFloat(temp.err_num);
+            temp.grade += (err_num - (err_num * bi)); // 错误最少的 得分应该最高
+        }
+    }
+
+    @Override
+    public float getWeight() {
+        return PlugInManager.ErrNumPluginNum;
+    }
+
+    @Override
+    public boolean isActivated() {
+        return true;
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/PriorityPlugin.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/PriorityPlugin.java
new file mode 100644 (file)
index 0000000..3c0fa8b
--- /dev/null
@@ -0,0 +1,47 @@
+package com.sina.util.dnscache.score.plugin;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.score.IPlugIn;
+import com.sina.util.dnscache.score.PlugInManager;
+
+public class PriorityPlugin implements IPlugIn {
+
+    @Override
+    public void run(ArrayList<IpModel> list) {
+        // 查找到最大优先级
+        float MAX_PRIORITY = 0;
+        for (IpModel temp : list) {
+            if (temp.priority == null || temp.priority.equals(""))
+                continue;
+            float priority = Float.parseFloat(temp.priority);
+            MAX_PRIORITY = Math.max(MAX_PRIORITY, priority);
+        }
+        // 计算比值
+        if (MAX_PRIORITY == 0) {
+            return;
+        }
+        float bi = getWeight() / MAX_PRIORITY;
+        // 计算得分
+        for (IpModel temp : list) {
+            if (temp.priority == null || temp.priority.equals("")){
+                continue;
+            }
+            float priority = Float.parseFloat(temp.priority);
+            temp.grade += (priority * bi);
+        }
+
+    }
+
+    @Override
+    public float getWeight() {
+        return PlugInManager.PriorityPluginNum;
+    }
+
+    @Override
+    public boolean isActivated() {
+        return true;
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.java
new file mode 100644 (file)
index 0000000..830c0c3
--- /dev/null
@@ -0,0 +1,46 @@
+package com.sina.util.dnscache.score.plugin;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.score.IPlugIn;
+import com.sina.util.dnscache.score.PlugInManager;
+
+public class SpeedTestPlugin implements IPlugIn {
+
+    @Override
+    public void run(ArrayList<IpModel> list) {
+        // 查找到最大速度
+        float MAX_SPEED = 0;
+        for (IpModel temp : list) {
+            if (temp.rtt == null || temp.rtt.equals(""))
+                continue;
+            float finallySpeed = Float.parseFloat(temp.rtt);
+            MAX_SPEED = Math.max(MAX_SPEED, finallySpeed);
+        }
+        // 计算比值
+        if (MAX_SPEED == 0) {
+            return;
+        }
+        float bi = getWeight() / MAX_SPEED;
+        // 计算得分
+        for (IpModel temp : list) {
+            if (temp.rtt == null || temp.rtt.equals("")){
+                continue;
+            }
+            float finallySpeed = Float.parseFloat(temp.rtt);
+            temp.grade += (getWeight() - (finallySpeed * bi));
+        }
+    }
+
+    @Override
+    public float getWeight() {
+        return PlugInManager.SpeedTestPluginNum;
+    }
+
+    @Override
+    public boolean isActivated() {
+        return true;
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.java
new file mode 100644 (file)
index 0000000..f32043c
--- /dev/null
@@ -0,0 +1,47 @@
+package com.sina.util.dnscache.score.plugin;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.score.IPlugIn;
+import com.sina.util.dnscache.score.PlugInManager;
+
+public class SuccessNumPlugin implements IPlugIn {
+
+    @Override
+    public void run(ArrayList<IpModel> list) {
+        // 查找到最大历史成功次数
+        float MAX_SUCCESSNUM = 0;
+        for (IpModel temp : list) {
+            if (temp.success_num == null || temp.success_num.equals(""))
+                continue;
+            float successNum = Float.parseFloat(temp.success_num);
+            MAX_SUCCESSNUM = Math.max(MAX_SUCCESSNUM, successNum);
+        }
+        // 计算比值
+        if (MAX_SUCCESSNUM == 0) {
+            return;
+        }
+        float bi = getWeight() / MAX_SUCCESSNUM;
+        // 计算得分
+        for (IpModel temp : list) {
+            if (temp.success_num == null || temp.success_num.equals("")){
+                continue;
+            }
+            float successNum = Float.parseFloat(temp.success_num);
+            temp.grade += (successNum * bi);
+        }
+
+    }
+
+    @Override
+    public float getWeight() {
+        return PlugInManager.SuccessNumPluginNum;
+    }
+
+    @Override
+    public boolean isActivated() {
+        return true;
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.java b/dNSCache/src/main/java/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.java
new file mode 100644 (file)
index 0000000..3461c39
--- /dev/null
@@ -0,0 +1,39 @@
+package com.sina.util.dnscache.score.plugin;
+
+import java.util.ArrayList;
+
+import com.sina.util.dnscache.model.IpModel;
+import com.sina.util.dnscache.score.IPlugIn;
+import com.sina.util.dnscache.score.PlugInManager;
+
+public class SuccessTimePlugin implements IPlugIn {
+
+    @Override
+    public void run(ArrayList<IpModel> list) {
+        final float dayTime = 24 * 60;// 单位是minute
+        final float bi = getWeight() / dayTime;
+        for (IpModel temp : list) {
+            if (temp.finally_success_time == null || temp.finally_success_time.equals(""))
+                continue;
+            long lastSuccTime = Long.parseLong(temp.finally_success_time);
+            long now = System.currentTimeMillis();
+            long offTime = (now - lastSuccTime) / 1000 / 60; // 单位是minute
+            if (offTime > dayTime) {
+                continue;
+            } else {
+                temp.grade += (getWeight() - (offTime * bi));
+            }
+        }
+    }
+
+    @Override
+    public float getWeight() {
+        return PlugInManager.SuccessTimePluginNum;
+    }
+
+    @Override
+    public boolean isActivated() {
+        return true;
+    }
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/BaseSpeedTest.java b/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/BaseSpeedTest.java
new file mode 100644 (file)
index 0000000..ada9d8e
--- /dev/null
@@ -0,0 +1,20 @@
+package com.sina.util.dnscache.speedtest;
+
+
+public abstract class BaseSpeedTest {
+
+    public abstract int speedTest(String ip, String host);
+    
+    /**
+     * 被执行的优先级
+     * @return
+     */
+    public abstract int getPriority();
+    
+    /**
+     * 是否是激活状态
+     * @return
+     */
+    public abstract boolean isActivate();
+    
+}
\ No newline at end of file
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/ISpeedtest.java b/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/ISpeedtest.java
new file mode 100644 (file)
index 0000000..fb80585
--- /dev/null
@@ -0,0 +1,10 @@
+package com.sina.util.dnscache.speedtest;
+
+/**
+ * Created by fenglei on 15/4/22.
+ */
+public interface ISpeedtest {
+
+    public int speedTest(String ip, String host);
+
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/SpeedtestManager.java b/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/SpeedtestManager.java
new file mode 100644 (file)
index 0000000..ab82c89
--- /dev/null
@@ -0,0 +1,67 @@
+package com.sina.util.dnscache.speedtest;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import com.sina.util.dnscache.Tools;
+import com.sina.util.dnscache.speedtest.impl.PingTest;
+import com.sina.util.dnscache.speedtest.impl.Socket80Test;
+
+/**
+ * 测速类
+ *
+ * Created by fenglei on 15/4/22.
+ */
+public class SpeedtestManager implements ISpeedtest {
+
+    /**
+     * 请求server过程中发生错误
+     */
+    public static final int OCUR_ERROR = -1;
+    
+    public static final int MAX_OVERTIME_RTT = 9999;
+
+    /**测速的轮询间隔*/
+    public static long time_interval = 1 * 60 * 1000;
+
+    private ArrayList<BaseSpeedTest> mSpeedTests = new ArrayList<BaseSpeedTest>();;
+
+    public SpeedtestManager() {
+        mSpeedTests.add(new Socket80Test());
+        mSpeedTests.add(new PingTest());
+    }
+
+    /**
+     * 
+     * @param url
+     * @param host
+     * @return
+     */
+    @Override
+    public int speedTest(String ip, String host) {
+        Collections.sort(mSpeedTests, new Comparator<BaseSpeedTest>() {
+            @Override
+            public int compare(BaseSpeedTest lhs, BaseSpeedTest rhs) {
+                if (lhs == null || rhs == null) {
+                    return 0;
+                } else {
+                    // 按照降序排序
+                    return rhs.getPriority() - lhs.getPriority();
+                }
+            }
+        });
+
+        for (BaseSpeedTest st : mSpeedTests) {
+            Tools.log("TAG", "测速模块" + st.getClass().getSimpleName() + "启动," + "\n优先级是:" + st.getPriority() + "\n该模块是否开启:" + st.isActivate());
+            if (st.isActivate()) {
+                int rtt = st.speedTest(ip, host);
+                Tools.log("TAG", "测速模块" + st.getClass().getSimpleName() + "结束," + "\n测速的结果是(RTT):" + rtt);
+                if (rtt > OCUR_ERROR) {
+                    return rtt;
+                }
+            }
+        }
+        return OCUR_ERROR;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/impl/PingTest.java b/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/impl/PingTest.java
new file mode 100644 (file)
index 0000000..9112752
--- /dev/null
@@ -0,0 +1,74 @@
+package com.sina.util.dnscache.speedtest.impl;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import android.text.TextUtils;
+
+import com.sina.util.dnscache.speedtest.BaseSpeedTest;
+import com.sina.util.dnscache.speedtest.SpeedtestManager;
+
+public class PingTest extends BaseSpeedTest{
+
+    @Override
+    public int speedTest(String ip, String host) {
+        try {
+            return Ping.runcmd("ping -c1 -s1 -w1 " + ip);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return SpeedtestManager.OCUR_ERROR;
+    }
+
+    public static class Ping {
+        // ping -c1 -s1 -w1 www.baidu.com //-w 超时单位是s
+        private static final String TAG_BYTES_FROM = "bytes from ";
+
+        public static int runcmd(String cmd) throws Exception {
+            Runtime runtime = Runtime.getRuntime();
+            Process proc = null;
+
+            final String command = cmd.trim();
+            long startTime = System.currentTimeMillis();
+            proc = runtime.exec(command);
+            proc.waitFor();
+            long endTime = System.currentTimeMillis();
+            InputStream inputStream = proc.getInputStream();
+            String result = "unknown ip";
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+            StringBuilder resultBuilder = new StringBuilder();
+            String line = "";
+            while (null != (line = reader.readLine())) {
+                resultBuilder.append(line);
+            }
+            reader.close();
+            String responseStr = resultBuilder.toString();
+            result = responseStr.toLowerCase().trim();
+            if (isValidResult(result)) {
+                return (int) (endTime - startTime);
+            }
+            return SpeedtestManager.OCUR_ERROR;
+        }
+
+        private static boolean isValidResult(String result) {
+            if (!TextUtils.isEmpty(result)) {
+                if (result.indexOf(TAG_BYTES_FROM) > 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public int getPriority() {
+        return 0;
+    }
+
+    @Override
+    public boolean isActivate() {
+        return false;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/impl/Socket80Test.java b/dNSCache/src/main/java/com/sina/util/dnscache/speedtest/impl/Socket80Test.java
new file mode 100644 (file)
index 0000000..c0988b6
--- /dev/null
@@ -0,0 +1,47 @@
+package com.sina.util.dnscache.speedtest.impl;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import com.sina.util.dnscache.speedtest.BaseSpeedTest;
+import com.sina.util.dnscache.speedtest.SpeedtestManager;
+
+public class Socket80Test extends BaseSpeedTest {
+
+    static final int TIMEOUT = 5 * 1000;
+
+    @Override
+    public int speedTest(String ip, String host) {
+        Socket socket = null;
+        try {
+            long begin = System.currentTimeMillis();
+            Socket s1 = new Socket();
+            s1.connect(new InetSocketAddress(ip, 80), TIMEOUT);
+            long end = System.currentTimeMillis();
+            int rtt = (int) (end - begin);
+            return rtt;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (null != socket) {
+                    socket.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return SpeedtestManager.OCUR_ERROR;
+    }
+
+    @Override
+    public int getPriority() {
+        return 10;
+    }
+
+    @Override
+    public boolean isActivate() {
+        return true;
+    }
+}
diff --git a/dNSCache/src/main/java/com/sina/util/dnscache/thread/RealTimeThreadPool.java b/dNSCache/src/main/java/com/sina/util/dnscache/thread/RealTimeThreadPool.java
new file mode 100644 (file)
index 0000000..7f86144
--- /dev/null
@@ -0,0 +1,61 @@
+package com.sina.util.dnscache.thread;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class RealTimeThreadPool {
+    private static final Object lock = new Object();
+    private static RealTimeThreadPool mInstance;
+    private static ExecutorService executorService;
+
+    public static RealTimeThreadPool getInstance() {
+        if (null == mInstance) {
+            synchronized (lock) {
+                if (null == mInstance) {
+                    mInstance = new RealTimeThreadPool();
+                    executorService = new ThreadPoolExecutor(1, 100, 120, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
+                            new DefaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());
+                }
+            }
+        }
+        return mInstance;
+    }
+
+    public void execute(Runnable command) {
+        if (null != executorService && !executorService.isShutdown()) {
+            executorService.execute(command);
+        } else {
+            Thread thread = new Thread(command);
+            thread.start();
+        }
+    }
+
+    /**
+     * The default thread factory
+     */
+    static class DefaultThreadFactory implements ThreadFactory {
+        private static final AtomicInteger poolNumber = new AtomicInteger(1);
+        private final ThreadGroup group;
+        private final AtomicInteger threadNumber = new AtomicInteger(1);
+        private final String namePrefix;
+
+        DefaultThreadFactory() {
+            SecurityManager s = System.getSecurityManager();
+            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
+            namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
+        }
+
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
+            if (t.isDaemon())
+                t.setDaemon(false);
+            if (t.getPriority() != Thread.NORM_PRIORITY)
+                t.setPriority(Thread.NORM_PRIORITY);
+            return t;
+        }
+    }
+}
diff --git a/dNSCache/src/main/res/drawable-hdpi/ic_launcher.png b/dNSCache/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..288b665
Binary files /dev/null and b/dNSCache/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/dNSCache/src/main/res/drawable-mdpi/ic_launcher.png b/dNSCache/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..6ae570b
Binary files /dev/null and b/dNSCache/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/dNSCache/src/main/res/drawable-xhdpi/ic_launcher.png b/dNSCache/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..d4fb7cd
Binary files /dev/null and b/dNSCache/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/dNSCache/src/main/res/drawable-xxhdpi/ic_launcher.png b/dNSCache/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..85a6081
Binary files /dev/null and b/dNSCache/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/dNSCache/src/main/res/layout/activity_main.xml b/dNSCache/src/main/res/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..26e19b8
--- /dev/null
@@ -0,0 +1,27 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".MainActivity" >
+
+    <TextView
+        android:id="@+id/textView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text=" 输入一个需要测试的API URL:" />
+
+    <EditText
+        android:id="@+id/editText"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:text="http://api.weibo.cn/2/remind/unread_count?remind_version=94&amp;ext_all=0&amp;c=android&amp;i=f6fd268&amp;s=7fe80de0&amp;ua=Xiaomi-MI%203W__weibo__5.3.0_alpha1__android__android4.4.4&amp;wm=3333_1001&amp;idc=&amp;v_f=2&amp;from=1052895010&amp;gsid=_2A254Mx_tDeTxGeNM7lMY9ybEzD6IHXVZaRQlrDV6PUJbrdANLVfzkWo8pgH_awAHMa74PMGrs-jUSB8TTg..&amp;lang=zh_CN&amp;skin=default&amp;oldwm=3333_1001&amp;with_settings=1&amp;unread_message=1&amp;with_page_group=1" />
+
+    <Button
+        android:id="@+id/button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="测试" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/dNSCache/src/main/res/menu/menu_main.xml b/dNSCache/src/main/res/menu/menu_main.xml
new file mode 100644 (file)
index 0000000..503537b
--- /dev/null
@@ -0,0 +1,17 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
+
+    <item android:id="@+id/action_clear" android:title="@string/action_clear"
+        android:orderInCategory="100" />
+
+    <item android:id="@+id/action_printf_domain" android:title="@string/action_printf_domain"
+        android:orderInCategory="100" />
+
+    <item android:id="@+id/action_printf_ip" android:title="@string/action_printf_ip"
+        android:orderInCategory="100" />
+
+    <item android:id="@+id/action_settings" android:title="@string/action_settings"
+        android:orderInCategory="100" />
+
+</menu>
diff --git a/dNSCache/src/main/res/values/strings.xml b/dNSCache/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..c25607c
--- /dev/null
@@ -0,0 +1,9 @@
+<resources>
+    <string name="app_name">DNSCache</string>
+
+    <string name="hello_world">Hello world!</string>
+    <string name="action_printf_domain">打印域名表</string>
+    <string name="action_printf_ip">打印IP表</string>
+    <string name="action_clear">清除缓存</string>
+    <string name="action_settings">参数设置</string>
+</resources>