一、Activity 简介

在android开发中Activity非常重要,在一个应用中,每一个显示的屏幕都是一个Activity.所以学习android,必须要对Activity有一定的了解.
activity类处于android.app包中,继承体系如下:
1.java.lang.Object
2.android.content.Context
3.android.app.ApplicationContext
4.android.app.Activity

activity是单独的,用于处理用户操作。几乎所有的activity都要和用户打交道,所以activity类创建了一个窗口,开发人员可以通过setContentView(View)接口把UI放到activity创建的窗口上,当activity指向全屏窗口时,也可以用其他方式实现:作为漂浮窗口(通过windowIsFloating的主题集合),或者嵌入到其他的activity(使用ActivityGroup)。大部分的Activity子类都需要实现以下两个接口:
onCreate(Bundle)接口是初始化activity的地方. 在这儿通常可以调用setContentView(int)设置在资源文件中定义的UI, 使用findViewById(int) 可以获得UI中定义的窗口.
onPause()接口是使用者准备离开activity的地方,在这儿,任何的修改都应该被提交(通常用于ContentProvider保存数据).
为了能够使用Context.startActivity(),所有的activity类都必须在AndroidManifest.xml文件中定义有相关的“activity”项。

activity类是Android 应用生命周期的重要部分。

简单的例子:

/Chapter05_Activity_Creation/src/com/amaker/test/MainActivity.java

        
  1. 代码
  2. packagecom.amaker.test;
  3. importandroid.app.Activity;
  4. importandroid.os.Bundle;
  5. importandroid.widget.Button;
  6. importandroid.widget.TextView;
  7. //继承Activity
  8. publicclassMainActivityextendsActivity{
  9. //声明要使用的组件
  10. privateTextViewmyTextView;
  11. privateButtonmyButton;
  12. //覆盖onCreate方法
  13. publicvoidonCreate(BundlesavedInstanceState){
  14. super.onCreate(savedInstanceState);
  15. //设置当前视图
  16. setContentView(R.layout.main);
  17. //通过findViewById() 方法实例化组件
  18. myTextView=(TextView)findViewById(R.id.TextView01);
  19. myButton=(Button)findViewById(R.id.Button01);
  20. }
  21. }

布局文件

/Chapter05_Activity_Creation/res/layout/main.xml

        
  1. 代码
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. >
  8. <TextViewandroid:id="@+id/TextView01"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:text="简单的Activity"></TextView>
  12. <Buttonandroid:text="ClickMe!"
  13. android:id="@+id/Button01"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"></Button>
  16. </LinearLayout>

清单文件

/Chapter05_Activity_Creation/AndroidManifest.xml

        
  1. 代码
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  4. package="com.amaker.test"
  5. android:versionCode="1"
  6. android:versionName="1.0">
  7. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  8. <activityandroid:name=".MainActivity"
  9. android:label="@string/app_name">
  10. <intent-filter>
  11. <actionandroid:name="android.intent.action.MAIN"/>
  12. <categoryandroid:name="android.intent.category.LAUNCHER"/>
  13. </intent-filter>
  14. </activity>
  15. </application>
  16. <uses-sdkandroid:minSdkVersion="3"/>
  17. </manifest>

二、启动一个Activity

一个activity可以启动另外一个,甚至包括与它不处于同一应用程序之中的。举个例子说,假设你想让用户看到某个地方的街道地图。而已经存在一个具有此功能的activity了,那么你的activity所需要做的工作就是把请求信息放到一个Intent对象里面,并把它传递给startActivity()。于是地图浏览器就会显示那个地图。而当用户按下BACK键的时候,你的activity又会再一次的显示在屏幕上。

Android将这两个activity放在同一个任务中来维持一个完整的用户体验。简单的说,任务就是用户所体验到的应用程序。它是安排在一个堆栈中的一组相关的activity。堆栈中的根activity就是启动了这整个任务的那个──一般情况下,它就是用户在应用程序加载器中所选择的。而堆栈最上方的activity则是当前运行的──用户直接对其进行操作的。当一个activity启动另外一个的时候,新的activity就被压入堆栈,并成为当前运行的activity。而前一个activity仍保持在堆栈之中。当用户按下BACK键的时候,当前activity出栈,而前一个恢复为当前运行的activity

