zoukankan      html  css  js  c++  java
  • Android之Activity组件

    一 、定义与创建

      定义:简单的说,一个Activity就是一个界面

      创建:定义类继承Activity,并在清单文件的Application节点下配置

     1  <activity
     2     android:name="com.example.application.MainActivity"
     3     android:label="@string/app_name" >
     4     <intent-filter>
     5         <action android:name="android.intent.action.MAIN" />
     6 
     7         <category android:name="android.intent.category.LAUNCHER" />
     8     </intent-filter>
     9 </activity>
    10 <activity android:name="com.example.application.PlayGame"></activity>

      <intent-filter/>:在Launcher中显示的快捷方式(程序的入口)

      一个应用程序对应一个快捷方式即自定义的标签中不配置也可以,程序的入口只有Main一个,在main的界面进行某些操作点击按钮或超链接来启动另外一个Activity

    二 、生命周期

      一个活动有三个基本状态:

    • 激活状态运行状态,这时它运行在屏幕的前台(处于当前任务活动栈的最上面)。这个活动有用户的操作的焦点。
    • 暂停状态,这时活动失去焦点但是它对用户仍可见。也就是说,另一个活动在它的上面且那个活动是透明的或者没有覆盖整个屏幕,因此通过它可以看见暂停状态的活动。一个暂停的活动完全是活着的(它维护着所有的状态和成员信息,且仍然依附在窗口管理器),但是当内存极小时可以被系统杀掉。
    • 停止状态,这时活动完全被其他活动掩盖。它仍然保留所有状态和成员信息,但是对用户它不可见,因此它的窗口时隐藏的且当其他地方需要内存时它往往被系统杀掉。

      如果一个活动被暂停或停止,系统可以将它从内存移除,通过要求它结束(通过调用它的finish()方法),或简单地杀掉它的进程。当它再次显示给用户时,必须要完全重新启动和恢复到之前的状态。随着活动从一个状态转为另一个状态,通过调用下面的受保护的方法通知该改变:

    • void onCreate(Bundle saveInstanceState)
    • void onStart()
    • void onRestart()
    • void onResume()
    • void onPause()
    • void onStop()
    • void onDestroy()

      所有这些方法都是钩子,你可以重写当状态改变时做适当的工作。所有的活动必须要实现onCreate()去做一些初始化的设置,当对象第一次实例化的时候。很多活动也会实现onPause()去提交数据修改或准备停止与用户交互。

      将他们合并在一起,这七个方法定义了活动的整个生命周期。有三个嵌套的循环,你可以通过这七个方法监视:

    • 活动的整个生命时间,从第一次调用onCreate()开始直到调用onDestroy()结束。一个活动在onCreate()中做所有的“全局”状态的初始设置,在onDestroy()中释放所有保留的资源。举例来说,有一个线程运行在后台从网络上下载数据,它可能会在onCreate()中创建线程,在onDestroy()中结束线程。
    • 活动的可视生命时间,从调用onStart()到相应的调用onStop() 。在这期间,用户可以在屏幕上看见活动,虽然它可能不是运行在前台且与用户交互。在这两个方法之间,你可以保持显示活动所需要的资源。举例来说,你可以在onStart()中注册一个广播接收者监视影响你的UI的改变,在onStop() 中注销。因为活动在可视和隐藏之间来回切换,onStart()onStop()  可以调用多次。
    • 活动的前台生命时间,从调用onResume()到相应的调用onPause()。在这期间,频繁地在重用和暂停状态转换——例如,当设备进入睡眠状态或一个新的活动启动时调用onPause(),当一个活动返回或一个新的意图被传输时调用onResume()。因此,这两个方法的代码应当是相当轻量级的。

      下面这个图解释了这三个循环和状态之间状态的可能路径。着色的椭圆表示活动的主要状态,矩形表示当活动在状态之间转换时你可以执行的回调方法。

    activity_lifecycle

    三 、Activity的启动

      启动Activity:创建意图对象Intent,直接调用startActivity()方法,intent可以启动指定的activity

      启动方式:

        a、显示意图(Explicit) ----应用程序内跳转,需要指定类名

    1 Intent intent=new Intent();//创建意图对象
    2 intent.setClass(this, MainActivity.class);//指定类名
    3 //intent.setClassName(this,"com.example.application.MainActivity");方法重载,作用同上
    4 //intent.setClassName("com.abcde.sqlite","com.abcde.sqlite.ui.RefreshActivity");启动其他程序的Activity(包名+全类名)
    5 startActivity(intent);//启动activity

        b隐式意图(Implicit)---应用程序间跳转,不需指定类名(创建快捷方式需用隐式意图)

        上网操作 :

    1 Intent intent=new Intent();
    2 intent.setAction(Intent.ACTION_VIEW);//设置动作
    3 intent.setData(Uri.parse("HTTP://www.baidu.com"));//设置数据
    4 startActivity(intent);//根据意图中的数据和动作匹配一个Activity

        图片或视频:
        将所要用的图片和视频烤到mnt的sdcard下,文件名不可有中文,否则无法导入
     

    1 Intent intent=new Intent();
    2 intent.setAction(Intent.ACTION_VIEW);
    3 intent.setDataAndType(Uri.parse("file:///mnt/sdcard/a.jpg"),"image/*");//图片
    4 intent.setDataAndType(Uri.parse("file:///mnt/sdcrad/1.mp3"),"audio/*");//音乐
    5 intent.setDataAndType(Uri.parse("file:///mnt/sdcard/1.mp4"),"vedio/*");//视频
    6 startActivity(intent);

    四 、Activity之间的数据传递

      可传递的数据类型:

      基本数据类型,String,Bundle,Serializable,Parcelable---- 点击按钮或者链接通过intent带数据到另一个界面(intent中带有bundle,用来存储数据,类似Mapj集合)

    案例:在MainActivity中发送数据,在OtherActivity中获取数据

      启动时传递数据:

    1. 在MainActivity中创建intent对象,利用intent对象通过putExtra()方法向intent中放数据,然后开启Activity; 
    2. 若所放的参数为javabean(person类),则需要person类实现Serializable这个接口,这样就可以放入intent中。因为是一个应用程序,两个activity 之间的跳转,一个应用程序(一个进程)之内的对象传输数据是可以的,但是activity的跳转,有可能从一个程序跳到另一个程序,也许另一个程序都没有person类,两个应用程序之间是不可以传输对象的,应用程序之间传数据只能是字节数据,不能是对象,而实现序列化后,可以把对象转为字节数组这样就可以传输,所以说要传输自定义类对象,要实现Serializable接口;若传入的为集合,List<Person>集合默认实现了,但是必须保证集合中的元素也要实现
    3. 在OtherActivity中通过getIntent()方法获得intent,  通过intent的getStringExtra()或者getIntExtra()方法获得数据
    4. Parcelable类(后期绑定服务一定会用到,绑定服务会传参数,参数必须是Parcelable),Person类实现Parcelable这个接口,并添加两个未实现的方法 
    1 public void writeToParcel(Parcel parcel,int flags){------定义怎么把该类对象写入Parcel
    2     parcel.writeString(name);
    3     parcel.writeInt(age);
    4 }

      关闭时返回数据:

        如果希望新的Activity可以返回数据, 那么就需要使用startActivityForResult()方法来启动Activity在新的Activity中调用setReuslt()方法设置要返回的数据
        finish()之后, 原Activity会自动调用onActivityResult(), 该方法的形参就是setReuslt()设置的数据

     五 、启动模式

      有四种不同的启动模式可以分配到<activity>元素的launchMody属性:

    • "standard"(默认模式)
    • "singleTop "
    • "singleTask"
    • "singleInstance"

      这些模式的在以下四方面不同:

    • 哪个任务将持有响应意图(intent)的活动。对"standard"和"singleTop "模式,是产生意图的任务(调用startActivity()方法)——除非Intent对象包含FLAG_ACTIVITY_NEW_TASK标志。在那种情况下,像上一节亲和度和新任务(Affinities and new tasks)所描述的那样选择一个不同的任务。 
      相反,"singleTask"和"singleInstance"模式,总是将活动标记为一个任务的根活动。他们定义一个任务,而从不启动到其他任务。
    • 活动是否可以实例化多次。"standard"或"singleTop "活动可以实例化多次。这些实例可以属于多个任务,且一个给定任务可以包含同一个活动的多个实例。 
      相反,"singleTask"和"singleInstance"活动仅可以被实例化一次。因为这些活动是一个任务的根,这个限制意味着设备上一个时间只有不多于一个任务的实例。
    • 是否允许实例所在任务有其他活动。"singleInstance"活动所在任务只有它一个活动。如果他启动别的活动,那些活动将启动到不同的任务中,无论它的模式如何——就好像Intent对象包含FLAG_ACTIVITY_NEW_TASK标志。在所有其他方面,"singleInstance"模式等同于"singleTask"模式。 
      其它三种模式允许多个活动属于一个任务。"singleTask"活动总是任务的根活动,但是它能启动其他活动到它的任务。"standard"或"singleTop "活动的实例可以出现的栈中的任何位置。
    • 响应一个意图时是否需要生成类的新实例。对于默认的"standard"模式,创建新的实例去响应每一个新的意图。每个实例仅处理一个意图。对于"singleTop "模式,一个类已存在的实例可以重新用了处理新的意图,如果它位于目标任务的活动栈的栈顶。如果不是在栈顶,就不可以重用。相反,将创建一个新的实例并压入栈顶。 
      例如,一个任务的活动栈由根活动A、B、C和D组成,顺序为A-B-C-D。当一个意图到达请求类型D时,如果D是默认的"standard"模式,将产生D类的新实例且栈变为A-B-C-D-D。然而,如果D的启动模式是"singleTop ",已存在的D实例将去处理新的意图(因为它在栈顶)且栈仍然是A-B-C-D。 
      如果,另一方面,到达的意图是请求类型B时,一个B的新实例将启动而不管B的模式是"standard"还是"singleTop "(因为B不是在栈顶),因此栈的结构为A-B-C-D-B。 
      如前所述,"singleTask"和"singleInstance"活动仅可以被实例化一次,因此他们的实例将处理所有的新意图。一个"singleInstance"活动总是在栈顶(因为仅有一个活动在任务中),因此它总是在可以处理意图的位置。然而,一个"singleTask"活动在栈中可能有或可能没有其他活动在它上面。如果有,即它不在处理意图的位置,意图会被丢弃(即使意图被丢弃了,它的到来使任务转到并保持在前台运行)

      当一个已存在的活动被请求处理一个新的意图,Intent对象将通过onNewIntent()调用传到活动。(产生启动活动的意图对象可以由getIntent()获取。)

      注意到当一个活动的新实例被创建去处理新意图时,用户总是可以按返回键返回到之前的状态(之前的活动)。但是当一个已存在的活动实例去处理新意图是,用户不可以按返回键返回到意图到达之前的状态。

    六、 横竖屏切换

    a.默认情况下, 横竖屏切换时会摧毁Activity重构, 因为要进行屏幕适配.
      R文件下创建布局文件layout-port(竖屏,指定线性布局,垂直)和layout-land(横屏,指定线性布局,水平),横竖屏切换时控件会随之变化
      横竖屏切换和杀死重建文件都需要保存和还原数据:
        onSaveInstanceState()在摧毁时自动执行保存数据---onPause()之后onStop()之前执行(两者之间)
        onRestoreInstanceState()在恢复的时候自动执行还原数据---onStart()之后onResume()之前执行(两者之间)
          被杀死之后再启动才会恢复数据,数据是存在Bundle里的,Bundle是以文件形式存储的,程序再启动时会读取文件,以达到恢复数据的目的
        onSaveInstanceState()在Activity失去焦点时也会被调用, 如果Activity在后台被杀死了, 再次启动时会自动调用onRestoreInstanceState()

    b.如果不需要屏幕适配, 那么可以通过定义属性控制Activity不摧毁重构
      android:configChanges="orientation|screenSize" 这种情况下不执行任何生命周期方法, 也不会改变布局

    c.固定Activity方向---屏幕不随手机转动而改变
      android:screenOrientation="portrait"---固定屏幕方向指定竖屏
      android:screenOrientation="landscape"---固定屏幕方向指定横屏

      android:screenOrientation="sensorLandscape"---两个横屏之间的切换
      android:screenOrientation="Portrait"----两个竖屏之间的切换
      在这种情况下, Activity不会摧毁重构, 也不会改变方向


    d.用代码控制横竖屏的方向---通过点击按钮改变屏幕方向或者获取当前屏幕的方向
      getResources().getConfiguration().orientation
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)---将当前屏幕置为横屏
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)---将当前屏幕置为竖屏

     

     

  • 相关阅读:
    PHP配置redis支持
    redis入门——redis常用命令
    CentOS7 linux下yum安装redis以及使用
    Linux安装配置git
    Java基础88 数据库设计的三大范式
    Java基础87 MySQL数据约束
    Java基础85 MVC开发模式
    错误/异常:java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind;的解决方法
    Java基础84 javaBean规范
    Java基础83 JSP标签及jsp自定义标签(网页知识)
  • 原文地址:https://www.cnblogs.com/myxiaoQ/p/3650064.html
Copyright © 2011-2022 走看看