美文网首页
Android学习(二)—— 四大组件之Activity

Android学习(二)—— 四大组件之Activity

作者: LongSh1z | 来源:发表于2019-05-07 20:01 被阅读0次

    本文目录结构:
    一、活动的生命周期
    二、活动的启动模式
    三、活动间的信息传递之一 —— Intent

    一、活动的生命周期

    1.返回栈

    Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也叫返回栈。在默认情况下,当我们启动了一个活动,那么它会入栈,并处于栈顶的位置。当我们按下返回键或者调用finish方法时,处于栈顶的活动就会出栈。系统总是显示处于栈顶的活动。

    2.活动状态

    活动的状态可以分为4种:
    (1)运行状态
    当一个活动处于栈顶的时候,那么它就处于运行状态。系统就不愿意就是回收运行状态的活动,因为这会给用户带来很不好的体验。
    (2)暂停状态
    当一个活动不处于栈顶但仍然可见时,它就处于暂停状态。比如对话框形式的活动只会占用屏幕中间的区域。系统也不愿意回收这样的活动,只有在内存极低的时候才会考虑去回收。
    (3)停止状态
    当一个活动不再处于栈顶,并且不可见的时候,就进入了停止状态。系统仍然会为这种活动保存相应的状态和成员变量,但这并不是完全可靠的。当其他地方需要内存,系统就有可能回收掉该活动。
    (4)销毁状态
    当一个活动被栈移除之后,它就处于销毁状态。系统最愿意回收这样的活动,从而保持手机内存的充足。

    3.活动的生命周期

    (1)onCreate
    它会在活动第一次创建的时候被调用。我们应该在该方法中完成活动的初始化操作,比如加载布局、绑定事件等。
    (2)onStart
    该方法在活动由不可见变为可见的时候调用。
    (3)onResume
    该方法在活动准备好和用户交互的时候调用。此时的活动一定处于栈顶的位置。
    (4)onPause
    该方法在系统准备去启动或恢复另一个活动的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放掉,但该方法的执行速度一定要快,不然会影响到新的栈顶活动的调用。
    (5)onStop
    该方法在活动完全不可见的时候调用。它和onPause方法不同的是,如果启动的新活动是一个对话框形式的活动,那么onPause方法会被调用,而它不会。
    (6)onDestroy
    该方法会在活动被销毁之前调用。
    (7)onRestart
    该方法会在活动从停止状态变为运行状态之前调用。

    活动的生命周期.jpg

    PS:如果活动被销毁了,但是可能存在临时数据和状态,那要怎么办呢?
    ①可以调用onSaveInstanceState方法将数据临时保存起来
    @Override
    protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    String data = "Keep it";
    outState.putString("tempData",data);
    }
    ②然后在onCreate方法中判断savedInstanceState是否为空
    @Override
    protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    ......
    if(savedInstanceState != null)
    String tempData = savedInstanceState.getString("tempData");
    }

    二、活动的启动模式

    活动的启动模式一共有4种,它们需要在AndroidManifest文件中通过给<activity>标签指定android:launchMode属性来设置。

    1.standard

    它是活动默认的启动模式。每当有一个活动启动时,它就会入栈并处于栈顶的位置。系统根本不在乎栈里是否已经有了该活动的实例,每次启动活动都会创建一个新的实例。


    standard.jpg
    2.singleTop

    当活动指定为该模式时,在启动活动时如果发现栈顶的活动已经是该活动,则系统会直接使用它,不会再创建新的活动实例。但如果该活动不在栈顶时再启动该活动时,还是会创建新的实例的。


    singleTop.jpg
    3.singleTask

    当活动处于该模式时,每次启动活动时系统首先会在栈里检查是否存在该活动的实例,如果发现有则直接使用,并把在该活动之上的所有活动出栈。如果没发现则创建一个新的活动实例。


    singleTask.jpg
    4.singleInstance

    当活动处于该模式时,系统会启用一个新的栈来管理这个活动。它可以解决共享活动实例的问题。比如:活动B为该模式,然后A启动B,B启动C,那么第一次按下返回键时系统会回到A,再按下一次时会回到B,再按下一次则退出应用。一个栈里的活动没有了之后才会去到另一个栈。


    singleInstance.png

    三、活动间的信息传递之一 —— Intent

    1.显式Intent

    (1)构造方法

    //Intent intent = new Intent(Context packageContext,Class<?> cls);
    //前者为启动活动的上下文,后者为想要启动的目标活动
    Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
    

    (2)setComponent方法

    ComponentName componentName = new ComponentName(this, SecondActivity.class);  
    Intent intent = new Intent();  
    intent.setComponent(componentName);  
    startActivity(intent);
    

    (3)setClass/setClassName方法

    Intent intent = new Intent();  
    intent.setClass(this, SecondActivity.class);  
    // 或者intent.setClassName(this, "top.longsh1z.www.SecondActivity");  
    // 或者intent.setClassName(this.getPackageName(), "top.longsh1z.www.SecondActivity");        
    startActivity(intent);
    
    2.隐式Intent

    顾名思义,隐式Intent不会明确的指出想要启动的activity,而是通过指定action和category等信息让系统来选择要启动的活动。

    首先,在AndroidManifest文件中,目标活动要有<intent-filter>标签,里面包含<action><category>子标签,只有这两个子标签中的内容同时匹配才能够生效。比如:

    <activity android:name=".ui.Main2Activity">
      <intent-filter>
        <action android:name="top.longsh1z.www.Main2Activity"/>
        <!--该category是一种默认的category-->
        <!--在调用startActivity方法时会自动将这个category加到intent中-->
        <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>
    </activity>
    

    设置intent有两种方法:
    (1)构造方法

    Intent intent = new Intent("top.longsh1z.www.Main2Activity");
    //如果category不是默认的话要再加下面的一条语句
    //比如在AndroidManifest中自定义的category为
    //top.longsh1z.www.Main2Activity_category,那么该语句为
    //intent.addCategory("top.longsh1z.www.Main2Activity_category");
    startActivity(intent);
    

    (2)setAction方法

    Intent intent = new Intent();
    intent.setAction("top.longsh1z.www.Main2Activity");
    //如果category不是默认的话同上
    startActivity(intent);
    
    3.更多隐式Intent的用法

    我们也可以调用系统中固有的活动,比如系统的浏览器,拨号等等。比如调用系统浏览器:

    //Intent.ACTION_VIEW是系统内置的动作,其常量值为android.intent.action.VIEW
    Intent intent = new Intent(Intent.ACTION_VIEW);
    //这条语句的意思是打开百度,具体其他用法请自己搜索
    intent.setData(Uri.parse("https://www.baidu.com"));
    startActivity(intent);
    

    另外,在一个活动的<action>标签里也可以写成系统内置的动作。当然这个前提是你的程序要有这样的功能,不然的话就会报错。

    4.向下一个活动传递数据

    使用intent.putExtra方法放消息,使用intent.getStringExtra方法拿消息。

    //放消息进intent中
    String data = "Hello world!";
    Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
    intent.putExtra("MyData",data);
    //其中data不一定只限于字符串,也可以为int,boolean类型
    startActivity(intent);
    
    //取消息
    Intent intent = getIntent();
    String data = intent.getStringExtra("MyData");
    //若传递的数据为其他类型,则为getXxxExtra方法,比如getIntExtra,getBooleanExtra方法
    

    5.返回数据给上一个活动
    总体思路为(这里假设是FActivity<简写为F>)跳到SActivity<简写为S>,再S返回数据给F)
    先在F中使用startActivityForResult方法向S传递一个唯一的请求码,
    然后在S中使用setResult方法将结果码和数据返回给F,
    最后F在onActivityResult中通过请求码和结果码拿到返回的数据。

    //F中:
    Intent intent = new Intent(F.this,S.class);
    startActivityForResult(intent,1);//这里请求码为1
    
    //S中:
    Intent intent = new Intent();
    intent.putExtra("dataReturn","I am dataReturn.");
    setResult(RESULT_OK,intent);
    //第一个参数一般只使用RESULT_OK或RESULT_CANCELED这两个值
    
    //F中:
    @Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data){
      //第一个参数为请求码,是为了区分是哪个activity返回的数据,即数据来源
      //第二个参数是判断处理结果是否成功
      //第三个参数就是返回的数据
      switch(requestCode){
        case 1:
          if(resultCode == RESULT_OK){
            String data = intent.getStringExtra("dataReturn");
          }
        break;
      }
    }
    

    相关文章

      网友评论

          本文标题:Android学习(二)—— 四大组件之Activity

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