首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Coding
V2EX  ›  Android

问一个安卓开发相关的问题

  •  
  •   Vegetable · 32 天前 · 2198 次点击
    这是一个创建于 32 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我不是安卓开发,但是有些好奇这个机制↓:

    在抖音里边,我从某一个账号开始,查看他的粉丝,选中一个粉丝继续查看这个选中粉丝的粉丝.

    这样我可以一直打开新的页面,点击返回的话,会回到上一个页面,那这些历史记录是怎么处理的呢?

    如此往复下去可以打开足够多的个人详情页面导致 app 崩溃吗? 还是说那些页面会被回收掉,只保存了一个路径而已?

    29 回复  |  直到 2019-11-13 14:24:49 +08:00
        1
    Vegetable   32 天前
    嗯..验证了一下好像是会,几十个之后好像是会黑屏,复现不是很稳定.
        2
    llcfays   32 天前
    Android 是栈视图,另外也可以设置[启动模式]( https://blog.csdn.net/mynameishuangshuai/article/details/51491074)的。
        3
    751762476   32 天前
        4
    Edward4074   32 天前
    页面会被回收,但页面中 View 的状态会被保留,页面对应的数据需要开发人员在对应的回调里处理才能保留
        5
    Mrxxy   32 天前
    Android 中每个 Activity 即界面,会被放在一个栈中
    https://developer.android.com/guide/components/tasks-and-back-stack.html?hl=zh-CN
        6
    tongyang   32 天前
    一般安卓的 app 不会做处理的,你这属于极端现象
        7
    Vegetable   32 天前
    @llcfays
    @751762476
    @Edward4074
    @Mrxxy
    感谢各位,看明白啦
        8
    fhvch   32 天前   ♥ 1
    一般来说 Android 中你看到每一个页面都是一个 activity 组件(也有可能是 fragment/view )
    如果是 activity 的话,Android 中 activity 是通过 栈(先进后出) 这种数据结构去存储的
    一般情况下,也就你看到的那种情况就是每次你点击一次粉丝 都会去生成一个新的 activity 然后存到 栈顶,也就是我们能够看到的~( 2 楼有说还有其它的启动 activity 的模式)
    如果真的是我说的这样子的话,每次都去启动一个新的 activity 不去做一些处理的话确实是会有问题的,启动几十个甚至上百的时候,很有可能会内存溢出导致 crash...
        9
    raiz   32 天前   ♥ 1
    社交软件都会遇到这个问题, 表现由交互和稳定性妥协,开发者通过设置 Activity 的启动模式,可以决定上一个 activity 留不留在返回栈里,如果留,那么会出现你说的问题(测试会报内存泄漏),不留的话,用户可能会丢失路径。
        10
    wvitas   32 天前
    启动模式了解下
        11
    Goolge   32 天前
    监听 activity 生命周期 超过 N 个 finish 之前的 为了防止占用大量内存。具体你怎么处理看情况。
        12
    charlieputon   32 天前 via Android
    这种情况应该使用 single top 启动模式来启动 activity
        13
    ukyoo   32 天前
    这和启动模式有啥关系啊...很常见的情况就是商品详情页通过相似商品无限开下去, 最后肯定会 OOM 的
        14
    BigDogWang   32 天前
    @fhvch 没有内存泄漏的话是不会崩溃的。后台活动在内存不足的情况下是会回收掉的
        15
    BigDogWang   32 天前
    为啥这帖子里这么多人在误导。如果你没有内存泄漏的话,后台 Activity 过多是不会导致 OOM 的
        16
    DeweyReed   32 天前
    请问有什么办法可以最效率地保存这个历史路径吗?
        17
    jjhappyforever   32 天前
    首先打开足够多的页面是会被回收的,页面回收机制是由系统控制的,APP 本身只不过是一直 new Activity,单个 Activity 占有内存很少的,所以不停的 new 也无所谓,但假如你真的开启页面过度,导致栈底端一些页面被回收了,也只是将回收数据持久化到本地,待你返回在通过 Bundle 恢复数据而已.所以开启页面过多导致 crash 概率几乎为 0.系统分配给 APP 内存有临界值,内存溢出是内存使用不当造成的,如图片,大文件等,但开启页面的 Activity 机制,安卓系统是绝对不会让之内存不足而 crash 的.
        18
    janus77   32 天前 via iPhone
    会爆栈
    如果需要处理的话,就跟代码的单例一样,永远只有一个页面。
        19
    fhvch   32 天前
    @BigDogWang activity 对象是绝对的强引用!这种级别的引用就算是 app 再怎么内存不足也不会去回收的!
        20
    ukyoo   32 天前
        21
    vigidroid   32 天前 via iPhone
    @BigDogWang 没记错的话,android 中的内存回收是以进程为单位的。一般情况下,activity 栈中的所有 activity 都处于同一进程中,所以会内存会一直累积直到 oom
        22
    ukyoo   32 天前   ♥ 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 所在的进程。
        23
    yukiww233   32 天前
    @ukyoo #22 感谢。差点信了楼上说的,虽然自己做的应用都预防了循环路由
        24
    BigDogWang   31 天前
    @vigidroid 你到底是不是安卓开发😂
        25
    BigDogWang   31 天前
    @fhvch Activity 的 onSaveInstanceState 就是为了这种场景设计的。不过楼上有人做实验,崩了
        26
    BigDogWang   31 天前
    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   31 天前
    @BigDogWang 淦,收回我的话,这个还真是杀进程的。看来对安卓的基础部分还存在误解
        28
    qiibeta   31 天前
    Activity 会直接内存一直增加直到 OOM,https://github.com/bytedance/scene 现在也是这样……想做 [超过多少个页面就把之前老页面销毁,等返回老页面的时候再恢复,来节省内存] 这样的功能,还没做
        29
    imn1   31 天前
    昨天帮老妈更新一下手机 app,打开 chrome,竟然看到 98 个 tab……98 个……呆了几秒
    比我桌面系统还狠
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2326 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 26ms · UTC 12:58 · PVG 20:58 · LAX 04:58 · JFK 07:58
    ♥ Do have faith in what you're doing.