mirror of
https://github.com/MatsuriDayo/NekoBoxForAndroid.git
synced 2025-12-20 07:00:05 +08:00
optimize restart
This commit is contained in:
parent
2259fd3777
commit
6c3eea7ef9
@ -202,7 +202,7 @@ class SagerNet : Application(),
|
|||||||
|
|
||||||
var underlyingNetwork: Network? = null
|
var underlyingNetwork: Network? = null
|
||||||
|
|
||||||
var appVersionNameForDisplay = lazy {
|
var appVersionNameForDisplay = {
|
||||||
var n = BuildConfig.VERSION_NAME
|
var n = BuildConfig.VERSION_NAME
|
||||||
if (isPreview) {
|
if (isPreview) {
|
||||||
n += " " + BuildConfig.PRE_VERSION_NAME
|
n += " " + BuildConfig.PRE_VERSION_NAME
|
||||||
@ -213,7 +213,7 @@ class SagerNet : Application(),
|
|||||||
n += " DEBUG"
|
n += " DEBUG"
|
||||||
}
|
}
|
||||||
n
|
n
|
||||||
}
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,6 +105,10 @@ class BaseService {
|
|||||||
override fun getProfileName(): String = data?.proxy?.displayProfileName ?: "Idle"
|
override fun getProfileName(): String = data?.proxy?.displayProfileName ?: "Idle"
|
||||||
|
|
||||||
override fun registerCallback(cb: ISagerNetServiceCallback, id: Int) {
|
override fun registerCallback(cb: ISagerNetServiceCallback, id: Int) {
|
||||||
|
if (id == SagerConnection.CONNECTION_ID_RESTART_BG) {
|
||||||
|
Runtime.getRuntime().exit(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!callbackIdMap.contains(cb)) {
|
if (!callbackIdMap.contains(cb)) {
|
||||||
callbacks.register(cb)
|
callbacks.register(cb)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,24 +3,21 @@ package io.nekohasekai.sagernet.bg
|
|||||||
import android.system.ErrnoException
|
import android.system.ErrnoException
|
||||||
import android.system.Os
|
import android.system.Os
|
||||||
import android.system.OsConstants
|
import android.system.OsConstants
|
||||||
import android.text.TextUtils
|
|
||||||
import io.nekohasekai.sagernet.ktx.Logs
|
import io.nekohasekai.sagernet.ktx.Logs
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import androidx.core.text.isDigitsOnly
|
||||||
|
|
||||||
object Executable {
|
object Executable {
|
||||||
private val EXECUTABLES = setOf(
|
private val EXECUTABLES = setOf(
|
||||||
"libtrojan.so",
|
"libtrojan.so", "libtrojan-go.so", "libnaive.so", "libtuic.so", "libhysteria.so"
|
||||||
"libtrojan-go.so",
|
|
||||||
"libnaive.so",
|
|
||||||
"libtuic.so",
|
|
||||||
"libhysteria.so"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
fun killAll(alsoKillBg: Boolean = false) {
|
fun killAll(alsoKillBg: Boolean = false) {
|
||||||
for (process in File("/proc").listFiles { _, name -> TextUtils.isDigitsOnly(name) }
|
// kill bg may fail
|
||||||
?: return) {
|
for (process in File("/proc").listFiles { _, name -> name.isDigitsOnly() } ?: return) {
|
||||||
val exe = File(try {
|
val exe = File(
|
||||||
|
try {
|
||||||
File(process, "cmdline").inputStream().bufferedReader().use {
|
File(process, "cmdline").inputStream().bufferedReader().use {
|
||||||
it.readText()
|
it.readText()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,9 @@ class SagerConnection(
|
|||||||
const val CONNECTION_ID_TILE = 1
|
const val CONNECTION_ID_TILE = 1
|
||||||
const val CONNECTION_ID_MAIN_ACTIVITY_FOREGROUND = 2
|
const val CONNECTION_ID_MAIN_ACTIVITY_FOREGROUND = 2
|
||||||
const val CONNECTION_ID_MAIN_ACTIVITY_BACKGROUND = 3
|
const val CONNECTION_ID_MAIN_ACTIVITY_BACKGROUND = 3
|
||||||
|
const val CONNECTION_ID_RESTART_BG = 4
|
||||||
|
|
||||||
|
var restartingApp = false
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
@ -124,7 +127,7 @@ class SagerConnection(
|
|||||||
} catch (e: RemoteException) {
|
} catch (e: RemoteException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
callback!!.onServiceConnected(service)
|
callback?.onServiceConnected(service)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceDisconnected(name: ComponentName?) {
|
override fun onServiceDisconnected(name: ComponentName?) {
|
||||||
@ -137,8 +140,10 @@ class SagerConnection(
|
|||||||
override fun binderDied() {
|
override fun binderDied() {
|
||||||
service = null
|
service = null
|
||||||
callbackRegistered = false
|
callbackRegistered = false
|
||||||
|
if (!restartingApp) {
|
||||||
callback?.also { runOnMainDispatcher { it.onBinderDied() } }
|
callback?.also { runOnMainDispatcher { it.onBinderDied() } }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun unregisterCallback() {
|
private fun unregisterCallback() {
|
||||||
val service = service
|
val service = service
|
||||||
@ -149,7 +154,7 @@ class SagerConnection(
|
|||||||
callbackRegistered = false
|
callbackRegistered = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun connect(context: Context, callback: Callback) {
|
fun connect(context: Context, callback: Callback?) {
|
||||||
if (connectionActive) return
|
if (connectionActive) return
|
||||||
connectionActive = true
|
connectionActive = true
|
||||||
check(this.callback == null)
|
check(this.callback == null)
|
||||||
|
|||||||
@ -20,6 +20,8 @@ import androidx.activity.result.ActivityResultLauncher
|
|||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorRes
|
import androidx.annotation.ColorRes
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.isGone
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
@ -30,10 +32,10 @@ import com.jakewharton.processphoenix.ProcessPhoenix
|
|||||||
import io.nekohasekai.sagernet.BuildConfig
|
import io.nekohasekai.sagernet.BuildConfig
|
||||||
import io.nekohasekai.sagernet.R
|
import io.nekohasekai.sagernet.R
|
||||||
import io.nekohasekai.sagernet.SagerNet
|
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.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.MainActivity
|
||||||
import io.nekohasekai.sagernet.ui.ThemedActivity
|
import io.nekohasekai.sagernet.ui.ThemedActivity
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -201,7 +203,7 @@ val shortAnimTime by lazy {
|
|||||||
fun View.crossFadeFrom(other: View) {
|
fun View.crossFadeFrom(other: View) {
|
||||||
clearAnimation()
|
clearAnimation()
|
||||||
other.clearAnimation()
|
other.clearAnimation()
|
||||||
if (visibility == View.VISIBLE && other.visibility == View.GONE) return
|
if (isVisible && other.isGone) return
|
||||||
alpha = 0F
|
alpha = 0F
|
||||||
visibility = View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
animate().alpha(1F).duration = shortAnimTime
|
animate().alpha(1F).duration = shortAnimTime
|
||||||
@ -256,11 +258,25 @@ fun triggerFullRestart(ctx: Context) {
|
|||||||
runOnDefaultDispatcher {
|
runOnDefaultDispatcher {
|
||||||
SagerNet.stopService()
|
SagerNet.stopService()
|
||||||
delay(500)
|
delay(500)
|
||||||
Executable.killAll(true)
|
SagerConnection.restartingApp = true
|
||||||
runOnMainDispatcher {
|
val connection = SagerConnection(SagerConnection.CONNECTION_ID_RESTART_BG)
|
||||||
|
connection.connect(ctx, RestartCallback {
|
||||||
ProcessPhoenix.triggerRebirth(ctx, Intent(ctx, MainActivity::class.java))
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.getColour(@ColorRes colorRes: Int): Int {
|
fun Context.getColour(@ColorRes colorRes: Int): Int {
|
||||||
|
|||||||
@ -80,7 +80,7 @@ class AboutFragment : ToolbarFragment(R.layout.layout_about) {
|
|||||||
MaterialAboutActionItem.Builder()
|
MaterialAboutActionItem.Builder()
|
||||||
.icon(R.drawable.ic_baseline_update_24)
|
.icon(R.drawable.ic_baseline_update_24)
|
||||||
.text(R.string.app_version)
|
.text(R.string.app_version)
|
||||||
.subText(SagerNet.appVersionNameForDisplay.value)
|
.subText(SagerNet.appVersionNameForDisplay)
|
||||||
.setOnClickAction {
|
.setOnClickAction {
|
||||||
requireContext().launchCustomTab(
|
requireContext().launchCustomTab(
|
||||||
"https://github.com/MatsuriDayo/NekoBoxForAndroid/releases"
|
"https://github.com/MatsuriDayo/NekoBoxForAndroid/releases"
|
||||||
@ -251,7 +251,7 @@ class AboutFragment : ToolbarFragment(R.layout.layout_about) {
|
|||||||
.setMessage(
|
.setMessage(
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.update_dialog_message,
|
R.string.update_dialog_message,
|
||||||
SagerNet.appVersionNameForDisplay.value,
|
SagerNet.appVersionNameForDisplay,
|
||||||
releaseName
|
releaseName
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
PACKAGE_NAME=moe.nb4a
|
PACKAGE_NAME=moe.nb4a
|
||||||
VERSION_NAME=1.3.9
|
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
|
VERSION_CODE=43
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user