学习笔记(二)Activity

来源:互联网 发布:java开源门户网站系统 编辑:程序博客网 时间:2024/06/11 14:34

一. 什么是 Activity(活动)?

  Activity 是 Android 组件中最基本也是最为常见用的四大组件(Activity 活动,Service 服务,Broadcast Receiver 广播接收器,Content Provider 内容提供器)之一。Activity 是一种包含了用户界面的组件,所有操作都与用户密切相关,主要用于和用户进行交互。
  在一个 Android 应用中,一个 Activity 通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity 之间通过 Intent 进行通信。
  所以我认为 Activity 还有一个作用就是传递数据。


二. Activity的创建、加载和注册

  自定义一个 FirstActivity 继承 Activity,通过 XML 文件的方式来编辑布局,然后在onCreate()方法中调用setContentView(R.layout.first_layout)方法来给当前的活动加载布局,并且所有的活动都要在 AndroidManifest.xml中进行注册才能生效。
  活动的注册声明要放在<application>标签内,这里是通过<activity>标签来对活动进行注册的。


三. Intent

  Intent 是 Android 程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以再不同组件之间传递数据。Intent 的用法分为显式 Intent 和隐式 Intent 。

3.1 显式 Intent

  显式 Intent 直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式 Intent 更多用于在应用程序内部传递消息。代码如下:

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

  Intent 的构造函数接受两个参数,第一个参数 Context 要求提供一个启动活动的上下文,第二个参数 Class 则是指定想要启动的目标活动。再将构建好的 Intent 传入 startActivity() 中来启动目标活动。

3.2 隐式 Intent

  相比于显式 Intent,隐式 Intent 则含蓄了许多,由于没有明确的目标组件名称,所以必须由 Android 系统帮助应用程序寻找与 Intent 请求意图最匹配的组件。因此,它更广泛地用于在不同应用程序之间传递消息。
  Android 系统寻找与 Intent 请求意图最匹配的组件具体的选择方法是:Android 将 Intent 的请求内容和一个叫做 Intent-Filter 的过滤器比较,Intent-Filter 中包含系统中所有可能的待选组件。在通过和 Intent-Filter 比较来解析隐式 Intent 请求时,Android 将以下三个因素作为选择的参考标准:Action、Data、Category。Extra 和 Flag 在解析收到 Intent 时是并不起作用的。
  一个没有声明 Intent-Filter 的组件只能响应指明自己名字的显式 Intent 请求,而无法响应隐式 Intent 请求。而一个声明了 Intent-Filter 的组件既可以响应显式 Intent 请求,也可以响应隐式 Intent 请求。


四. 传递数据

  Intent 中提供了一系列的putExtra()方法的重载,可以把我们想要传递的数据暂存在 Intent 中,启动了另一个活动后,再从 Intent 中取出即可。

4.1 向下一个活动传递数据

  先把数据暂存在第一个活动的 Intent 中:

String data = "Hello World!";Intent intent = new Intent(FirstActivity.this,SecondActivity.class);intent.putExtra("extra_data",data);//第一个参数是键,第二个参数是键对应的值,即想要的数据。startActivity(intent);

  再在第二个活动将传递的数据取出并打印信息:

Intent intent = getIntent();String data = intent.getStringExtra("extra_data");//对应头一个活动的键,以此取出值。Log.d("SecondActivity",data);//打印信息。

  这里由于传递的是字符串,所以使用getStringExtra()方法,如果传递的是整型数据,则使用getIntExtra()方法,以此类推。

4.2 返回数据给上一个活动

  在第一个活动中不用startActivity()而是用startActivityForResult()方法来启动第二个活动:

Intent intent = new Intent(FirstActivity.this,SecondActivity.class);startActivityForResult(intent,233);//这里的233是请求码,请求码只要是一个唯一值就可以了,用来判断数据来源。

  接下来在第二个活动中给按钮注册点击事件,并在点击事件中添加可以返回数据的逻辑代码:

Button button2 = (Button) findViewById(R.id.button2);button2.setOnClickListener(new OnClickListener(){    @override    public void onClick(View v){    Intent intent = new Intent();//没有意图仅用于传递数据。    intent.putExtra("data_return","Hello FirstActivity");//把数据放入 Intent中。    setResult(RESULT_OK,intent);//一般只用RESULT_OK和RESULT_CANCELED两个值。    finish();//销毁活动。    }});

  因为使用的是startActivityForResult()方法来启动第二个活动的,在第二个活动被销毁之后会回调第一个活动的onActivityResult()方法:

@overrideprotected void onActivityResult(int requestCode,int resultCode,Intent data){    switch(requestCode){         //requestCode请求码就是上面传入的233。    case 233:        if(resultCode == RESULT_OK){      //resultCode即在返回数据时传入的处理结果。        String returnedData = data.getStringExtra("data_return");        Log.d("FirstActivity",returnedData);        }        break;    default:    }}

  如果在第二个活动中,是按返回键返回的,那么就在第二个活动中重写onBackPressed()方法返回数据,方法同上。


五. 活动的生命周期

5.1 活动状态

  每个活动在其生命周期中拥有四种基本状态:
1. 运行状态 (Active/Running):活动位于返回栈的栈顶。
2. 暂停状态 (Paused):活动不在栈顶位置,但是仍然可见。在系统内存极端低下的时候将被强行终止掉。
3. 停止状态 (Stoped):活动不在栈顶位置,并且完全不可见。当系统内存需要被用在其他地方的时候,停止状态的活动将被强行终止掉。
4. 销毁状态 (Killed):活动从返回栈中移除。系统最倾向于回收处于这种状态的活动,从而保证手机的内存充足。

5.2 活动生存期

  1. 完整生存期:活动在onCreate()onDestroy()之前所经历的。
  2. 可见生存期:活动在onStart()onStop()之前所经历的。
  3. 前台生存期:活动在onResume()onPause()之前所经历的。
    活动生存期

5.3 活动的启动模式

  启动模式一共有四种,可以在<activity>标签中 android:launchMode 定义。
1. standard:默认启动方式,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。
2. singleTop:在启动活动时检查栈顶是否已经存在该活动,存在的话系统就认为可以直接使用,不创建新的实例。不过当活动并未处于栈顶位置时,这时再启动改活动,还是会创建新的实例。
3. singleTask:启动活动时系统会检查整个返回栈是否存在该活动的实例,如果存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈。没有的话会新建。
4. singleInstance: 系统会启用一个新的返回栈(或 Task )来管理这个活动,该活动与其他活动不在同一个 Task 中,其他程序也可以调用这个活动的实例。


六. 活动的最佳实践

6.1 知晓当前页面是哪一个活动

  新建一个 BaseActivity 继承 Activity,然后在 BaseActivity 中重写onCreate()方法:

@overrideprotected void onCreate(Bundle saveInstanceState){    super.onCreate(saveInstanceState);    Log.d("BaseActivity",getClass().getSimpleName()); //获得类名    }

然后,所有让所有的活动都继承 BaseActivity,查看 LogCat 中的打印信息。现在每当我们进入到一个活动的界面,该活动的类名就会被打印出来。

6.2 随时随地退出程序

  当打开很多活动之后,退出程序需要一直按 Back,很麻烦。这时候只需要用一个专门的 ActivityColletor 集合类对所有的活动进行管理,创建静态变量和静态方法来实现所有的活动的add()remove()finish()

6.3 启动活动的最佳写法

  比如我需要启动一个 SecondActivity,可是不知道该活动需要哪些参数,怎么办?在 SecondActivity 中添加一个启动自己的方法:

public class SecondActivity extends Activity{    ...    public static void startActivity(Context contex, String data1, String data2){        Intent intent = new Intent(context, SecondActicity.class);        intent.putExtra("param1", data1);        intent.putExtra("param2", data2);        startActivity(intent);    }     ...} 

  在 SecondActivity 中添加了 startActivity()方法之后,在任意的 activity 中启动 SecondActivity,都可以调用该方法,而且知道需要传入哪些参数。
  比如在 MainActivity 中启动方法为:

SecondActivity.startActivity(MainActivity.this, "data1", "data2");

  养成一个良好的习惯,给自己编写的每个活动都添加类似的启动方法。

0 0
原创粉丝点击