fix ANR
This commit is contained in:
parent
93148fcf36
commit
d1314a1b32
@ -50,8 +50,14 @@ import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.net.URL
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.concurrent.Executors
|
||||
import android.os.StrictMode
|
||||
|
||||
|
||||
// Thread pool for tile downloading to prevent blocking UI thread
|
||||
private val tileDownloadExecutor = Executors.newFixedThreadPool(4)
|
||||
|
||||
// MapState configuration for OpenStreetMap
|
||||
// Max zoom level is 18, tile size is 256x256
|
||||
// At zoom level 18, there are 2^18 = 262144 tiles in each dimension
|
||||
@ -67,6 +73,7 @@ val mapState = MapState(
|
||||
* Creates a cached tile stream provider for OpenStreetMap tiles
|
||||
* Tiles are cached in the app's cache directory for offline access and faster loading
|
||||
* Cache expires after 30 days to ensure map updates are fetched
|
||||
* Uses background thread pool to prevent ANR (Application Not Responding)
|
||||
*/
|
||||
fun createCachedTileStreamProvider(context: Context, cacheExpiryDays: Int = 30): TileStreamProvider {
|
||||
val cacheDir = File(context.cacheDir, "map_tiles")
|
||||
@ -89,12 +96,16 @@ fun createCachedTileStreamProvider(context: Context, cacheExpiryDays: Int = 30):
|
||||
// Use cached tile
|
||||
FileInputStream(tileFile)
|
||||
} else {
|
||||
// Download tile from OpenStreetMap (either new or expired)
|
||||
// Download tile from OpenStreetMap in background thread
|
||||
val future = tileDownloadExecutor.submit<FileInputStream?> {
|
||||
try {
|
||||
val url = URL("https://tile.openstreetmap.org/$zoomLvl/$col/$row.png")
|
||||
val connection = url.openConnection()
|
||||
// Set User-Agent header as required by OSM tile usage policy
|
||||
val userAgent = "${BuildConfig.APPLICATION_ID}/${BuildConfig.VERSION_NAME} (Android) (Contact: poliecho@pupes.org)"
|
||||
connection.setRequestProperty("User-Agent", userAgent)
|
||||
connection.connectTimeout = 5000 // 5 second timeout
|
||||
connection.readTimeout = 10000 // 10 second timeout
|
||||
|
||||
val inputStream = connection.getInputStream()
|
||||
|
||||
@ -108,23 +119,36 @@ fun createCachedTileStreamProvider(context: Context, cacheExpiryDays: Int = 30):
|
||||
|
||||
// Return the cached file's input stream
|
||||
FileInputStream(tileFile)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for download with timeout
|
||||
try {
|
||||
future.get() ?: run {
|
||||
// If download failed but we have a cached tile (even if expired), use it
|
||||
if (tileFile.exists()) {
|
||||
FileInputStream(tileFile)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// If download fails but we have a cached tile (even if expired), use it
|
||||
val tileFile = File(cacheDir, "tile_${zoomLvl}_${col}_${row}.png")
|
||||
// If download timed out or failed, try using expired cache
|
||||
if (tileFile.exists()) {
|
||||
try {
|
||||
FileInputStream(tileFile)
|
||||
} catch (fallbackError: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
} else {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -132,6 +156,21 @@ class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// Configure StrictMode to detect threading violations (debug mode only)
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictMode.setThreadPolicy(
|
||||
StrictMode.ThreadPolicy.Builder()
|
||||
.detectAll()
|
||||
.penaltyLog() // Log violations instead of crashing
|
||||
.build()
|
||||
)
|
||||
StrictMode.setVmPolicy(
|
||||
StrictMode.VmPolicy.Builder()
|
||||
.detectAll()
|
||||
.penaltyLog()
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
setContent {
|
||||
MaterialTheme {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user