Android 组件 — Activity (创建与启动)

Android Activity

Activity 简介

 Activity 是应用程序的四大组件之一,为用户提供一个交互界面,比如打电话、发短信、发送邮件等。每一个Activity都会提供一个窗口用于绘制用户界面。通常窗口都是全屏,但是也可以浮在其他的窗口之上。

 app一般由一个或者多个Activity松散耦合在一起。最常见的情况是,一个Activity被指定为“mian”Activity,作为用户启动app时最先进入的界面。Activity可以启动其他的Activity界面来满足不同德操作。每次开启一个新的Activity时会先关闭当前的Activity,然后将其保存在“Back Stack”(类似先进后出的栈结构),默认情况下,被关闭的Activity会被放在Back Stack中,当用户按下返回键时,以前的Activity会从栈顶弹出并获得用户的焦点。(关于Back Stack的部分会在Tasks and Back Stack文档中详细讨论)

 当一个Activity因为新开启一个Activity是被关闭,他会将Activity状态的变化通知Activity的“生命周期回调”方法。Activity的生命周期被分为几个状态:creation、started、stopped、pause、resume、destroy,每个状态会对应一个回调方法。系统会在Activity状态发生改变的时候回调这些方法,这样你就有机会指定一些适当的代码。举个例子,当你关闭一个Activity的时候你必须释放一些太好内存的对象,比如网络、数据库连接等。当Activity恢复时,你可以再次申请那些必要的资源来恢复之前被中断的操作。

 这篇文章剩余的部分会讨论如何创建和使用一个Activity,包括Activity生命周期的状态切换,以及如何处理状态的变换。

Activity的创建


 

 首先你需要创建一个子类来继承Activity。在子类中需要实现回调方法以提供给系统在不同的状态下调用,其中最重要的两个回调函数如下:

onCreate()
这个方法你必须实现。系统在Activity被创建的时候会调用此方法。在此方法中你应用初始化Activity必须用到的资源。最终要的时候你需要调用 setContentView()设置Layout文件来填充你的用户界面。
onPause()
当用户离开当前的界面时会调用此方法,虽然不一定会终止Activity,但是有可能此界面不会在恢复,所以你需要保存一些用户的设置,以保证用户的设置生效。

 还有一些其他的生命周期回调方法,你应该合理的运用这些回调方法,保证在正不同Activity切换和Activity被异常中断的情况下仍然有一个流畅的用户体验,稍后会在Managing the Activity Lifecycle 一节中详细的讨论所有的回调方法。

实现用户界面

 一个用户界面由不同级别的视图(view)组成—view是继承于View类的对象。每一个视图都控制者Activity窗口中的一个矩形区域,而且可以与用户交互。举个例子,一个视图可能是一个按钮,当用户点击时可以触发某个操作。

 Android 提供了许多现成的视图(view),你可以用来设计和组织你layout(布局)。“Widgets”是view的别称,它提供了一个在屏幕可视化的元素,比如一个按钮(button)、文本框(Text filed)、单选框(checkbox)、或者仅仅是一副图像(image)。“Layout”继承于ViewGroup,为view提供了一个特有的布局模型,比如线性布局(LinearLayout)、网格布局(grid Layout)、相对布局(relative Layout)。当然,你也可以直接继承 View 和ViewGroup 类来创建自己的widget和layout,然后应用到Activity的布局中。

 一般会在app的资源文件中定义一个XML Layout文件。通过这个方法,你可以将Activity的行为与用户的界面分开维护。每一个布局文件都有一个ID,你可以调用setContentView(layout ID)方法为你的Activity设置布局文件,你也可以在代码中(分级式地)创建view并插入到ViewGroup中,然后将ViewGroup作为layout参数传递给setContentView()

 要知道如何创建用户界面可以参照 User Interface

 在AndroidManifest.xml中声明Activity

为了保证系统能够访问你的Activity,你需要在AndroidManifest.xml文件中进行声明。声明方式如下:打开工程目中的AndroidManifest.xml文件,在<application>元素中添加一个子元素<activity>:

<manifest ... > 
  <application ... > 
      <activity android:name=".ExampleActivity" /> 
      ... 
  </application ... > 
  ... 
