android学习手记第一章--activity From 11 Mar to 15 Mar,2011

 

一 Activities

这个东东相当于一个屏幕,你也可以理解成一个窗口,反正你就能在它上面操作,不管你是用它来发邮件还是打电话,这个东西会充满整个屏幕,就算窗口尺寸比屏幕小,它也会满屏的漂浮在窗口的最顶层。

一个程序可能有多个activities,但是一定要有一个是“mainactivities,程序一旦运行起来,就首先加载这个main。每个activities又可以加载其他activities,每次启动新的activities,前面一个将被放到所谓的“后台堆栈”,这些后台堆栈遵循“后进先出”的原则,所以当你按back键的时候,你看到的是上一屏,也就是上一个activities

当一个新的activities启动而旧的activities被停止的时候,有个叫callback的方法会放到这个activities的状态里面。有好几种callback的方法,在于你赋予什么属性给它,当你使用stop的时候,很多对象将会释放,例如网络或者数据库连接等等,如果仅仅是resume,你还可以继续在这个activities里面查询你需要的东西。看得不太明白,以后再说。

1.1创建一个activities

要创建一个activities,你必须是创建一个Activities子类,或者其他Activities子类的子类,也就是孙子类?你的activities必须实现callback方法,系统才能在它的生命周期中调用它的时候才知道到底要干吗,例如停止它,创建它,摧毁它还是怎么着。其中有两个最重要的方法:

onCreate()

你必须实现这个方法,系统靠它来启动创建activity。在实现这个方法的过程中,你必须初始化一些基本的组件。特别重要的是,你必须调用setContentView()来定义你的UI布局。

onPause()

系统在用户离开这个activity的时候调用这个方法,这个一般是在你还需要上一个用户session的时候使用的。

还有很多种callback的方法来实现你不同的需要,这些我们晚点再讨论。

1.1.1实现一个用户界面

一个activity的用户界面由Views的派生对象hierarchy提供。每个view控件控制一个特殊的长方形空间,并可以对用户动作作出反应。例如,某个view控件包含一个按钮,当用户触发这个按钮的时候就可以初始化某行为。

Android提供很多可视views控件供你设计的时候选择,这些玩意都放在了Widgets面板下,例如按钮,文本输入框,选择框等等。Layouts是另外一个views,它由ViewGroup派生出来,它提供特殊的架构模型,例如线性的布局,表格性的布局等。你也可以在View或者ViewGroup下构建属于你自己的子类,以方便你以后的使用。

最常用的办法就是使用你程序源代码下面的xml文件来定义你的布局。这样,你就可以自由的修改你的用户布局,而不影响activity的行为。也就是所谓的分层吧。你还可以通过setContentView的方法来使用你的布局作为用户界面。当然,你还可以在ViewGroup下插入新的Views代码,然后使用setContentView的办法来调用。更多的内容请查看User Interface那章。

1.1.2 manifest下面声明activity

你必须在manifest下面声明你的activity。方法很简单,打开你的manifest然后在<application>元素下加入一个<activity>子元素。

 

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

在这里你还可以定义activity的很多属性,例如标签,icon,主题。更多的内容请参阅<activity>参考资料。

1.1.3 使用intent filters

一个<activity>元素可以通过定以<intent-filter>元素来指定多种intent filters,这样就声明了其他程序组件将通过什么方式激活这个activity

当你使用android sdk工具来创建一个新的activity,它将自动生成一个intent filter,并声明通过main动作激活它,而这个filter必须在LAUCHER目录下。例如:

<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>

上述代码表明,这个activity是程序的main的启动点,同时,<category>元素指定这个activty应该在应用的launcher下,也就是允许用户调用的activity

如果你希望你的activity仅仅是本程序可以访问,不允许其他程序访问,你不需要做任何的修改,如果你希望你的activity对其他应用作出反应,你就需要增加新的intent filters

2011-3-14

1.2启动一个activity

你可以调用startActivity()来启动一个新的activity,通过Intent来定义你要启动的activityIntent会指定准确的activity你希望启动或者描述。在启动的时候一个intent还可以传递少量的数据。

下面的代码简单的告诉你如何启动一个名叫SignInActivity

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

然而,你的应用可能需要实现一个动作,比如发送一封邮件,一条短信,或者调用一些activity的数据。在这情况下,你的activity不一定需要属于自己的行为来实现这些动作,你可以调用设备上的其他应用程序来实现这些动作。这就是intent的价值所在,你可以通过它调用任意一个外部应用程序的activity。如果有多个activity可以处理你的intent,用户可以自由选择。下面代码展示如果发送邮件

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

上述代码说明,EXTRA_EMAIL是一串收件人的地址数组,当一个发送邮件程序回应这个intent的时候,自动读取到收件人数组并放到收件人栏,流程大概这样,发送邮件程序的activity启动并完成发送动作后,你的activity被重新调用放到前台来。

 

1.3 获取activity运算结果

如果你想得到一个activity的运算结果,你就是用startActivityForResult(),而不是使用startActivity()。使用onActivityReult()callback方法去获取子activity的结果的时候,结果会保存在一个intent里面并传给你的onActivityResult()方法。

比如,你希望用户从他的电话簿里面选择一个联系人出来干点什么事情….

private void pickContact() {
   
// 创建一个新的intent,以便选择联系人,CONTENT_URIandroid共享平台的数据方法
   
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) {
   
//逻辑判断:如果请求顺利并且请求是PICK_CONTACT_REQUEST
   
if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
       
// 按联系人姓名执行查询
       
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);
           
