optimize restart

This commit is contained in:
armv9 2025-09-05 14:48:09 +09:00
parent 2259fd3777
commit 6c3eea7ef9
7 changed files with 46 additions and 24 deletions

View File

@ -202,7 +202,7 @@ class SagerNet : Application(),
var underlyingNetwork: Network? = null
var appVersionNameForDisplay = lazy {
var appVersionNameForDisplay = {
var n = BuildConfig.VERSION_NAME
if (isPreview) {
n += " " + BuildConfig.PRE_VERSION_NAME
@ -213,7 +213,7 @@ class SagerNet : Application(),
n += " DEBUG"
}
n
}
}()
}
}

View File

@ -105,6 +105,10 @@ class BaseService {
override fun getProfileName(): String = data?.proxy?.displayProfileName ?: "Idle"
override fun registerCallback(cb: ISagerNetServiceCallback, id: Int) {
if (id == SagerConnection.CONNECTION_ID_RESTART_BG) {
Runtime.getRuntime().exit(0)
return
}
if (!callbackIdMap.contains(cb)) {
callbacks.register(cb)
}

View File

@ -3,24 +3,21 @@ package io.nekohasekai.sagernet.bg
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
import android.text.TextUtils
import io.nekohasekai.sagernet.ktx.Logs
import java.io.File
import java.io.IOException
import androidx.core.text.isDigitsOnly
object Executable {
private val EXECUTABLES = setOf(
"libtrojan.so",
"libtrojan-go.so",
"libnaive.so",
"libtuic.so",
"libhysteria.so"
"libtrojan.so", "libtrojan-go.so", "libnaive.so", "libtuic.so", "libhysteria.so"
)
fun killAll(alsoKillBg: Boolean = false) {
for (process in File("/proc").listFiles { _, name -> TextUtils.isDigitsOnly(name) }
?: return) {
val exe = File(try {
// kill bg may fail
for (process in File("/proc").listFiles { _, name -> name.isDigitsOnly() } ?: return) {
val exe = File(
try {
File(process, "cmdline").inputStream().bufferedReader().use {
it.readText()
}

View File

@ -32,6 +32,9 @@ class SagerConnection(
const val CONNECTION_ID_TILE = 1
const val CONNECTION_ID_MAIN_ACTIVITY_FOREGROUND = 2
const val CONNECTION_ID_MAIN_ACTIVITY_BACKGROUND = 3
const val CONNECTION_ID_RESTART_BG = 4
var restartingApp = false
}
interface Callback {
@ -124,7 +127,7 @@ class SagerConnection(
} catch (e: RemoteException) {
e.printStackTrace()
}
callback!!.onServiceConnected(service)
callback?.onServiceConnected(service)
}
override fun onServiceDisconnected(name: ComponentName?) {
@ -137,7 +140,9 @@ class SagerConnection(
override fun binderDied() {
service = null
callbackRegistered = false
callback?.also { runOnMainDispatcher { it.onBinderDied() } }
if (!restartingApp) {
callback?.also { runOnMainDispatcher { it.onBinderDied() } }
}
}
private fun unregisterCallback() {
@ -149,7 +154,7 @@ class SagerConnection(
callbackRegistered = false
}
fun connect(context: Context, callback: Callback) {
fun connect(context: Context, callback: Callback?) {
if (connectionActive) return
connectionActive = true
check(this.callback == null)

View File

@ -20,6 +20,8 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.AttrRes
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
@ -30,10 +32,10 @@ import com.jakewharton.processphoenix.ProcessPhoenix
import io.nekohasekai.sagernet.BuildConfig
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.SagerNet
import io.nekohasekai.sagernet.bg.Executable
import io.nekohasekai.sagernet.aidl.ISagerNetService
import io.nekohasekai.sagernet.bg.BaseService
import io.nekohasekai.sagernet.bg.SagerConnection
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.database.SagerDatabase
import io.nekohasekai.sagernet.database.preference.PublicDatabase
import io.nekohasekai.sagernet.ui.MainActivity
import io.nekohasekai.sagernet.ui.ThemedActivity
import kotlinx.coroutines.Dispatchers
@ -201,7 +203,7 @@ val shortAnimTime by lazy {
fun View.crossFadeFrom(other: View) {
clearAnimation()
other.clearAnimation()
if (visibility == View.VISIBLE && other.visibility == View.GONE) return
if (isVisible && other.isGone) return
alpha = 0F
visibility = View.VISIBLE
animate().alpha(1F).duration = shortAnimTime
@ -256,10 +258,24 @@ fun triggerFullRestart(ctx: Context) {
runOnDefaultDispatcher {
SagerNet.stopService()
delay(500)
Executable.killAll(true)
runOnMainDispatcher {
SagerConnection.restartingApp = true
val connection = SagerConnection(SagerConnection.CONNECTION_ID_RESTART_BG)
connection.connect(ctx, RestartCallback {
ProcessPhoenix.triggerRebirth(ctx, Intent(ctx, MainActivity::class.java))
}
})
}
}
private class RestartCallback(val callback: () -> Unit) : SagerConnection.Callback {
override fun stateChanged(
state: BaseService.State,
profileName: String?,
msg: String?
) {
}
override fun onServiceConnected(service: ISagerNetService) {
callback()
}
}

View File

@ -80,7 +80,7 @@ class AboutFragment : ToolbarFragment(R.layout.layout_about) {
MaterialAboutActionItem.Builder()
.icon(R.drawable.ic_baseline_update_24)
.text(R.string.app_version)
.subText(SagerNet.appVersionNameForDisplay.value)
.subText(SagerNet.appVersionNameForDisplay)
.setOnClickAction {
requireContext().launchCustomTab(
"https://github.com/MatsuriDayo/NekoBoxForAndroid/releases"
@ -251,7 +251,7 @@ class AboutFragment : ToolbarFragment(R.layout.layout_about) {
.setMessage(
context.getString(
R.string.update_dialog_message,
SagerNet.appVersionNameForDisplay.value,
SagerNet.appVersionNameForDisplay,
releaseName
)
)

View File

@ -1,4 +1,4 @@
PACKAGE_NAME=moe.nb4a
VERSION_NAME=1.3.9
PRE_VERSION_NAME=pre-1.4.0-20250904-2
PRE_VERSION_NAME=pre-1.4.0-20250905-1
VERSION_CODE=43