免责声明:我是一位经验丰富的程序员,但几乎是Android的新手。我可能会问明显的问题。
我的临时应用程序有一个非常简单的GUI。
具体来说,我有一个最高的Switch
来打开/关闭我的应用程序。
启动时开关处于关闭状态。
当它打开时,我可以从菜单中选择一个子MonitorActivity
以显示正在发生的事情(某种正在运行的日志)。
MonitorActivity
已正确链接到父级,所以我可以返回到MainActivity
。
到目前为止,太好了。一切正常。
问题是我向后导航MainActivity
时完全重置了,就像重新开始一样;特别是我的开/关Switch
回到了off
的位置。
我对relevant documentation的理解是MainActivity
应该已经停止;相关代码段是:
上一个活动保留在堆栈中,但已停止。当一个 活动停止,系统保留其用户的当前状态 接口。当用户按下“后退”按钮时,当前活动 从堆栈顶部弹出(该活动被销毁),并且 恢复先前的活动(其UI的先前状态为 恢复)。
据此我了解,我不应该为恢复MainActivity
状态做任何特定的事情;这是正确的吗?
我应该发布我的AndroidMainfest.xml
(或其他文件)吗?
更新(根据要求):
我严格遵循MyFirstApp中的模式:
MonitorActivity
从MainActivity
开始startActivity(intent)
。<activity android:name=".DisplayMessageActivity" android:parentActivityName=".MainActivity">
中的AndroidManifest.xml
) 注意:这正是MyFirstApp
的行为:从DisplayMessageActivity
返回时,EditText
小部件的内容消失了(即使没有明确清除)它)。
也许我应该重命名问题:“如何在“ MyFirstApp”中的“发送”之后保留“消息”?”
UPDATE2 :我重写了几个回调以跟踪实际发生的情况; 这是日志(注释内联,查找“ <<<<<<”):
02/27 16:05:24: Launching app
$ adb install-multiple -r -t -p it.condarelli.myfirstapp /home/mcon/AndroidStudioProjects/MyfirstApp/app/build/intermediates/split-apk/debug/slices/slice_2.apk
Split APKs installed in 483 ms
$ adb shell am start -n "it.condarelli.myfirstapp/it.condarelli.myfirstapp.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Waiting for application to come online: it.condarelli.myfirstapp | it.condarelli.myfirstapp.test
Waiting for application to come online: it.condarelli.myfirstapp | it.condarelli.myfirstapp.test
Connecting to it.condarelli.myfirstapp
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/elli.myfirstap: Not late-enabling -Xcheck:jni (already on)
W/elli.myfirstap: Unexpected CPU variant for X86 using defaults: x86
W/ActivityThread: Application it.condarelli.myfirstapp is waiting for the debugger on port 8100...
I/System.out: Sending WAIT chunk
I/System.out: Debugger has connected
waiting for debugger to settle...
Connected to the target VM, address: 'localhost:8603', transport: 'socket'
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/chatty: uid=10085(it.condarelli.myfirstapp) identical 2 lines
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1354)
W/elli.myfirstap: JIT profile information will not be recorded: profile file does not exits.
I/chatty: uid=10085(it.condarelli.myfirstapp) identical 10 lines
W/elli.myfirstap: JIT profile information will not be recorded: profile file does not exits.
I/InstantRun: starting instant run server: is main process
I/MainActivity: onCreate(null) <<<<< This is App start
W/elli.myfirstap: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
I/MainActivity: onStart()
I/MainActivity: onResume()
I/MainActivity: onPostResume()
D/OpenGLRenderer: HWUI GL Pipeline
D/: HostConnection::get() New Host Connection established 0xcb81c0c0, tid 17161
I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
D/OpenGLRenderer: Swap behavior 0
D/EGL_emulation: eglCreateContext: 0xde3584a0: maj 2 min 0 rcv 2
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
I/AssistStructure: Flattened final assist data: 2344 bytes, containing 1 windows, 8 views
I/MainActivity: onPause() <<<<< This is first message after I pressed 'Send' button.
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@18e99e1
I/DisplayMessageActivity: onStart()
I/DisplayMessageActivity: onResume()
I/DisplayMessageActivity: onPostResume()
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
I/MainActivity: onStop()
I/MainActivity: onSaveInstanceState() <<<<< This is where log stops while DisplayMessageActivity is focused
I/DisplayMessageActivity: onPause() <<<<< This is first message after Back-navigation
I/MainActivity: onDestroy() <<<<< WHY THIS NOW??
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@bd33145
I/MainActivity: onCreate(null) <<<<< MainActivity is recreated from scratch
I/MainActivity: onStart()
I/MainActivity: onResume()
I/MainActivity: onPostResume()
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
I/DisplayMessageActivity: onStop()
I/DisplayMessageActivity: onDestroy()
我在做什么错了?
答案 0 :(得分:1)
您的问题与您使用“向上导航”(即菜单栏中的箭头)有关,而不是与使用“返回”按钮有关。我认为,如果您按BACK按钮返回到MainActivity
,一切都会按照您的意愿进行。
您应该通过删除以下内容来禁用“向上导航”:
android:parentActivityName=".MainActivity"
来自清单中的<activity>
声明。
当您详细了解如何自定义“向上导航”的行为时,可以确保当您使用它返回时,不会创建前一个Activity
的新实例,而是现有实例被重用。
答案 1 :(得分:0)
我认为您可以存储MainActivity的状态并使用startActivityForResult()启动子级。
这是kotlin中的一个示例(我省略了代码中无关的部分):
class ProductDataActivity : BaseActivity(),ProductDataFragment.ProductDataListener {
private var productData: ProductBinding? = null
companion object {
private const val INSTANCE_STATE_PRODUCT_DATA = "state_product_data"
private const val RESULT_DATA = 1
}
override fun onSaveInstanceState(outState: Bundle?) {
outState?.putSerializable(INSTANCE_STATE_PRODUCT_DATA, this.productData)
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
this.productData = savedInstanceState?.getSerializable(INSTANCE_STATE_PRODUCT_DATA) as ProductBinding
super.onRestoreInstanceState(savedInstanceState)
}
override fun onDataClicked() {
val intent = TabProductDetailsActivity.getCallingIntent(this, productData!!, false)
this.startActivityForResult(intent, RESULT_DATA)
}
其他活动:
class TabProductDetailsActivity : BaseActivity() {
private var productData: ProductBinding? = null //The activity is started with an intent as you can see above in the ProducDataActivity.
companion object {
const val INTENT_EXTRA_PRODUCT_DATA = "intent_product_data"
}
override fun onBackPressed() {
val resultIntent = Intent()
resultIntent.putExtra(INTENT_EXTRA_PRODUCT_DATA, productData)
setResult(Activity.RESULT_OK, resultIntent)
finish()
}
我希望您能理解我在这里所做的事情,基本上我是将一个对象从一项活动传递到另一项活动,并且当我按下“后退”按钮时,启动该活动没有问题。不确定是否正是您想要的,但是我认为它可以为您提供多种方法中的一种。
答案 2 :(得分:0)
事实证明,“罪魁祸首”是{em}似乎(经过大量调试)在android.support.v7.app.AppCompatActivity
末尾无条件调用requestDestroy()
的{{1}}的用法在由dispatchMessage()
启动的链的末尾调用。
startActivity(intent)
的默认实现忠实地将小部件状态保存在onSaveInstanceState()
中,但这不传递给了Bundle
。
制造MainActivity.onCreate(null)
(而不是public class MainActivity extends Activity { ...
)可以解决问题(它也给public class MainActivity extends AppCompatActivity
和其他组件造成破坏,但这是另一回事了。)