以下通过Kotlin来写,就当顺手学Kotlin了。
安卓通过intent来启动activity,例如:
findViewById<Button>(R.id.btn_last).setOnClickListener({
val intent = Intent(MainActivity@this, SecondActivity::class.java)
intent.putExtra("key", "last")
startActivity(intent)
})
SecondActivity获取intent有两种做法:
1,通过getIntent()来获取
2,通过onNewIntent()来获取
首先是getIntent(),在Kotlin中可以直接写成属性intent,例如:
override fun onResume() {
super.onResume()
var extra = intent.getStringExtra("key")
if (extra == null) {
extra = "empty"
}
Log.e("SecondActivity", "onResume $extra")
}
这个做法有个坑,见:
假使AActivity已经启动(对应的启动Intent为intent1),此时调用startActivity(intent2)再次启动AActivity,在onResume()中调用getIntent()获取到的Intent仍然是intent1,除非重写onNewIntent()方法。
即:如果碰到会调用onNewIntent()的情况,getIntent()还是上一次的情况,如果希望保证intent跟随当前次,需要重写onNewIntent()方法。
其次是onNewIntent(),onNewIntent并不是页面进入每次都调用的,如果希望每次都调用,应该使用onResume()。
如果是A中再次启动A
在launchMode是standard时则依次调用了:
A1 onPause
A2 onCreate
A2 onStart
A2 onResume
A1 onStop
在launchMode非standard时则依次调用了:
A onPause
A onNewIntent
A onResume
如果是A启动B再启动A
在launchMode standard/singleTop时调用跟A再次启动A类似:
B onPause
A2 onCreate
A2 onStart
A2 onResume
B onStop
在launchMode singleTask/singleInstance时依次调用了:
B onPause
A onNewIntent
A onStart
A onResume
B onStop
如果是A启动B再返回A
B onPause
A onStart
A onResume
B onStop
onNewIntent写法
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
var extra = intent?.getStringExtra("key")
if (extra == null) {
extra = "empty"
}
Log.e("MainActivity", "onNewIntent $extra")
setIntent(intent) //上面说的问题
}
结论
1,launchMode设置为standard,由于每次创建一个新的对象,所以不存在onNewIntent调用,需要通过getIntent()来获取。
2,launchMode设置为singleTop,如果是栈顶跳转,会调用onNewIntent,反之同standard。
3,launchMode设置为singleTask和singleInstance,如果通过startActivity再次进入,会调用onNewIntent,如果通过返回则不调用。
4,如果希望保证getIntent()是可靠的,需要重载onNewIntent并调用setIntent()。
网友评论