activity相当于web开发中的页面,从一个页面跳转到另外的一个页面。

小例子:

/Chapter05_Activity_StartActivity/src/com/amaker/test/FirstActivity.java

        
  1. 代码
  2. packagecom.amaker.test;
  3. importandroid.app.Activity;
  4. importandroid.content.Intent;
  5. importandroid.os.Bundle;
  6. importandroid.view.View;
  7. importandroid.view.View.OnClickListener;
  8. importandroid.widget.Button;
  9. publicclassFirstActivityextendsActivity{
  10. /**Calledwhentheactivityisfirstcreated.*/
  11. privateButtonb1;
  12. @Override
  13. publicvoidonCreate(BundlesavedInstanceState){
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.first);
  16. b1=(Button)findViewById(R.id.Button01);
  17. //响应按键事件
  18. b1.setOnClickListener(newOnClickListener(){
  19. @Override
  20. publicvoidonClick(Viewv){
  21. //显示方式声明Intent,直接启动SecondActivity
  22. Intentintent=newIntent(FirstActivity.this,SecondActivity.class);
  23. startActivity(intent);
  24. }
  25. });
  26. }
  27. }

/Chapter05_Activity_StartActivity/src/com/amaker/test/SecondActivity.java

        
  1. 代码
  2. packagecom.amaker.test;
  3. importandroid.app.Activity;
  4. importandroid.content.Intent;
  5. importandroid.os.Bundle;
  6. importandroid.view.View;
  7. importandroid.view.View.OnClickListener;
  8. importandroid.widget.Button;
  9. publicclassSecondActivityextendsActivity{
  10. /**Calledwhentheactivityisfirstcreated.*/
  11. privateButtonb2;
  12. @Override
  13. publicvoidonCreate(BundlesavedInstanceState){
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.second);
  16. b2=(Button)findViewById(R.id.Button02);
  17. //响应按键事件
  18. b2.setOnClickListener(newOnClickListener(){
  19. @Override
  20. publicvoidonClick(Viewv){
  21. //显示方式声明Intent,直接启动SecondActivity
  22. Intentintent=newIntent(SecondActivity.this,FirstActivity.class);
  23. startActivity(intent);
  24. }
  25. });
  26. }
  27. }

布局文件

/Chapter05_Activity_StartActivity/res/layout/first.xml

        
  1. 代码
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. >
  8. <Buttonandroid:id="@+id/Button01"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:text="SecondActivity"></Button>
  12. </LinearLayout>

/Chapter05_Activity_StartActivity/res/layout/second.xml

        
  1. 代码
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <Buttonandroid:id="@+id/Button02"
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. android:text="返回"></Button>
  10. </LinearLayout>

三、Activity之间传递数据

如何在Activity中调用另一个Activity,但若需要在调用另外一个Activity的同时传递数据,那么就需要 利用android.os.Bundle对象封装数据的能力,将欲传递的数据或参数,通过Bundle来传递不同Intent之间的数据。 相当于web开发中用session等等进行参数传递一样。

利用Intent传递数据

传递数据的Activity中:

Intent intent = new Intent();
intent.putExtra("name","Jon");//在Intent中加入键值对数据。键:name,值:Jon
intent.setClass(Activity01.this,Activity02.class);
Activity01.this.startActivity(intent);

在取出数据的Activity中:

Intent intent = getIntent();//获得传过来的Intent。
String value = intent.getStringExtra("name");//根据键name取出值。

利用Bundle传递数据

传递数据的Activity:

Intent intent = new Intent();
Bundle myBundle = new Bundle();
myBundle.putString("Key_Name","Tom");
intent.putExtras(myBundle);
intent.setClass(Activity01.this,Activity02.class);
Activity01.this.startActivity(intent);

取出数据的Activity:

Bundle getBundle = getIntent().getExtras();
String value = getBundle.getString("Key_Name");

利用startActivityForResult传递数据

startActivityForResult可以把数据传过去,还可以把那边的数据传过来。

