zoukankan      html  css  js  c++  java
  • Android学习笔记38-Android四大组件之Activity

    Android应用程序的四大组件分别是Activity、Service、BroadcastReceiver和ContentProvider。本文将主要对Activity做一个较全面的总结,Service和BroadcaseReceiver也将在随后的博文中分别进行介绍。有关ContentProvider的使用方法可以参阅博文《Android学习笔记37:使用Content Providers方式共享数据》。

    1.Activity注册

      Activity是Android中最常见的组件,每个Activity都相当于一个屏幕,为用户提供了进行交互的可视化界面。应用程序可以根据需要包含一个或多个Activity,这些Activity都继承自android.app包下的Activity类,并且这些Activity之间的运行是相互独立的。

      应用程序中使用到的所有Activity都需要在AndroidManifest.xml文件中进行注册。注册Activity时,需要使用<Activity></Activity>标签,该标签位于<application></application>中,具体位置如下:

    复制代码
     1   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     2     package="com.example.android_datastorage_sqlite"
     3      android:versionCode="1"
     4      android:versionName="1.0" >
     5   
     6     <application
     7       android:icon="@drawable/ic_launcher"
     8        android:label="@string/app_name"
     9        android:theme="@style/AppTheme">
    10   
    11       <activity
    12               android:name=".MainActivity"
    13               android:label="@string/title_activity_main" >
    14               <intent-filter>
    15                   <action android:name="android.intent.action.MAIN" />
    16                   <category android:name="android.intent.category.LAUNCHER" />
    17               </intent-filter>
    18           </activity>
    19   
    20       </application>
    21   
    22   </manifest>  
    复制代码

    1.1 <Activity>标签的属性值

      在<Activity></Activity>标签中,有以下一些常用的属性值可以设置:

      (1)android:name,该属性值用于表示自定义的Activity子类名称,其值可以是子类的全称类名“com.example.android_datastorage_sqlite.MainActivity”,也可以以“.”开头省略掉应用程序的包名,后面直接加上子类的类名(即“.MainActivity”)。

      (2)android:process,该属性值用于表示Activity组件应该运行在哪个进程中,一般情况下不用设置该属性,所有的组件均运行在同一个进程中。如果该值以“:”开头将会为该Activity创建一个私有的新进程;如果该值以小写字母开头将会创建一个全局的新进程。

      (3)android:permission,该属性值用于指定启动该Activity所必须具有的权限。

      (4)android:screenOrientation,该属性值用于设置屏幕方向,可以选择的设置值有:unspecified(默认值,由系统来选择方向)、landecape(横向显示,宽度比高度大)、portrait(纵向显示,高度比宽度大)、user(使用用户当前首选的方向)、behind(使用与Activity堆栈中该Activity之下的那个Activity相同的方向)、sensor(显示的方向由设备的方向传感器来决定)、nosensor(屏幕的显示方向不会参照物理方向传感器)。

      (5)android:launchMode,该属性值用于设置Activity的启动模式,可以选择的设置值有:standard、singleTop、singleTask、singleInstance。

      (6)android:theme,该属性值用于设置Activity的主题模式。

    1.2 <Activity>标签的内嵌标签

      在<Activity></Activity>标签中,可以内嵌以下两个标签:

      (1)<intent-filter></intent-filter>,该标签指明了Activity组件的过滤规则。

      (2)<meda-data>,该标签指明了额外的提供给Activity组件的数据值。

    1.3不同包下的Activity注册方法

      当应用程序中包含多个Activity,并且这些Activity不在同一个包中时,注册Activity时需要做一点小小的改动。

      比如,在图1所示的工程中包含了3个Activity,且这3个Activity处于不同的包中。

    图1 工程目录结构示意图

      那么,在注册AddDialogActivity和DeleteDialogActivity时,使用上述代码中和注册MainActivity一样的方法是行不通的。因为上述代码指定了package="com.example.android_datastorage_sqlite",所以可以使用android:name=".MainActivity"的方式注册MainActivity。但是很显然,AddDialogActivity和DeleteDialogActivity并不在包"com.example.android_datastorage_sqlite"中,所以我们应当使用android:name=".userOerate.AddDialogActivity"和android:name=".userOerate.DeleteDialogActivity"的方式来注册AddDialogActivity和DeleteDialogActivity组件。

    2.Activity生命周期

      Activity的生命周期包含3个阶段,7个方法。具体可以参阅博文《Android学习笔记04:Activity及Activity生命周期》。这里便不再赘述了。

    3.Activity内容的两种声明方式

      Activity显示内容有两种声明方式,一种是通过xml布局文件来声明,一种是将屏幕设置为某个继承自View类的对象。

    3.1通过xml布局文件声明

      Activity的xml布局文件位于工程的res目录下的layout目录中,一个布局文件就相当于一个View容器,其中可以添加Android系统内置的View(比如Button、TextView等),也可以添加自定义的继承自View类的子类对象,甚至是View容器。

      同时,在xml布局文件还可以指定View对象在View容器中的排列方式(比如线性布局LinearLayout等)。

      通过xml布局文件将不同的View对象整合在一起确实非常方便,但是留给开发人员的自主性却不够。尤其是当进行游戏编程时,往往Android系统中自带的View对象并不能完全满足设计需求。在这种情况下,一般需要通过继承和扩展View类来开发自己想要的用户界面。

    3.2通过View类的子类对象声明

      使用View类的子类对象作为Activity所要显示的内容,可以通过以下的两个步骤来实现:

      (1)编写一个继承自View类的MyView类,在MyView类中需要实现onDraw(Canvas canvas)方法。在该方法中通过操作Canvas对象,完成界面的绘制工作。

      (2)实现了界面的绘制之后,就可以在Activity中通过setContentView(View view)方法加载MyView对象,从而让绘制的界面显示出来。

    以上两个步骤的具体实现方法,可以参阅博文《Android学习笔记09:Paint及Canvas的简单应用》。

    4.Activity之间的通信

      Intent对象是组件之间通信的载体,组件之间进行通信就是一个个Intent对象在不断的传递。Intent对象不仅可以运行在相同的组件之间(如Activity之间的通信),也可以运行在不同的组件之间(如Activity与Service之间的通信)。

      对于Activity组件,Intent主要通过调用Context.startActivity()、Context.startActivityForResult()方法实现传递,其结果是启动一个新的Activity或者使当前的Activity开始新的任务。

      关于如何使用以上两个方法实现Activity之间的通信,可以参阅博文《Android学习笔记33:Intent介绍及Intent在Activity中的使用方法》。

    5.保存Activity临时状态数据

      在Activity中提供了onSaveInstanceState()方法,用于当前Activity在系统未经你许可的情况下(比如处于暂停或停止状态的Activity,在系统资源极度匮乏时,有可能被杀死)被销毁时,对当前Activity中的临时状态数据进行保存。

      使用onSaveInstanceState(Bundle outState)方法,可以在Activity被杀掉之前将Activity的临时状态数据以键值对的形式存放到Bundle对象中,从而能够在再次调用OnCreate()方法时恢复Activity状态。

      如下的代码使用onSaveInstanceState()方法对EditText对象中的输入内容进行了保存,并在OnCreate()方法中对EditText对象中的数据进行了恢复。

    复制代码
     1     EditText mEditText;                            //EditText对象,用于输入内容
     2     private static final String KEY1 = "editTextValues";    //用于保存EditText对象内容的键
     3     private static final String TAG = "MainActivity";        //Log输出过滤器
     4     
     5     /*
     6      * Function  :    onCreate方法,Activity创建时调用
     7      * Author    :    博客园-依旧淡然
     8      */
     9     public void onCreate(Bundle savedInstanceState) {
    10         super.onCreate(savedInstanceState);
    11         setContentView(R.layout.activity_main);
    12         mEditText = (EditText)this.findViewById(R.id.edittext);
    13         
    14         //如果Bundle对象中保存有所需对象的内容,则恢复该对象内容
    15         if((savedInstanceState != null) && savedInstanceState.containsKey(KEY1)) {
    16             mEditText.setText(savedInstanceState.getString(KEY1));
    17         }
    18         Log.i(TAG, "-->onCreate()");
    19     }
    20 
    21     /*
    22      * Function  :    onSaveInstanceState方法,销毁Activity时调用
    23      * Author    :    博客园-依旧淡然
    24      */
    25     protected void onSaveInstanceState(Bundle outState) {
    26         super.onSaveInstanceState(outState);
    27         String editTextValues = mEditText.getText().toString();    //获取EditText对象内容
    28         outState.putString(KEY1, editTextValues);    //以键值对的形式保存EditText对象内容
    29         Log.i(TAG, "-->onSaveInstanceState()");
    30     }
    复制代码

      需要注意的一点是,onSaveInstanceState()方法并不是总会被调用的,只有系统为了节省内存资源而强制销毁Activity时才会调用,所以应当仅仅通过重写onSaveInstanceState()方法来保存一些临时数据,而不是持久数据。要保存持久数据,应该使用onPause()方法。

    6.Activity的主题模式

      上面已经提到,通过设置<Activity></Activity>标签下的android:theme属性值,可以设置Activity的主题模式。

      在Android系统中预设了以下一些主题模式:

      (1)android:theme="@android:style/Theme.Dialog",将一个Activity显示为对话框模式 

      (2)android:theme="@android:style/Theme.NoTitleBar",不显示应用程序标题栏 

      (3)android:theme="@android:style/Theme.NoTitleBar.Fullscreen",不显示应用程序标题栏,且全屏显示该Activity 

      (4)android:theme="@android:style/Theme.Light",将Activity的背景设置为白色 

      (5)android:theme="@android:style/Theme.Light.NoTitleBar",将Activity的背景设置为白色,且不显示应用程序标题栏  

      (6)android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen",将Activity的背景设置为白色,不显示应用程序标题栏,且全屏显示该Activity  

      (7)android:theme="@android:style/Theme.Black",将Activity的背景设置为黑色 

      (8)android:theme="@android:style/Theme.Black.NoTitleBar",将Activity的背景设置为黑色,且不显示应用程序标题栏 

      (9)android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen",将Activity的背景设置为黑色,不显示应用程序标题栏,且全屏显示该Activity 

      (10)android:theme="@android:style/Theme.Wallpaper",以系统桌面做为Activity的背景

      (11)android:theme="@android:style/Theme.Wallpaper.NoTitleBar",以系统桌面做为Activity的背景,且不显示应用程序标题栏 

      (12)android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen",以系统桌面做为Activity的背景,不显示应用程序标题栏,且全屏显示该Activity 

      比如,我们可以通过设置android:theme="@android:style/Theme.Dialog",将一个Activity仿造成对话框Dialog的样子,如图2所示。

    图2 对话框模式的Activity

  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/britalient/p/3173259.html
Copyright © 2011-2022 走看看