我不是安卓开发,但是有些好奇这个机制↓:
在抖音里边,我从某一个账号开始,查看他的粉丝,选中一个粉丝继续查看这个选中粉丝的粉丝.
这样我可以一直打开新的页面,点击返回的话,会回到上一个页面,那这些历史记录是怎么处理的呢?
如此往复下去可以打开足够多的个人详情页面导致 app 崩溃吗? 还是说那些页面会被回收掉,只保存了一个路径而已?
1
Vegetable OP 嗯..验证了一下好像是会,几十个之后好像是会黑屏,复现不是很稳定.
|
2
llcfays 2019-11-12 10:20:02 +08:00
Android 是栈视图,另外也可以设置[启动模式]( https://blog.csdn.net/mynameishuangshuai/article/details/51491074)的。
|
3
751762476 2019-11-12 10:20:05 +08:00
我不玩抖音。不过之前在 v2 上看见过抖音开发者开源的单 Activity 库 https://www.v2ex.com/t/611711。基于这个库的机制不在前台显示的粉丝界面是可以回收的。相当于只是保存的一个回退栈(路径)
|
4
Edward4074 2019-11-12 10:20:59 +08:00
页面会被回收,但页面中 View 的状态会被保留,页面对应的数据需要开发人员在对应的回调里处理才能保留
|
5
Mrxxy 2019-11-12 10:21:32 +08:00
Android 中每个 Activity 即界面,会被放在一个栈中
https://developer.android.com/guide/components/tasks-and-back-stack.html?hl=zh-CN |
6
tongyang 2019-11-12 10:31:37 +08:00
一般安卓的 app 不会做处理的,你这属于极端现象
|
7
Vegetable OP |
8
fhvch 2019-11-12 10:38:13 +08:00 1
一般来说 Android 中你看到每一个页面都是一个 activity 组件(也有可能是 fragment/view )
如果是 activity 的话,Android 中 activity 是通过 栈(先进后出) 这种数据结构去存储的 一般情况下,也就你看到的那种情况就是每次你点击一次粉丝 都会去生成一个新的 activity 然后存到 栈顶,也就是我们能够看到的~( 2 楼有说还有其它的启动 activity 的模式) 如果真的是我说的这样子的话,每次都去启动一个新的 activity 不去做一些处理的话确实是会有问题的,启动几十个甚至上百的时候,很有可能会内存溢出导致 crash... |
9
raiz 2019-11-12 11:18:17 +08:00 1
社交软件都会遇到这个问题, 表现由交互和稳定性妥协,开发者通过设置 Activity 的启动模式,可以决定上一个 activity 留不留在返回栈里,如果留,那么会出现你说的问题(测试会报内存泄漏),不留的话,用户可能会丢失路径。
|
10
wvitas 2019-11-12 11:29:05 +08:00
启动模式了解下
|
11
Goolge 2019-11-12 16:17:23 +08:00
监听 activity 生命周期 超过 N 个 finish 之前的 为了防止占用大量内存。具体你怎么处理看情况。
|
12
charlieputon 2019-11-12 16:49:24 +08:00 via Android
这种情况应该使用 single top 启动模式来启动 activity
|
13
ukyoo 2019-11-12 17:18:21 +08:00
这和启动模式有啥关系啊...很常见的情况就是商品详情页通过相似商品无限开下去, 最后肯定会 OOM 的
|
14
BigDogWang 2019-11-12 17:22:12 +08:00
@fhvch 没有内存泄漏的话是不会崩溃的。后台活动在内存不足的情况下是会回收掉的
|
15
BigDogWang 2019-11-12 17:24:03 +08:00
为啥这帖子里这么多人在误导。如果你没有内存泄漏的话,后台 Activity 过多是不会导致 OOM 的
|
16
DeweyReed 2019-11-12 18:05:39 +08:00
请问有什么办法可以最效率地保存这个历史路径吗?
|
17
jjhappyforever 2019-11-12 18:43:54 +08:00
首先打开足够多的页面是会被回收的,页面回收机制是由系统控制的,APP 本身只不过是一直 new Activity,单个 Activity 占有内存很少的,所以不停的 new 也无所谓,但假如你真的开启页面过度,导致栈底端一些页面被回收了,也只是将回收数据持久化到本地,待你返回在通过 Bundle 恢复数据而已.所以开启页面过多导致 crash 概率几乎为 0.系统分配给 APP 内存有临界值,内存溢出是内存使用不当造成的,如图片,大文件等,但开启页面的 Activity 机制,安卓系统是绝对不会让之内存不足而 crash 的.
|
18
janus77 2019-11-12 19:18:56 +08:00 via iPhone
会爆栈
如果需要处理的话,就跟代码的单例一样,永远只有一个页面。 |
19
fhvch 2019-11-12 19:51:06 +08:00
@BigDogWang activity 对象是绝对的强引用!这种级别的引用就算是 app 再怎么内存不足也不会去回收的!
|
20
ukyoo 2019-11-12 19:56:53 +08:00
|
21
vigidroid 2019-11-12 20:13:10 +08:00 via iPhone
@BigDogWang 没记错的话,android 中的内存回收是以进程为单位的。一般情况下,activity 栈中的所有 activity 都处于同一进程中,所以会内存会一直累积直到 oom
|
22
ukyoo 2019-11-12 20:20:41 +08:00 1
自己新建个 Activity, 在 onCreate 里分配个大内存的数组, 无限重复开页面.
class DetailActivity1111 : AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.acti111) val ints = IntArray(120000000) findViewById<Button>(R.id.btn).setOnClickListener { startActivity(Intent(this, DetailActivity1111::class.java)) } } } 最后崩溃的日志如下: JNI DETECTED ERROR IN APPLICATION: JNI IsInstanceOf called with pending exception java.lang.OutOfMemoryError: Failed to allocate a 480000016 byte allocation with 25165824 free bytes and 457MB until OOM, max allowed footprint 82083784, growth limit 536870912 代码就两三行,不存在内存泄露. 所以回收栈底 Activity 来回收内存的说法不成立. 再看官方文档: https://developer.android.com/guide/components/activities/activity-lifecycle#asem 写的很明白: 系统永远不会直接终止 Activity 以释放内存,而是会终止 Activity 所在的进程。 |
24
BigDogWang 2019-11-13 09:40:31 +08:00
@vigidroid 你到底是不是安卓开发😂
|
25
BigDogWang 2019-11-13 09:44:44 +08:00
@fhvch Activity 的 onSaveInstanceState 就是为了这种场景设计的。不过楼上有人做实验,崩了
|
26
BigDogWang 2019-11-13 09:49:47 +08:00
A background activity (an activity that is not visible to the user and has been stopped) is no longer critical, so the system may safely kill its process to reclaim memory for other foreground or visible processes. If its process needs to be killed, when the user navigates back to the activity (making it visible on the screen again), its onCreate(Bundle) method will be called with the savedInstanceState it had previously supplied in onSaveInstanceState(Bundle) so that it can restart itself in the same state as the user last left it.
https://developer.android.com/reference/android/app/Activity#ProcessLifecycle 官方文档 |
27
BigDogWang 2019-11-13 09:52:27 +08:00
@BigDogWang 淦,收回我的话,这个还真是杀进程的。看来对安卓的基础部分还存在误解
|
28
qiibeta 2019-11-13 11:37:17 +08:00
Activity 会直接内存一直增加直到 OOM,https://github.com/bytedance/scene 现在也是这样……想做 [超过多少个页面就把之前老页面销毁,等返回老页面的时候再恢复,来节省内存] 这样的功能,还没做
|
29
imn1 2019-11-13 14:24:49 +08:00
昨天帮老妈更新一下手机 app,打开 chrome,竟然看到 98 个 tab……98 个……呆了几秒
比我桌面系统还狠 |