传递数据的Activity中:

Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("data", "somedata");//把数据传过去
intent.putExtras(bundle);
intent.setClass(Activity01.this, Activity02.class);
startActivityForResult(intent, 10);//10是一个代码

重载onActivityResult方法,用来接收传过来的数据:

protected void onActivityResult(int requestCode, int resultCode,Intent intent) {
switch (resultCode) {
case RESULT_OK:
Bundle b = intent.getExtras();
String str = b.getString("Result");
setTitle("Return data:" + str);
break;
default:
break;
}
}

接收数据的Activity:

Intent intent = getIntent();
Bundle getBundle = getIntent().getExtras();
String data = getBundle.getString("data");//读取传过来的数据
et.setText(data);

EditText edittext = (EditText) findViewById(R.id.text);
Intent intent = new Intent();//实例化一个Intent用来传过去,可以在Intent里存放数据。
Bundle bundle = new Bundle();
bundle.putString("Result",edittext.getText().toString());
intent.putExtras(bundle);
Activity02.this.setResult(RESULT_OK,intent);//把Intent(数据)传过去,RESULT_OK是请求码。
finish();//结束当前的Activity。

四、启动一个Activity并返回结果

使用startActivityForResult()方法

实例:

/Chapter05_Activity_StartActivityForResult/src/com/amaker/test/MainActivity.java

        
  1. 代码
  2. packagecom.amaker.test;
  3. importandroid.app.Activity;
  4. importandroid.content.Intent;
  5. importandroid.os.Bundle;
  6. importandroid.util.Log;
  7. importandroid.view.View;
  8. importandroid.view.View.OnClickListener;
  9. importandroid.widget.Button;
  10. importandroid.widget.EditText;
  11. publicclassMainActivityextendsActivity{
  12. privateEditTextusername,password;
  13. privateButtonb1;
  14. @Override
  15. publicvoidonCreate(BundlesavedInstanceState){
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.main);
  18. b1=(Button)findViewById(R.id.Button01);
  19. b1.setOnClickListener(newOnClickListener(){
  20. @Override
  21. publicvoidonClick(Viewv){
  22. username=(EditText)findViewById(R.id.username);
  23. password=(EditText)findViewById(R.id.password);
  24. Stringstr_username=username.getText().toString();
  25. Stringstr_password=password.getText().toString();
  26. Bundleb=newBundle();
  27. b.putString("username",str_username);
  28. b.putString("password",str_password);
  29. Intentintent=newIntent(MainActivity.this,NextActivity.class);
  30. intent.putExtras(b);
  31. startActivityForResult(intent,1);
  32. }
  33. });
  34. }
  35. @Override
  36. protectedvoidonActivityResult(
  37. intrequestCode,intresultCode,Intentdata){
  38. Log.i("requestcode",requestCode+"-----------");
  39. Log.i("resultCode",resultCode+"-----------");
  40. Bundleb=data.getExtras();
  41. Stringstr_username=b.getString("username");
  42. Stringstr_password=b.getString("password");
  43. System.out.println(str_username);
  44. Log.i("abc",data.getStringExtra("abc"));
  45. username.setText(str_username);
  46. password.setText(str_password);
  47. }
  48. }

/Chapter05_Activity_StartActivityForResult/src/com/amaker/test/NextActivity.java

        
  1. 代码
  2. packagecom.amaker.test;
  3. importandroid.app.Activity;
  4. importandroid.content.Intent;
  5. importandroid.os.Bundle;
  6. importandroid.view.View;
  7. importandroid.view.View.OnClickListener;
  8. importandroid.widget.Button;
  9. publicclassNextActivityextendsActivity{
  10. privateButtonb2;
  11. @Override
  12. protectedvoidonCreate(BundlesavedInstanceState){
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.next);
  15. b2=(Button)findViewById(R.id.Button02);
  16. b2.setOnClickListener(newOnClickListener(){
  17. @Override
  18. publicvoidonClick(Viewv){
  19. Intentintent=getIntent();
  20. intent.putExtra("abc","test");
  21. NextActivity.this.setResult(5,intent);
  22. NextActivity.this.finish();
  23. }
  24. });
  25. }
  26. }

