zoukankan      html  css  js  c++  java
  • Android笔记-Activity相关+内存泄漏+Fragment+service

    看了下,上次学习android还是17年的事情,,,,两年过去了我现在终于来搞android了。。。

     

     

    官网有一段基础描述:

    https://developer.android.google.cn/guide/components/fundamentals

    Android 应用采用 Java 编程语言编写。Android SDK 工具将您的代码 — 连同任何数据和资源文件 — 编译到一个 APK:Android 软件包,即带有 .apk 后缀的存档文件中。一个 APK 文件包含 Android 应用的所有内容,它是基于 Android 系统的设备用来安装应用的文件。

    安装到设备后,每个 Android 应用都运行在自己的安全沙箱内:

    • Android 操作系统是一种多用户 Linux 系统,其中的每个应用都是一个不同的用户;
    • 默认情况下,系统会为每个应用分配一个唯一的 Linux 用户 ID(该 ID 仅由系统使用,应用并不知晓)。系统为应用中的所有文件设置权限,使得只有分配给该应用的用户 ID 才能访问这些文件;
    • 每个进程都具有自己的虚拟机 (VM),因此应用代码是在与其他应用隔离的环境中运行;
    • 默认情况下,每个应用都在其自己的 Linux 进程内运行。Android 会在需要执行任何应用组件时启动该进程,然后在不再需要该进程或系统必须为其他应用恢复内存时关闭该进程。

    Android 系统可以通过这种方式实现最小权限原则。也就是说,默认情况下,每个应用都只能访问执行其工作所需的组件,而不能访问其他组件。 这样便营造出一个非常安全的环境,在这个环境中,应用无法访问系统中其未获得权限的部分。

    不过,应用仍然可以通过一些途径与其他应用共享数据以及访问系统服务:

    • 可以安排两个应用共享同一 Linux 用户 ID,在这种情况下,它们能够相互访问彼此的文件。 为了节省系统资源,可以安排具有相同用户 ID 的应用在同一 Linux 进程中运行,并共享同一 VM(应用还必须使用相同的证书签署)。
    • 应用可以请求访问设备数据(如用户的联系人、短信、可装载存储装置 [SD 卡]、相机、蓝牙等)的权限。 用户必须明确授予这些权限。 如需了解详细信息,请参阅 使用系统权限

    https://developer.android.google.cn/guide/topics/resources/runtime-changes

    有些设备配置可能会在运行时发生变化(例如屏幕方向、键盘可用性及语言)。 发生这种变化时,Android 会重启正在运行的 Activity(先后调用 onDestroy() 和 onCreate())。重启应用并恢复大量数据不仅成本高昂,而且给用户留下糟糕的使用体验。

    如果重启 Activity 需要恢复大量数据、重新建立网络连接或执行其他密集操作,那么因配置变更而引起的完全重启可能会给用户留下应用运行缓慢的体验。 此外,依靠系统通过onSaveInstanceState() 回调为您保存的 Bundle,可能无法完全恢复 Activity 状态,因为它并非设计用于携带大型对象(例如位图),而且其中的数据必须先序列化,再进行反序列化,这可能会消耗大量内存并使得配置变更速度缓慢。 在这种情况下,如果 Activity 因配置变更而重启,则可通过保留 Fragment 来减轻重新初始化 Activity 的负担。此片段可能包含对您要保留的有状态对象的引用。

    当 Android 系统因配置变更而关闭 Activity 时,不会销毁您已标记为要保留的 Activity 的片段。 您可以将此类片段添加到 Activity 以保留有状态的对象。

    要在运行时配置变更期间将有状态的对象保留在片段中,请执行以下操作:

    1. 扩展 Fragment 类并声明对有状态对象的引用。
    2. 在创建片段后调用 setRetainInstance(boolean)
    3. 将片段添加到 Activity。
    4. 重启 Activity 后,使用 FragmentManager 检索片段。
    注意:尽管您可以存储任何对象,但是切勿传递与 Activity 绑定的对象,
    例如,Drawable、Adapter、View 或其他任何与 Context 关联的对象。
    否则,它将泄漏原始 Activity 实例的所有视图和资源。
    泄漏资源意味着应用将继续持有这些资源,但是无法对其进行垃圾回收,因此可能会丢失大量内存。

      

    以下内容参考自:《Android从学习到产品》,《深入理解java虚拟机》,《操作系统之哲学原理》

    先甩一部分定义:

    1.每一个Activity都可以启动另一个Activity来完成不同的动作,每一次一个Activity启动,前一个Activity就停止了,但是系统保留一个Activity在一个栈上(Back stack)。当一个新的Activity启动时,它会被推送到栈顶,取得用户焦点。Back Stack 符合简单的“后进先出”原则,所以当用户完成当前Activity后单击Back按钮,它会被弹出栈(并且被摧毁),然后之前的Activity恢复。

    这里延申一下(猜测,没有看过具体的Android底层,不确定是不是准确的),这个Activity存储的back stack 应该是jvm中的VM Stack。

    同步一下VM Stack是什么,就要讨论jvm的运行,java虚拟机在执行java程序的过程中,会把它所管理的内存划分为若干个不同的数据区域,VM Stack是其中一个区域。

    VM Stack (java virtual machine stacks)是线程私有的,他的生命周期与线程相同。(线程概念补充一下:运行中的程序叫进程,一个进程占有一段内存来执行这个程序,一个进程我们可以拆分为多个线程,多个线程使用同一段内存空间来协同工作完成进程。线程是进程里面的一个执行上下文,或者执行序列。对于单核来说,一个时间段只能handle一个线程,多核可以有多个线程同时执行,从而提高进程的执行速度)

    VM stack 描述的是java方法执行的内存模型:每个方法执行的同时都会创建一个栈帧(stack Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

    那么对于Android来说,内存泄漏的场景有:1.Activity过多,内存占满,无法创建新的Activity对象;2.多个Activity单例化后,一直占据内存资源,无法释放;

    具体怎么做的还没有头绪,等开发完了再研究吧。

  • 相关阅读:
    #include <boost/scoped_ptr.hpp>
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    8.4散列表查找
    #include <boost/array.hpp>
    异常
    lambda
    #include <amp.h>
    #include <bitset>
    #include <hash_set>
  • 原文地址:https://www.cnblogs.com/zhizhiyin/p/11199246.html
Copyright © 2011-2022 走看看