|
1 | 1 | package rs.clash.android |
2 | 2 |
|
3 | | -import android.app.Application |
4 | | -import kotlinx.coroutines.CoroutineScope |
5 | | -import kotlinx.coroutines.Dispatchers |
6 | | -import kotlinx.coroutines.cancel |
| 3 | +import android.util.Log |
7 | 4 | import kotlinx.coroutines.flow.MutableStateFlow |
| 5 | +import uniffi.clash_android_ffi.EyreException |
| 6 | +import uniffi.clash_android_ffi.formatEyreError |
| 7 | +import android.app.Application as AndroidApplication |
8 | 8 |
|
9 | | -object Global : CoroutineScope by CoroutineScope(Dispatchers.IO) { |
10 | | - val application: Application |
11 | | - get() = applicationInstance |
12 | | - |
13 | | - private lateinit var applicationInstance: Application |
| 9 | +class Application : AndroidApplication() { |
| 10 | + override fun onCreate() { |
| 11 | + super.onCreate() |
| 12 | + // Setup uncaught exception handler |
| 13 | + setupUncaughtExceptionHandler() |
| 14 | + Global.application = this |
| 15 | + } |
| 16 | +} |
14 | 17 |
|
| 18 | +object Global { |
15 | 19 | var profilePath: String = "" |
16 | | - |
17 | 20 | val isServiceRunning = MutableStateFlow(false) |
| 21 | + lateinit var application: Application |
| 22 | +} |
18 | 23 |
|
19 | | - fun init(application: Application) { |
20 | | - this.applicationInstance = application |
21 | | - } |
| 24 | +private fun setupUncaughtExceptionHandler() { |
| 25 | + val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() |
| 26 | + |
| 27 | + Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> |
| 28 | + try { |
| 29 | + // Check if the exception is EyreException |
| 30 | + if (throwable is EyreException) { |
| 31 | + val errorMessage = formatEyreError(throwable) |
| 32 | + Log.e("Clash", "Uncaught EyreException on thread ${thread.name}:") |
| 33 | + Log.e("Clash", errorMessage) |
22 | 34 |
|
23 | | - fun destroy() { |
24 | | - cancel() |
| 35 | + // Also print to stderr |
| 36 | + System.err.println("Uncaught EyreException on thread ${thread.name}:") |
| 37 | + System.err.println(errorMessage) |
| 38 | + } else { |
| 39 | + // For other exceptions, log normally |
| 40 | + Log.e("Clash", "Uncaught exception on thread ${thread.name}:", throwable) |
| 41 | + } |
| 42 | + } catch (e: Exception) { |
| 43 | + // If something goes wrong in our handler, log it |
| 44 | + Log.e("Clash", "Error in exception handler:", e) |
| 45 | + } finally { |
| 46 | + // Call the default handler to let the system handle the crash |
| 47 | + defaultHandler?.uncaughtException(thread, throwable) |
| 48 | + } |
25 | 49 | } |
26 | 50 | } |
0 commit comments