/Chapter05_Activity_StartActivityForResult/res/layout/main.xml

        
  1. 代码
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. >
  8. <TextView
  9. android:text="用户名称:"
  10. android:id="@+id/TextView01"
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"></TextView>
  13. <EditText
  14. android:text=""
  15. android:id="@+id/username"
  16. android:layout_width="fill_parent"
  17. android:layout_height="wrap_content"></EditText>
  18. <TextView
  19. android:text="用户密码:"
  20. android:id="@+id/TextView02"
  21. android:layout_width="wrap_content"
  22. android:layout_height="wrap_content"
  23. ></TextView>
  24. <EditText
  25. android:text=""
  26. android:id="@+id/password"
  27. android:layout_width="fill_parent"
  28. android:layout_height="wrap_content"
  29. android:password="true"
  30. ></EditText>
  31. <Button
  32. android:text="下一步"
  33. android:id="@+id/Button01"
  34. android:layout_width="wrap_content"
  35. android:layout_height="wrap_content"></Button>
  36. </LinearLayout>

/Chapter05_Activity_StartActivityForResult/res/layout/next.xml

        
  1. 代码
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. >
  8. <TextView
  9. android:text="Email:"
  10. android:id="@+id/email"
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"></TextView>
  13. <EditText
  14. android:text=""
  15. android:id="@+id/EditText01"
  16. android:layout_width="fill_parent"
  17. android:layout_height="wrap_content"></EditText>
  18. <TextView
  19. android:text="Mobile:"
  20. android:id="@+id/mobile"
  21. android:layout_width="wrap_content"
  22. android:layout_height="wrap_content"></TextView>
  23. <EditText
  24. android:text=""
  25. android:id="@+id/EditText02"
  26. android:layout_width="fill_parent"
  27. android:layout_height="wrap_content"></EditText>
  28. <Button
  29. android:text="上一步"
  30. android:id="@+id/Button02"
  31. android:layout_width="wrap_content"
  32. android:layout_height="wrap_content"></Button>
  33. </LinearLayout>

五、Activity的生命周期

和其他手机平台的应用程序一样,Android的应用程序的生命周期是被统一掌控 的,也
就是说我们写的应用程序命运掌握在别人(系统)的手里,我们不能改变它,只能学习并
适应它。

简单地说一下为什么是这样:我们手机在运行一个应用程序的时候,有可能打进来电话
发进来短信,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能,另
外系统也不允许你占用太多资源,至少要保证电话功能吧,所以资源不足的时候也就有可

能被干掉。

言归正传,Activity的基本生命周期如下代码所示:

  1. public class MyActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState);
  3. protected void onStart();
  4. protected void onResume();
  5. protected void onPause();
  6. protected void onStop();
  7. protected void onDestroy();
  8. }
 public class MyActivity extends Activity {     protected void onCreate(Bundle savedInstanceState);     protected void onStart();     protected void onResume();     protected void onPause();     protected void onStop();     protected void onDestroy();   } 

你自己写的Activity会按需要 重载这些方法,onCreate是免不了的,在一个Activity正常启动的过程中,他们被调用的顺序是 onCreate -> onStart -> onResume, 在Activity被干掉的时候顺序是onPause -> onStop -> onDestroy ,这样就是一个完整的生命周期,但是有人问了 ,程序正运行着呢来电话了,这个程序咋办?中止了呗,如果中止的时候新出的一个Activity是全屏的那么:onPause->onStop ,恢复的时候onStart->onResume ,如果打断 这个应用程序的是一个Theme为Translucent 或者Dialog 的Activity那么只是onPause ,恢复 的时候onResume

详细介绍一下这几个方法中系统在做什么以及我们应该做什么:

onCreate: 在这里创建界面,做一些数据的初始化工作

onStart: 到这一步变成用户可见不可交互

onResume: 变成和用户可交互 的,(在activity栈系统通过栈的方式管理这些个
Activity的最上面,运行完弹出栈,则回到上一个Activity)

onPause: 到这一步是可见但不可交互 的,系统会停止动画等消耗CPU 的事情
从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候
你的程序的优先级降低,有可能被系统收回。在这里保存的数据,应该在

