美文网首页
Android笔记-四大组件之Activity

Android笔记-四大组件之Activity

作者: 948d307d6ecf | 来源:发表于2018-04-28 10:30 被阅读0次

    简介

    Activity是Android APP开发中最常用、最基础的组件,属于Android四大组件之一,其主要负责UI展示以及与用户交互。

    启动

    • 显式启动
      显示启动就是明确指出要启动的目标Acitivity的名称,然后通过startActivity()或startAcitivtyForResult()方法来启动,并且在启动的时候可以携带数据至目标Activity。

      • 无参数无返回结果
      //StartActivity.java文件中
      this.startActivity(new Intent(this, TargetActivity.class));
      
      • 有参数无返回结果
      //send StartActivity.java文件中
      Intent intent = new Intent(this, TargetActivity.class);
      intent.putExtra("args_data", "data from start activity with explicit");
      this.startActivity(intent);
      
      //received TargetActivity.java文件中
      String data = getIntent().getStringExtra("args_data");
      
      • 无参数有返回结果
      //1.send StartActivity.java文件中
      //1.1 启动时指定requestCode = 1
      this.startActivityForResult(new Intent(this, TargetActivity.class), 1);
      
      //1.2 重写onActivityResult方法,通过requestCode、resulutCode和Intent获取返回结果
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          if (requestCode == 1) {
              if (resultCode == RESULT_OK) {
                  ((TextView) findViewById(R.id.text_dashboard)).setText("got data: " + data.getStringExtra("data_return"));
              }
          }
      }
      
      //2. received TargetActivity.java文件中
      Intent intent = new Intent();
      intent.putExtra("data_return", "return data from target");
      setResult(RESULT_OK, intent);
      finish();
      
      • 有参数有返回结果
      //1.send StartActivity.java文件中
      //1.1 启动时指定requestCode = 1
      Intent intent = new Intent(this, TargetActivity.class);
      intent.putExtra("args_data", "data from start activity for result with explicit");
      this.startActivityForResult(intent, 1);
      
      //1.2 重写onActivityResult方法,通过requestCode、resulutCode和Intent获取返回结果
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          if (requestCode == 1) {
              if (resultCode == RESULT_OK) {
                  ((TextView) findViewById(R.id.text_dashboard)).setText("got data: " + data.getStringExtra("data_return"));
              }
          }
      }
      
      //2. received TargetActivity.java文件中
      Intent intent = new Intent();
      intent.putExtra("data_return", "return data from target");
      setResult(RESULT_OK, intent);
      finish();
      

      温馨提示:显式启动的方式有个比较好的写法是在每个Activity中声明静态方法来启动当前Activity,启动参数信息可以一目了然,对于调用者来说非常清晰明了,示例代码如下:

      public class TargetActivity extends AppCompatActivity {
          private static final String DATA_TAG = "data_tag";
          
          public static void startAction(Context context, XXX args) {
              Intent intent = new Intent(context, TargetActivity.class);
              intent.putExtra(DATA_TAG, args);
              context.startActivity(intent);
          }
      }
      
    • 隐式启动
      隐式启动是通过一定的匹配规则来进行启动目标Activity的,相对于显式启动更加隐晦,数据的传递及返回均域显式启动相同,唯一不同的是Intent中必须指定action名字,以及category类型(可以不需要,默认通过 `android.intent.category.DEFAULT 来匹配),另外需要在manifest文件中为目标Activity添加过滤条件,只有完全匹配的才能正常启动,简单示例如下:

      //1. manifest.xml文件中
      <activity android:name=".activity.TargetActivity">
           <intent-filter>
               <action android:name="com.example.study.START_ACTION" />
               <category android:name="android.intent.category.DEFAULT" />
           </intent-filter>
       </activity>
           
      //2. StartActivity.java 文件中
      this.startActivity(new Intent("com.example.study.START_ACTION"));
      

      温馨提示:隐式启动一般用于启动其他应用,比如拨号器和网页等,由于其需要启动的目标Activity比较隐晦,不利于代码阅读,因此在应用内尽量不要用隐式启动方式来实现启动目标Activity。

      隐式启动除了可以启动本应用或者其他应用以外,还有一个比较常用的场景,即当需要在别的应用或者浏览器中启动我们的应用时,需要给我们的响应Activity配上隐式启动规则。

    销毁

    销毁Activity只需要调用finish() 方法即可。

    生命周期

    • onCreate()
      该方法只在Activity第一次创建时调用,描述的是从无到有的一个状态变化,整个页面生存期间 只调用一次 ,在该方法中主要做一些初始化的工作,比如:加载布局绑定事件等。

    • onStart()
      该方法在Activity从不可见变成可见时调用,该方法中不要做耗时较长的事情。

    • onResume()
      该方法在Activity从可见变成可交互时调用,在该方法中做一些特殊的业务逻辑,比如每次回到页面刷新页面数据

    • onPause()
      该方法在Activity从可交互变成可见但不可交互时调用,通常会在该方法中释放消耗cpu的资源保存关键性数据,但是该方法执行速度一定要快,否则会影响新Activity的展示速度

    • onStop()
      该方法在Activity从可见变成不可见时调用。

    • onDestroy()
      该方法在Activity被销毁前调用,主要做一些资源的释放工作。

    • onRestart()
      该方法在Activity未销毁但不可见时将要变得可见时调用

    一图胜千言:


    Activity生命周期图.png

    下面来看下几种常见场景的生命周期方法调用顺序:

    • 当前Activity 启动另外一个正常Activity,然后返回,整个生命周期过程如下图:
    启动正常Activity然后返回生命周期时序图.png

    通过该时序图,可以看出即将不可见的Activity的onStop()是在即将可见Activity的onResume()方法之后调用的。

    • 当前Activity 启动一个Dialog类型的Acitivty,然后返回,整个生命周期过程如下图所示:
    启动一个Dialog类型的Acitivty然后返回生命周期时序图.png

    在这种情况下,主要区别在于Dialog类型的Activity和普通Activity的不同,前者不会完全遮挡住后面的Activity,所以后面的Activity还是可见的,只是不能与用户交互了而已,因此后面可见但是不可交互Activity的onStop()onRestart()onStart()方法不会被调用。

    Dialog类型Activity的最简单的创建方法是指定Activity的theme为Dialog类型即可。

        <activity
            android:name=".activity.lifecycle.LifecycleDialogActivity"
            android:theme="@style/Theme.AppCompat.Light.Dialog.Alert" />
    
    • 当前Activity 启动一个Alert Dialog,然后返回,整个生命周期过程
      创建一个最简单的AlertDialog代码如下:
      private void showAlertDialog() {
            new AlertDialog.Builder(this)
                    .setTitle("Alert Dialog Title")
                    .setMessage("The message content of this alert dialog!")
                    .setPositiveButton("ok", null)
                    .setNegativeButton("cancel", null)
                    .create()
                    .show();
        }
    

    AlertDialog的显示与关闭过程中都没有任何生命周期方法调用。

    • 横竖屏切换的生命周期


      横竖屏切换Acitivity的生命周期.png

    正常情况下横竖屏的切换,其实都是销毁当前Activity重新创建一个新Activity的过程。

    启动模式

    Android系统里面通过返回栈来管理每个Activity,当一个Activity被创建出来就会进栈,而当一个Activity销毁了就会出栈,并且当前位于栈顶的Activity一定是当前显示的Activity,系统提供了以下四种启动模式,可以根据需要给每个Activity设置不同的启动模式。

    • standard模式
      这是默认的启动模式,如果什么也不设置即为此模式,此模式的特点是:每次启动都会创建一个新的实例而不关心当前栈里是否已存在此Activity的实例

    • singleTop模式
      此模式的特点是:每次当需要创建一个Activity的实例时,先检查当前栈顶是否为此Activity的实例,如果是则复用,反之才会创建一个新的实例。常用设置方式为:

        <activity
            android:name=".activity.mode.ModeSingleTopActivity"
            android:launchMode="singleTop" />
      

      此模式通常用于Dialog类型Activity的启动模式。

    • singleTask模式
      此模式的特点是:栈中只存在唯一实例,如果已经存在,将其置为栈顶,位于其上面的Activity全部出栈, 反之则创建新的实例。常用设置方式为:

        <activity
            android:name=".activity.mode.ModeSingleTaskActivity"
            android:launchMode="singleTask" />
      

      此模式常用于一个应用的主Activity的启动模式。

    • singleInstance模式
      此模式的特点是:创建一个新的栈来管理此Activity。常用设置方式为:

        <activity
            android:name=".activity.mode.ModeSingleInstanceActivity"
            android:launchMode="singleInstance" />
      

      此模式通常用于需要与其他应用共享此Activity实例的情景,即一个Activity实例多个应用共享。如果此Activity中启动一个常规的Activity,则该常规Activity继续在老的栈中管理,此时如果按返回,会直接返回至上上个页面的Activity,例如:A-->B(SingleInstance模式)-->C,在C中按下返回按钮直接返回至A。

    面试常考点

    1. onStart()与onResume()的区别
    2. 横竖屏切换的生命周期
    3. Activity启动流程

    相关文章

      网友评论

          本文标题:Android笔记-四大组件之Activity

          本文链接:https://www.haomeiwen.com/subject/evlblftx.html