</manifest >

<activity>元素下还可以增加其他属性,比如增加一个标签、定义Activity的风格或主题。android:name属性是必须设置的,它指明了Activity的类名。一旦你发布app,你的类名就不能随意的更改,否则会破坏一些功能,比如已经创建好的app快捷方式,如果你更改了android:name,快捷方式就会失效。(read the blog post, Things That Cannot Change).

 参考 <activity> 可以获得更详细的信息。

“intent filter”的使用

 AndroidManifest.xml文件中,为了方便其他的app能够激活你的activity,可以在<activity>增加<intent-filter>元素。

 当你用Android SDK tools创建一个app时,它会自动为你创建一个放在“launcher” 类中的activity的存根,以便响应“main”action,inten filter的使用方式如下:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> 
    <intent-filter> 
        <action android:name="android.intent.action.MAIN" /> 
        <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity>


<action>标识了app的“main”入口,<category>表示activity会被放在系统的ApplicationLauncher中,以便用户启动(launch)这个activity。

如果你打算只在当前app中使用该activity,而且不允许其他app激活该activity,那你就不需要任何intent filter。如同上面的例子,只能有一个activity的intent filter 能用户“main”action和“launcher”category。你不需要其他app访问的activity则不需要声明intent filter,该activity所在的app只需要指定activity类名就可以启动了。

<intent-filter>下也可以增加<category> 和<data>元素。这些元素可以指定你的activity可以响应的intent类型。想了解更多关于activity响应intent的方式,可以参考Intents and Intent Filters

 启动Activity


你可以调用startActivity((Intent intent, Bundle options))来启动其他的Activity,intent用于描述想要启动的Activity。intent可以是明确指定启动的Activity类名,或者描述你要启动的动作(系统会根据你的描述为你选择一个合适的Activity,甚至从不同app查找也是有可能的)。intent也可以携带少量的数据传递给需要启动的Activity。

 在Activity内部启动当前app中的其他Activity可以直接在intent中指定类名,方式如下:

Intent intent = new Intent(this, SignInActivity.class); 
startActivity(intent);

然而,你的app执行的某些操作,比如打电话、发短信、查看地图,但是你的app可能没有完成这些功能的Activity,这个时候你可以利用设备上其他具备这些功能的Activity来完成这些操作。intent真正的价值在于,你只需要描述你想要做的操作,系统会自动为你匹配合适的Activity,如果存在相同功能的Activity的时候,会再提示用户选择。举个例子,如果你允许用户发邮件,你可以像下面这样创建一个intent:

Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); 
startActivity(intent);

putExtra中recipientArray是一个email 地址的字符串,当带有email功能的app响应这个intent的时候,它会解析recipientArray中的内容然后放到收件人的地址栏里。这种情况下,email 发送后会再恢复你之前的Activity。 

Activity 的反馈机制

 有时候,你可能希望启动的Activity完成操作后能回传数据。这种情况下,你可以调用startActivityForResult()来启动Activity(而不是调用startActivity())。为了能接收Activity处理的结果,你需要实现回调方法:onActivityResult()。当被启动的Activity推出后会返回一个intent给onActivityResult()

 举个例子,可能你想要用户选择一个联系人,然后你的Activity就可以使用联系人信息做一些事情。上代码:

private void pickContact() { 
    // Create an intent to "pick" a contact, as defined by the content provider URI 
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); 
    startActivityForResult(intent, PICK_CONTACT_REQUEST); 
} 
 
@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST 
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { 
        // Perform a query to the contact's content provider for the contact's name 
        Cursor cursor = getContentResolver().query(data.getData(), 
        new String[] {Contacts.DISPLAY_NAME}, null, null, null); 
        if (cursor.moveToFirst()) { // True if the cursor is not empty 
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); 
            String name = cursor.getString(columnIndex); 
            // Do something with the selected contact's name... 
        } 
    } 
}

这个例子展示了最基本的onActivityResult()用法。返回的数据通过ContentResolver 查询到contact的Cursor。更详细的信息可以参考Content Providers

转载请注明出处:http://blog.youkuaiyun.com/jack_chen_00/article/details/9771569

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值