Activity详解

357 阅读4分钟

1 Activity定义

Activity提供Android APP与用户交互的接口,是一个响应各种手势操作,并展示后台数据等信息给用户的界面。

2 Activity生命周期

2.1 Activity4种状态

  1. running Activity处于活动状态,能响应用户手势操作事件,处于Activity栈顶。
  2. paused Activity可见,但失去焦点。被透明Activity覆盖,此时Activity只是失去了和用户交互的能力,其信息和成员变量都存在,内存紧张时,该Activity会被回收。
  3. stopped 该Activity被另一个Activity完全覆盖,其信息和成员变量都存在,内存紧张时,该Activity会被回收。
  4. killed Activity被系统回收掉。

2.2 Activity生命周期分析

  1. Activity启动 onCreate():生命周期第一个方法,加载布局,设置view资源。 onStart():用户可见,但还未处于前台,不能响应用户手势操作事件,可初始化资源、加载图片等。 onResume():Activity处于前台,可正常与用户交互,可初始化资源、加载图片等。
  2. Activity退到后台运行 onPause():Activity可见,但不能被触摸,与onResume()对应。 onStop():onPause()方法后,会调用onStop()方法,此时Activity处于停止状态,被完全覆盖,不可见,后台运行。
  3. Activity再次回到前台 onRestart():Activity重新启动,由不可见状态变为可见状态。 onStart() onResume()
  4. 退出Activity onPause() onStop() onDestroy():Activity生命周期最后一个方法,此方法中应做一些回收工作,及资源的释放。

2.3 Android进程优先级

优先级依次降低

  1. 前台进程 与用户交互的Activity,以及与前台Activity绑定的Service。
  2. 可见进程 可见,但不能与用户交互的进程(onPause()后的Activity)。
  3. 服务进程 后台启动的Service进程。
  4. 后台进程 后台运行的Activity进程。
  5. 空进程 不属于前面四种进程的任何一种,出于缓存目的而保留,随时会被系统回收。

3 Android任务栈

Android任务栈,栈结构,后进先出,是一个Activity实例的集合,用于保存Activity实例,Android系统使用任务栈,有序的管理每个Activity。Activity启动、退出的过程,就是一个Activity是入栈、出栈的过程。 退出APP时,需要清空任务栈中所有的Activity,销毁任务栈,才能安全的退出APP。 一个APP中不仅一个任务栈,某些情况下(singleInstance启动模式)一个Activity可以独享一个任务栈。

4 Activity启动模式

4.1Activity四种启动模式

  1. standard:标准模式 每次启动Activity,都会创建一个Activity实例,并压入栈顶。此种方法比较消耗系统资源。
  2. singleTop:栈顶复用 启动Activity时,如果任务栈栈顶为目标Activity,则不重新创建该Activity实例。
  3. singleTask:栈内复用 启动Activity时,如果任务栈内存在目标Activity,则将目标Activity以上的Activity全部出栈,将目标Activity置于栈顶,并获取焦点。
  4. singleInstance:全局唯一模式 为目标Activity创建一个新的任务栈,将目标Activity入栈,并获取焦点,该Task中有且只有一个Activity实例。已存在的Activity不会被重新创建,而是将已存在的实例唤醒。

4.2 onNewIntent

Activity启动模式为singleTop、singleTask、singleInstance启动模式,不创建Activity实例的情况下,会调用onNewIntent(),方法。

  • Activity启动模式为singleTask或singleInstance

    1. Activity A start Activity B
    2. Activity B start Activity A 执行第二步时,Activity A的生命周期:onNewIntent()->onRestart()->onStart()->onResume()
  • Activty启动模式为singleTop、singleTask、singleInstance

    1. start Activity A
    2. Activity A start Activity B 第二步执行后,Activity A顺序执行onPause()->onNewIntent()->onResume()

第一种情况,目标Activity真正的被restart,第二种情况,目标Activity位于栈顶,再次start就会直接进入onNewIntent()。

总结:无论什么启动模式,只要Activity是同一个实例,并且Intent发生了变化,就会进入onNewIntent(),在这个方法中,需要对就得Intent 进行保存,对新的Intent进行处理。使用setIntent(intent),给Activity赋值新的Intent,否则,后续的getIntent(),获取到的都是旧的Intent。

5 Activity横竖屏切换生命周期

  • 不设置configChanges 重新创建Activity onPause()->onStop()->onDestory()->onCreate()->onStart()->onResume()
  • 设置android:configChanges="orientation|keyboardHidden|screenSize" 不重新创建Activity,调用onConfigurationChanged()

6 scheme跳转协议

Android中的scheme跳转协议是一种页面内跳转协议,通过定义自己的scheme协议,跳转到指APP指定的页面。

6.1 使用场景:

  • 服务器下发URL路径,客户端根据URL跳转到指定页面;
  • 从h5页面,跳转到响应的Activity;
  • APP根据URL,跳转到另一个APP的指定页面。

6.2 demo

SchemeTest跳转到SchemeTest2的SchemeActivity,部分代码如下:

  • SchemeTest:

    • 跳转

      public void onclick(View view) {   
              Uri uri = Uri.parse("scheme://autowanglei/sunny?jsonData=123");
              Intent intent = new Intent(Intent.ACTION_VIEW, uri);
              startActivity(intent);
       }
      
    • 判断scheme是否有效:

          /**
           * 判断APP是否安装 - 2
           *
           * @return
           */
          public static boolean checkUrlScheme(Activity activity) {
              Uri uri = Uri.parse("scheme://autowanglei/sunny?jsonData=123"");//scheme
              Intent intent = new Intent(Intent.ACTION_VIEW, uri);
      
              PackageManager packageManager = activity.getPackageManager();
              List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
              return !activities.isEmpty();
          }   
      
  • SchemeTest2:

    • AndroidManifest.xml

      <activity android:name=".SchemeActivity"> 
          <intent-filter>
              <action android:name="android.intent.action.VIEW" />
              <category android:name="android.intent.category.DEFAULT" />
              <data
                  android:host="autowanglei" 
                  android:path="/sunny" 
                  android:scheme="scheme" />
          </intent-filter>
      </activity>
      
    • SchemeActivity

      Uri uri = getIntent().getData();
      String scheme = uri.getScheme();// scheme 
      host = uri.getHost();//autowanglei 
      path = uri.getPath();///sunny 
      queryString = uri.getQuery();//jsonData=123