onResume里读出来,注意:这个方法里做的事情时间要短,因为下一
个activity不会等到这个方法完成才启动

onstop: 变得不可见 ,被下一个activity覆盖了

onDestroy: 这是activity被干掉前最后一个被调用方法了,可能是外面类调用finish方
法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判
断它,如果你有一个Progress Dialog在线程中转动,请在onDestroy里
把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛
的。

onPause,onstop, onDestroy,三种状态下 activity都有可能被系统干掉
为了保证程序的正确性,你要在onPause()里写上持久层操作的代码,将用户编辑的内容都保存到存储介质上(一般都是数据库)。实际工作中因为生命周期的变化而带来的问题也很多,比如你的应用程序起了新的线程在跑,这时候中断了,你还要去维护那个线程,是暂停还是杀掉还是数据回滚,是吧?因为Activity可能被杀掉,所以线程中使用的变量和一些界面元素就千万要注意了,一般我都是采用Android的消息机制[Handler, Message]来处理多线程和界面交互的问题。

/Chapter05_Activity_LifeCycle/src/com/amaker/test/MainActivity.java

        
  1. 代码
  2. packagecom.amaker.test;
  3. importandroid.app.Activity;
  4. importandroid.os.Bundle;
  5. importandroid.util.Log;
  6. importandroid.view.View;
  7. importandroid.view.View.OnClickListener;
  8. importandroid.widget.Button;
  9. publicclassMainActivityextendsActivity{
  10. privateButtonb1;
  11. privatestaticfinalStringTAG="lifecycle";
  12. @Override
  13. publicvoidonCreate(BundlesavedInstanceState){
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. Log.i(TAG,"onCreate------------------------------>");
  17. b1=(Button)findViewById(R.id.Button01);
  18. b1.setOnClickListener(newOnClickListener(){
  19. @Override
  20. publicvoidonClick(Viewv){
  21. MainActivity.this.finish();
  22. }
  23. });
  24. }
  25. @Override
  26. protectedvoidonStart(){
  27. super.onStart();
  28. Log.i(TAG,"onStart------------------------------>");
  29. }
  30. @Override
  31. protectedvoidonRestart(){
  32. super.onRestart();
  33. Log.i(TAG,"onRestart------------------------------>");
  34. }
  35. @Override
  36. protectedvoidonResume(){
  37. super.onResume();
  38. Log.i(TAG,"onResume------------------------------>");
  39. }
  40. @Override
  41. protectedvoidonPause(){
  42. super.onPause();
  43. Log.i(TAG,"onPause------------------------------>");
  44. }
  45. @Override
  46. protectedvoidonStop(){
  47. super.onStop();
  48. Log.i(TAG,"onStop------------------------------>");
  49. }
  50. @Override
  51. protectedvoidonDestroy(){
  52. super.onDestroy();
  53. Log.i(TAG,"onDestroy------------------------------>");
  54. }
  55. }

/Chapter05_Activity_LifeCycle/res/layout/main.xml

        
  1. 代码
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. >
  8. <TextView
  9. android:id="@+id/TextView01"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:text="�y�Activity的生命�L期"></TextView>
  13. <Buttonandroid:id="@+id/Button01"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"
  16. android:text="�Y束Activity"></Button>
  17. </LinearLayout>

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
  3. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
  4. 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
  5. android的TabActivity
  6. 【Android(安卓)开发教程】链接Activities
  7. Android(安卓)源码阅读之建立3G网络流程
  8. Android-NDK开发之基础--Android(安卓)JNI实例代码(二)-- 获取/
  9. android intent action 介绍大全

随机推荐

  1. android的webview调用javascript函数并得
  2. cyanogenmod 内核编译简记
  3. Android中设置EditText获得焦点时不弹出
  4. 百度地图移动版API 1.2.2版本(Android)地图
  5. android 使用分享功能
  6. Android实现简单手电筒功能
  7. android 设置所有的APP都转屏
  8. Android的一本很好的英文原著Andbook 我
  9. Android之ImageSwitcher的实例详解
  10. android spinner 样式完全自定义[包括Rad