рдЯреАрдПрд▓; рдбреАрдЖрд░: рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЬрд╛рдЧрд░реВрдХ рд╡рд╛рд╕реНрддреБрд╢рд┐рд▓реНрдк рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдХрд┐, рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореГрддреНрдпреБ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрд╡реЗрджрди рдХреЗрд╡рд▓ рд░рд╛рдЬреНрдп рдХреЛ рдмрд╣рд╛рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд┐рдП рдмрд┐рдирд╛ рдЦрд░реЛрдВрдЪ рд╕реЗ рдкреБрдирд░рд╛рд░рдВрдн рд╣реЛрддрд╛ рд╣реИред рдФрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ Serializable
, Parcelable
рдФрд░ рджреВрд╕рд░реЛрдВ рдХреА Bundle
рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИред
рдпрджрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рдмреАрдЪ рд╣реИ onStart()
рдФрд░ onStop()
, рддреЛ рдпрд╣ рдЧрд╛рд░рдВрдЯреА рд╣реИ рдХрд┐ рдЧрддрд┐рд╡рд┐рдзрд┐, рдФрд░ рдЗрд╕рд▓рд┐рдП рд╡рд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬрд┐рд╕рдореЗрдВ рдЧрддрд┐рд╡рд┐рдзрд┐ рд░рд╣рддреА рд╣реИ, рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИрдВред рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХрд┐рд╕реА рднреА рд╕рдордп рдЖрд╡реЗрджрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдорд╛рд░ рд╕рдХрддрд╛ рд╣реИред
рдореБрдЭреЗ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдореМрдд рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рд░рджрд░реНрд╢реА (рдпрд╛рдиреА, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрджреГрд╢реНрдп рд╣реЛрдирд╛) рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рдирд╛ рдерд╛ред рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ, рдПрдХ рдХрд╛рдордХрд╛рдЬреА рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: https://github.com/mychka/resurrection ред
рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ onSaveInstanceState()
рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЧрддрд┐рд╡рд┐рдзрд┐ рдореЗрдВ рдЖрд╡реЗрджрди рдХреА рдкреВрд░реА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдП, рдФрд░ onCreate()
, рдпрджрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдорд╛рд░ рджрд┐рдпрд╛ рдЧрдпрд╛, рддреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:
abstract class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ResurrectionApp.ensureState(savedInstanceState)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
ResurrectionApp.STATE.save(outState)
}
}
рдХрд┐рд╕реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рд╣рддреНрдпрд╛ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
adb shell am kill org.resurrection
рдпрджрд┐ рд╣рдо рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдореГрддреНрдпреБ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдУрд╡рд░рд╣реЗрдб рдХреЛ рдиреЛрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХреЛрдб рдЬрдЯрд┐рд▓рддрд╛ред
- , , , . , , - . - : , , .
Serializable
/Parcelable
.- тАФ , . ,
loading == true
. , , loading
false
. TCP-, . - ,
Activity#onCreate()
тАФ , тАФ .
, , , . , , , - .
Activity#onSaveInstanceState()
. (, Activity#isChangingConfigurations == true
, , .) , , - .
. 1, . / .
. , , , , , - .
, , : , . , , , .
, . , , foreground . , .
( ) , , .
. (02.03.2020) : Facebook, Twitter, WhatsApp, Chrome, Gmail, Yandex.Maps. : Yandex.Navigator, YouTube, -, Skype.
, , . , , . : , .
https://github.com/mychka/life-from-scratch
BaseActivity
. LoginActivity
. "NEXT". DashboardActivity
. .
adb shell am kill org.lifefromscratch
. , DashboardActivity
LoginActivity#loginShownAt
, .
. , . , :
abstract class BaseActivity : AppCompatActivity() {
companion object {
init {
if (!appStartedNormally) {
APP.startActivity(
APP.getPackageManager().getLaunchIntentForPackage(
APP.getPackageName()
)
);
System.exit(0)
}
}
}
}
. , -.
. , .
class BinderReference<T>(val value: T?) : Binder()
Parcel
. ,
class MyNonSerializableData(val os: OutputStream)
val parcel: Parcel = Parcel.obtain()
val obj = MyNonSerializableData(ByteArrayOutputStream())
parcel.writeStrongBinder(BinderReference(obj))
parcel.setDataPosition(0)
val obj2 = (parcel.readStrongBinder() as BinderReference<*>).value
assert(obj === obj2)
android.os.Binder
https://habr.com/ru/post/274635/
. . , . :
const val DEFAULT_BUNDLE_KEY = "com.example.DEFAULT_BUNDLE_KEY.cr5?Yq+&Jr@rnH5j"
val Any?.bundle: Bundle?
get() = if (this == null) null else Bundle().also { it.putBinder(DEFAULT_BUNDLE_KEY, BinderReference(this)) }
inline fun <reified T> Bundle?.value(): T =
this?.getBinder(DEFAULT_BUNDLE_KEY)?.let {
if (it is BinderReference<*>) it.value as T else null
} as T
inline fun <reified Arg> Fragment.defaultArg() = lazy<Arg>(LazyThreadSafetyMode.NONE) {
arguments.value()
}
. :
findNavController(R.id.nav_host_fragment).navigate(
R.id.bbbFragment,
MyNonSerializableData(ByteArrayOutputStream()).bundle
)
val data: MyNonSerializableData by defaultArg()
тАФ androidx.lifecycle.ViewModel
. , , destroy , configuration change, https://developer.android.com/reference/androidx/activity/ComponentActivity.html#onRetainCustomNonConfigurationInstance()
, , , . ViewModel
.
BinderReference
, androidx.lifecycle.ViewModel
, onSaveInstanceState(outState)
/onCreate(savedInstanceState)
. view model .
UPD: kamer Dimezis , , 2.3 (API 9). . (, finish()
), configuration change. :
https://stackoverflow.com/questions/7536988/android-app-out-of-memory-issues-tried-everything-and-still-at-a-loss/7576275#7576275
https://stackoverflow.com/questions/11616575/android-not-killing-activities-from-stack-when-memory-is-low/11616829#11616829
:
https://issuetracker.google.com/issues/36934944
рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рдЧреЛрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ "рдЧрддрд┐рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рди рд░рдЦреЗрдВ" рд╡рд┐рдХрд▓реНрдк рд╣реИ, рддреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдПрдХ рдХреЛрдб рд╣реИ рдЬреЛ рдЧрддрд┐рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ "рдзреАрд░реЗ" рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рдЙрдЪреНрдЪ рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде, рдЖрдк рдПрдХ рдореБрд╢реНрдХрд┐рд▓ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд╕рд╛рде рдЖ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рдпрд╣ рдХреЛрдб рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░, рддрджрдиреБрд╕рд╛рд░, androidx.lifecycle.ViewModel
рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдПрдХ рджреБрд░реНрдШрдЯрдирд╛ рдХрд╛ рдХрд╛рд░рдг рд╣реЛрдЧрд╛ onSaveInstanceState()
ред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ, рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░, androidx.lifecycle.ViewModel
рдЖрдк рдЕрднреА рднреА рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред