android之activity全面解析

本篇文章包括

概述

数据传递

生命周期

启动模式

Activity 进入和退出动画

概述

Activity是Android提供给开发者的一个组件,主要用于前台界面的展示和交互。在android中,使用频率最高,Android应用程序通常由多个Activity组成,几乎所有Activity都与用户交互。
activity工作流程

这里有两个几乎所有Activity子类都会实现的方法:

onCreate(Bundle)

是你初始化Activity的地方。最重要的,这里你经常会调用setContentView(int)并传入一个布局资源来定义你的UI,并且通过调用findViewById(int)得到UI中在编程时需要交互的组件。

onPause()

是处理用户离开你Activity的地方。最重要的,所有用户行为导致产生的变化都应该在此节点提交(例如ContentProvider持有数据)。

为了使用Context.startActivity(),所有Activity类型都必须在包的AndroidManifest.xml中存在对应的声明。

Activity和AppcompatActivity

继承AppCompatActivity的界面,界面会有一个默认的actionbar

public class MainActivity extends AppCompatActivity {  

   @Override  
   
   protected void onCreate(Bundle savedInstanceState) {  
 
       super.onCreate(savedInstanceState);  
        
      setContentView(R.layout.activity_main);  
   
 }  
}  

如果继承activity的话,该actionbar会消失。ActionBar向前兼容,出现在support v7里,如果需要使用兼容版的actionbar,则继承support v7提供的ActionBarActivity ,不过点进去ActionBarActivity从源码看ActionBarActivity实际就是AppCompatActivity,就是带有标题栏的Activity. 但是目前的v7包下并没有ActionBarActivity,

所以现在最常用的还是AppcompaActivity,AppcompaActivity其实也是ActionBarActivity 修改而来。

AppcompaActivity相对于Activity的变化;

1、 主界面带有toolbar的标题栏;

2 、theme主题只能用android:theme=”@style/AppTheme (appTheme主题或者其子类),而不能用android:style
否则会提示错误:
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

activity实现全屏(去掉标题栏和状态栏)的两种方法

1、需要在setContentView方法调用之前设置。

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

2、 定义一个主题,在styles.xml里面并引用。

<resources>
    <style name="Theme.NoTitle_FullScreen">
    	<item name="android:windowNoTitle">true</item>  
    	<item name="android:windowFullscreen">true</item>    
    </style>
</resources>

Intent 启动Activity和传递数据

    1.intent.putExtra(key,value):
    //key一般是String,值为 java八大基本数据类型及对应的数组,String及对应的数组,序列化 Serializable Parcelable的对象及对应的数组等
    2.intent.putExtras(bundle);
    3.intent.putExtra(key,bundle)
    
 Main2Activity(目标文件):
        1.intent.getXXXExtra(key)获取值
        2.bundle=intent.getExtras()
        3.bundle=intent.getExtras(key)


   //显式跳转
   val intent= Intent(this,Main2Activity::class.java)
   startActivity(intent)

    //传参
    val intent1= Intent(this,Main2Activity::class.java)
    intent1.putExtra("name","小明")
    startActivity(intent)

    //Main2Activity中
     val name=intent.getStringExtra("name")

    
    //bundle传参
    val bundle=Bundle()
    bundle.putString("name","小明")
    val intent2= Intent(this,Main2Activity::class.java)
    intent2.putExtras(bundle)
    startActivity(intent)

    //Main2Activity中
    val bundle1=intent.extras
    val name1=bundle1.get("name")

startActivityForResult完成activity向第二个activity传递数据并且回传数据。

1.使用startActivityForResult(intent,requestCode(大于等于0))方法激活目标Activity
2.在目标Activity 中调用setResult(resultCode,intent) 设置回传到源Activity 的结果码和意图对象
3.在源Activity 中重写onActivityResult(requestCode,resultCode,intent)方法得到目标Activity 回传的数据

    //发起者中写:
    val intent3= Intent(this,Main2Activity::class.java)
    intent3.putExtra("name","小明")
    startActivityForResult(intent3,100)

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode==100&&resultCode==200){
        val name3=data?.getStringExtra("name")
      
    }

    //Main2Activity中
   // 收到数据
    val name2=intent.getStringExtra("name")

    //回传数据
    val intent4= Intent(this,Main2Activity::class.java)
    intent4.putExtra("name","小红")
    setResult(200,intent4)
}
}

传递对象时候,需要对对象进行序列化Serializable Parcelable

   class Student(id:Int,name:String,age:Int) :Serializable{   
    var id:Int=0
    var name:String=""
    var age:Int=0
}

  val intent5= Intent(this,Main2Activity::class.java)
    intent5.putExtra("student",Student(1,"小明",10))
    startActivity(intent)
   
    //Main2Activity中
   val student= intent.getSerializableExtra("student")

隐式启动常用于不同应用之间的跳转(例如打开支付宝微信的支付页面),也可用于H5与native之间的交互。隐式启动就是action,category和data的匹配,篇幅有限,请参考添加链接安卓Activity隐式启动全面解析

Intent在传递数据时是有大小限制的,这里官方并未详细说明,不过通过实验的方法可以测出数据应该被限制在1MB之内(1024KB)

activity生命周期

在这里插入图片描述

Activity的整个生命周期发生在onCreate()和onDestroy()之间,activity在此期间存在。

Activity的可见生命周期发生在onStart()和onStop()之间,activity在此期间状态可见。

Activity的前景生命周期发生在调用onResume()和调用之间onPause(),activity在此期间处于屏幕最上层,用户可以与之交互。

在这里插入图片描述

1、要保存用户输入数据,需要在onPause()中执行,而不是在onStop()和onDestroy()中.因为如果离开当前activity onPause()一定被调用。

2、onSaveInstanceState()

onCreate就是Android提供给开发者用来对Activity实例对象中的成员做初始化的,

某些设备配置可能会在运行时更改(例如屏幕方向,键盘可用性和语言)。发生此类更改时,Android会重新创建正在运行的活动(系统调用onDestroy(),然后立即调用

onCreate()).处理此类重新启动的最佳方法是使用onSaveInstanceState()和onRestoreInstanceState()(或onCreate())来保存和恢复Activity活动状态

//用来保存用户状态信息onSaveInstanceState() 在Activity受破坏之前,系统会自动调用。系统会传递一个Bundle对象,您可以使用诸如putString()和putInt()之类的方

法将关于Activity的状态信息保存为名称 - 值的键值对.
然后,如果系统终止您的应用程序进程,系统将重新创建活动并将其Bundle传递给Activity的onCreate()和

onRestoreInstanceState()。使用这些方法之一,您可以从中提取已保存的状态Bundle并恢复活动状态。如果没有要恢复的状态信息,则Bundle传递给您的是null

3、当dialog弹出来的时候,如果是单纯是创建的dialog,Activity并不会执行生命周期的方法,但是如果是跳转到一个不是全屏的Activity的话,当然就是按照正常的生

命周期来执行了,即onPasue()->onStop()。

4、设备横竖屏切换的时候。

不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次;
设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次;

设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法;

tips:还有一点,非常重要,一个Android的变更细节!
当API >12时,需要加入screenSize属性,否则屏幕切换时即使你设置了orientation系统也会重建Activity!

5、有时候activity界面如果有dialog经常会发生activity为空,直接崩溃,这个时候可以加个判断

if (!MainActivity.this.isDestroyed()) {
            new AlertDialog.Builder(MainActivity.this).setMessage("Show Dialog").show();
        }

Activity启动模式:

Activity四种启动模式的设定出于两种目的:

复用机制,节省系统资源,这种情况主要发生在除Standard模式外的三种模式上,通过他们的名字前缀Single也可以看出,跟Java中的单例模式有类似的思想,避免太多的实例对象创建开销。

根据用户的交互行为定义,因为Activity最终的目的还是完成用户在各种交互场景下的需求。

在android里,有4种activity的启动模式,分别为:standard (默认) singleTop singleTask singleInstance

当应用运行起来后就会开启一条线程,线程中会运行一个任务栈,当Activity实例创建后就会放入任务栈中。Activity启动模式的设置在AndroidManifest.xml文件中,通过配置Activity的属性android:launchMode=""设置。

1. Standared模式(默认)

我们平时直接创建的Activity都是这种模式的Activity,这种模式的Activity的特点是:只要你创建了Activity实例,一旦激活该Activity,则会向任务栈中加入新创建的实例,退出Activity则会在任务栈中销毁该实例。
standartd模式是activity的默认模式,大部分情况下,都应该使用这种模式,也就是在配置文件中什么都不用做,当确实有特殊需求时,再考虑其他模式。

2. SingleTop 栈顶复用模式

栈顶模式,阅读类app经常会使用。这种模式会考虑当前要激活的Activity实例在任务栈中是否正处于栈顶,如果处于栈顶则无需重新创建新的实例,会重用已存在的实例,否则会在任务栈中创建新的实例。

3. SingleTask 栈内复用模式

如果任务栈中存在该模式的Activity实例,则把栈中该实例以上的Activity实例全部移除,调用该实例的newInstance()方法重用该Activity,使该实例处於栈顶位置,否则就重新创建一个新的Activity实例。

4. SingleInstance模式

当该模式Activity实例在任务栈中创建后,只要该实例还在任务栈中,即只要激活的是该类型的Activity,都会通过调用实例的newInstance()方法重用该Activity,此时使用的都是同一个Activity实例,它都会处于任务栈的栈顶。此模式一般用于加载较慢的,比较耗性能且不需要每次都重新创建的Activity。

后台堆栈

后台堆栈指的是Activitys在后台任务中的排列规则,按"后进先出"排列.

例如当前Activity启动另一个Activity时,新Activity将被推到堆栈顶部并获得焦点。之前的Activity仍在堆栈中,但已停止。当活动停止时,系统将保留其用户界面的当前状态。当用户按下“ 返回” 按钮时,当前Activity将从堆栈顶部弹出(活动被销毁),之前的Activity将恢复(其UI的先前状态将恢复)。堆栈中的活动永远不会重新排列,只能在当前Activity启动时从堆栈推送和弹出到堆栈中,并在用户使用Back按钮退出时弹出.因此,后台堆栈作为“后进先出”对象结构操作。

当此Activity的实例已经存在,并且此时的启动模式为SingleTask和SingleInstance,另外当这个实例位于栈顶且启动模式为SingleTop时也会触发onNewInstent()。此方法会把activity带到前台。

activity进入退出动画

淡入淡出为例:
首先在res文件夹下建立anim文件夹,然后在里面建立fade_in.xml和fade_out.xml两个动画资源

<?xml version="1.0" encoding="utf-8"?>  
<alpha xmlns:android="http://schemas.android.com/apk/res/android"  
    android:duration="500"  
    android:fromAlpha="0.0"  
    android:interpolator="@android:anim/accelerate_interpolator"  
    android:toAlpha="1.0" />


<?xml version="1.0" encoding="utf-8"?>  
<alpha xmlns:android="http://schemas.android.com/apk/res/android"  
    android:duration="1000"  
    android:fromAlpha="1.0"  
    android:interpolator="@android:anim/accelerate_interpolator"  
    android:toAlpha="0.0" /> 

然后在values文件夹下的styles.xml中的resources标签内写:

<style name="Anim_fade" parent="android:Theme.NoTitleBar">  
       <item name="android:windowAnimationStyle">@style/fade</item>  
   </style>  
  
   <style name="fade" parent="@android:style/Animation.Activity">  
       <item name="android:activityOpenEnterAnimation">@anim/fade_in</item>  
       <item name="android:activityOpenExitAnimation">@anim/fade_out</item>  
       <item name="android:activityCloseEnterAnimation">@anim/fade_in</item>  
       <item name="android:activityCloseExitAnimation">@anim/fade_out</item>  
   </style>

接下来在Mainfest中的activity中添加上android:theme="@style/Anim_fade"即可。
当然更简单,更推荐的方法是在oncreate()里面添加

  class Main2Activity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        overridePendingTransition(R.anim.fade_in,R.anim.fade_out)
    }

    override fun finish() {
        super.finish()
        overridePendingTransition(R.anim.fade_in,R.anim.fade_out)
    }
}

滑动动画

slide_in_left:从左边划进来:-100%p—>0
slide_in_right:从右边划进来:100%p—>0
slide_out_left:从左边划出去:0—>-100%p
slide_out_right:从右边划出去:0—>100%p

R.anim.slide_in_left.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate 
        android:duration="2000"
        android:fromXDelta="-100%p"
        android:toXDelta="0"/>

</set>

R.anim.slide_in_right.xml

R.anim.slide_out_left

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate 
        android:duration="2000"
        android:fromXDelta="0"
        android:toXDelta="-100%p"/>   
</set>

R.anim.slide_out_right

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate 
        android:duration="2000"
        android:fromXDelta="0"
        android:toXDelta="100%p"/>

</set>

R.anim.no_slide.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="300"
        android:fromAlpha="1"
        android:toAlpha="1" />
</set>

然后在values文件夹下的styles.xml中的resources标签内写:

<style name="Anim_translate" parent="android:Theme.NoTitleBar">  
       <item name="android:windowAnimationStyle">@style/translate</item>  
   </style>
   
    <style name="translate" parent="@android:style/Animation.Activity">  
       <item name="android:activityOpenEnterAnimation">@anim/slide_in_left</item>  
       <item name="android:activityOpenExitAnimation">@anim/slide_out_right</item>  
       <item name="android:activityCloseEnterAnimation">@anim/slide_in_right</item>  
       <item name="android:activityCloseExitAnimation">@anim/slide_out_left</item>  
   </style>

最后引用一下这个主题就好了
android:theme="@style/Anim_translate"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值