下载重试

This commit is contained in:
2026-06-17 16:12:44 +08:00
parent 494053be1a
commit 6556e044a2
@@ -60,9 +60,11 @@ class MainActivity : AppCompatActivity() {
private var retryCount = 0
private val maxRetries = 3
private var isFirstLaunch = true
private var hasShownNetworkRetryToast = false
private var isReverseOrder = false
private var isToolbarShowing = false
// 下载源重试状态
private var downloadRetryCount = 0
private val maxDownloadRetries = 6
// 频道名消失 Runnable
private val hideChannelNameRunnable = Runnable {
@@ -81,10 +83,8 @@ class MainActivity : AppCompatActivity() {
private const val KEY_REVERSE = "reverse_order"
private const val TIMEOUT_MS = 3000
private const val CHANNEL_NAME_DURATION_MS = 3000L
private const val NETWORK_DELAY_MS = 5000L
private const val TOOLBAR_DURATION_MS = 5000L
private const val LOADING_TIMEOUT_MS = 4000L
private const val SWITCH_STATUS_DURATION_MS = 2000L
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -345,7 +345,7 @@ class MainActivity : AppCompatActivity() {
return
}
hasShownNetworkRetryToast = false
downloadRetryCount = 0
val channels = ChannelManager.loadChannels(this)
if (channels.isNotEmpty()) {
@@ -358,12 +358,28 @@ class MainActivity : AppCompatActivity() {
val sourceUrl = ChannelManager.getSavedSourceUrl(this)
if (sourceUrl != null) {
executor.execute {
downloadAndUpdateSource(sourceUrl)
// 先检查网络是否可用,如果没网就不立即尝试下载
if (isNetworkAvailable()) {
executor.execute {
downloadAndUpdateSource(sourceUrl)
}
} else {
// 没网 → 等网络回调
if (channels.isEmpty()) {
loadingText.text = "等待网络连接后自动下载频道列表..."
}
// registerNetworkCallback 会在网络连上时自动触发下载
}
}
}
private fun isNetworkAvailable(): Boolean {
val cm = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val network = cm.activeNetwork ?: return false
val caps = cm.getNetworkCapabilities(network) ?: return false
return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
private fun downloadAndUpdateSource(sourceUrl: String) {
try {
val url = URL(sourceUrl)
@@ -382,6 +398,7 @@ class MainActivity : AppCompatActivity() {
val channelCountBefore = ChannelManager.getChannelCount()
ChannelManager.saveChannels(this, lines)
val newCount = ChannelManager.getChannelCount()
downloadRetryCount = 0 // 成功,重置重试
mainHandler.post {
if (channelCountBefore == 0 && newCount > 0) {
playChannel(ChannelManager.getCurrentChannel()!!)
@@ -398,21 +415,30 @@ class MainActivity : AppCompatActivity() {
conn.disconnect()
} catch (e: Exception) {
e.printStackTrace()
if (ChannelManager.getChannelCount() == 0) {
if (!hasShownNetworkRetryToast) {
hasShownNetworkRetryToast = true
mainHandler.post {
Toast.makeText(this@MainActivity, "无法连接服务器,将在后台继续尝试...", Toast.LENGTH_LONG).show()
downloadRetryCount++
if (downloadRetryCount >= maxDownloadRetries) {
// 达到最大重试次数,停止
mainHandler.post {
if (ChannelManager.getChannelCount() == 0) {
loadingText.text = "多次尝试失败,请检查网络或源地址"
Toast.makeText(this@MainActivity, "多次尝试下载失败", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(this@MainActivity, "更新失败,使用缓存", Toast.LENGTH_SHORT).show()
}
}
mainHandler.postDelayed({
executor.execute { downloadAndUpdateSource(sourceUrl) }
}, NETWORK_DELAY_MS)
} else {
mainHandler.post {
Toast.makeText(this@MainActivity, "更新源失败,使用缓存", Toast.LENGTH_SHORT).show()
return
}
// 指数退避:5s → 10s → 20s → 40s → 60s → 120s
val delays = longArrayOf(5000, 10000, 20000, 40000, 60000, 120000)
val delay = delays.getOrElse(downloadRetryCount - 1) { 120000L }
mainHandler.post {
if (ChannelManager.getChannelCount() == 0) {
loadingText.text = "连接失败,${delay / 1000}秒后重试(${downloadRetryCount}/$maxDownloadRetries)"
}
}
mainHandler.postDelayed({
executor.execute { downloadAndUpdateSource(sourceUrl) }
}, delay)
}
}
@@ -562,7 +588,9 @@ class MainActivity : AppCompatActivity() {
connectivityManager.registerNetworkCallback(builder.build(), object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
val sourceUrl = ChannelManager.getSavedSourceUrl(this@MainActivity)
if (sourceUrl != null && ChannelManager.getChannelCount() > 0) {
if (sourceUrl != null) {
// 网络恢复,重置重试计数并尝试下载
downloadRetryCount = 0
executor.execute {
downloadAndUpdateSource(sourceUrl)
}