// 给选中的联系人干点啥...
       
}
   
}
}

上述代码展示如何使用onActivityResult()来处理activity结果的最基本逻辑。首先是根据resultCode来判断request请求是否成功,然后再判断requstCodes是否符合startActivityForResult()的第二个参数,在这个例子里面,查询的结果返回intent里面来,也就是data的参数。后面就是指针去定位数据完全操作等,不赘述。

 

1.4 关闭一个activity

你可以调用finish()方法来关闭一个activity,也可以使用finshiActivity的方法关闭一个之前打开的activity

注意:很多时候,你不需要用这个办法来关闭你的activity。正如前面所述,android平台会自动管理你的activity的生命周期。除非你肯定不需要你的用户使用这个activity,要不使用这个办法来关闭activity会大大的伤害用户的体验。

 

1.5 管理activity的生命周期

使用callback的办法来管理你的activty的生命周期可以构造出强大的、灵活的应用程序。一个activity的生命周期和其他调用它的activity息息相关。

一个activity可以表现成如下三种状态:

Resumed可以理解成正在运行状态,处在屏幕的最前端并处在用户焦点内。

Paused其他activity正处在运行的状态,但是这个activity还是可见的状态。也就是说其他activity在它之上,它变得部分透明或者不能覆盖整个屏幕,一个Pausedactivity还处在内存中的活动状态,而且在window manager可见,但是如果系统内存严重不足的时候,会被干掉。

Stopped这个activity已经彻底的不可见,转到后台运行。这个状态下它还会保留在内存中,但是在window manager中不可见了。当系统需要新的内存的时候它将会被干掉。

当一个activity处在Paused或者Stopped的状态,系统可以随时干掉它,也就是finish()方法所干的一样,如果你还需要它的时候,你就必须再次启动它。

1.5.1 实现生命周期的回调

当一个activity是上述状态的时候,你可以使用很多种办法回调它。下面的代码将展示如何实现回调的方法

public class ExampleActivity extends Activity {
   
@Override
   
public void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
// activity开始创建
   
}
   
@Override
   
protected void onStart() {
       
super.onStart();
       
//activity准备处在可见状态.
   
}
   
@Override
   
protected void onResume() {
       
super.onResume();
       
// activity已经可见 (处在resumed状态).
   
}
   
@Override
   
protected void onPause() {
       
super.onPause();
       
// 其他activity开始可见(这个activity变成了paused状态).
   
}
   
@Override
   
protected void onStop() {
       
super.onStop();
       
// activity不再可见(处在stopped状态)
   
}
   
@Override
   
protected void onDestroy() {
       
super.onDestroy();
       
//activity不再存在
   
}
}

请注意,你每次使用callback方法前,你都需要重新实现父类。

2011-3-15

如上,你可以观察到一个activity的生命周期的嵌套循环过程。

·整个生命周期:从onCreate()开始到onDestory()结束。前者是所有线程的开始,后者是所有线程的释放。

·可视化状态生命周期:从onStart()开始到onStop()结束。这个状态中,用户可以看到这个activty并且可以与之交户。

·foreground lifetime ,可以理解成在前景状态。从onResume开始到onPause结束,这个状态期间,activity在所有屏幕的前端,并且获得用户焦点。一个activity可以频繁的变换其foreground状态。由于需要频繁转换,调用这两个方法的代码必须是轻量级的。

下面的图片将会说明一个activity的不同状态和调用方法等关系,并说明不同状态的之间。

 

 

 

1.6 保存activity的状态

在前面的介绍中,我们说过activity的如果改到了paused或者stopped的状态的时候,它还是继续保留在内存中。当你使用resume方法调出的时候,用户曾经做过的修改等都还保存在内存里面。

然而,当系统需要更多的内存来运作其他东西的时候,系统会选择干掉你的activity,也就是所谓的destroyed,你就不能resume它了。如果这时候用户使用back按钮回调这个activity的时候,系统只能重新创建它了,但是用户不知道这样的机制,他们还以为之前操作过的东西都还在呢。所以,你必须保留在系统干掉你的activity之前就保存一些重要的信息,以便下次系统重新创建它的时候可以修复回去。

Callback方法里面,你可以使用onSaveInstanceState()的办法来保存你activity的信息。如果你使用了这个办法,系统在干掉你的activity之前会把它保存成一个Bundle对象。你就可以使用这个对象和putString方法来修复你的数据了。

注意:没有人担保系统在干掉activity之前一定会调用这个onSaveInstanceState()来保存你的数据。

 

1.7 处理配置的改变

在你的activity运行期间,一些设备上的配置可能会发生改变,这个时候,android系统自动的重新启动你的activity(先是onDestroy,然后再onCreate),这样你的程序就可以自动适应新的配置。

为了使你的程序可以自动适应新的配置,最好的办法就是用之前办法,先onSaveInstanceState然后再onCreate

 

1.8 协调多个activity

当多个activity开始启动的时候,我们需要了解他们的运行机制。下面我们把这些顺利理一下:

A) activity A onPaused

B) activity B 马上开始执行onCreate或者onStart

C) 当这个activity不再需要的时候,开始执行onStop方法。

根据上述机制,你就可以轻松的掌握如何把数据从一个activity传递到下一个activity。比如,你想把数据写到数据库里面,让下一个activity可以使用它的时候,你就需要使用onPause方法而不是使用onStop方法。See

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值