Android编程权威指南 - 第5章 第二个Activity

1 手工新建一个Activity

1.1 在String.xml中添加需要Activity需要的字符串

  • 新的Activity的界面需要一些用到的字符串资源,手工在String.xml中添加
Cheat!
Show Answer

1.2 新建一个布局xml文件

  • 在包资源管理中,选中res/layout文件夹,新建一个Layout XML File
  • 需要注意的是,同时需要复制创建一份横屏的layout文件
    竖屏layout

    
          
          
      

横屏layout


    
          
          
      

1.3 创建一个Activity的类

  • 包资源管理器中,创建一个新class,继承android.app.Activity类
  • 复写onCreate函数。函数的参数是android.os.Bundle类型的savedInstanceState对象。函数需要将第二步定义的layout文件载入。
@Overridepublic void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);    
      setContentView(R.layout.activity_cheat);
}

1.4 AndroidManifest.xml文件中声明Activity

  • 必须有android:name属性

  • "."表示告知OS在AndroidManifest.xml文件的包属性值,指定的包路径下可以找到Activity类文件

2 两个Activity之间的通信

2.1 Intent负责在两个Activity之间传递信息

  • Activity的启动和关闭,是通过Android操作系统的ActivityManager来进行管理的。Intent对象是负责Activity和ActivityManager通信的。
  • 例如A界面要启动B界面,A先发送Intent对象给ActivityManager。接收到信息后,ActivityManager根据消息启动B界面。
  • 即使是APP内部的Activity通信,也需要通过操作系统的ActivityManager进行
  • Intent构造函数如下,第一个参数Context对象是告诉ActivityManager在哪一个包可以找到Class对象。第二个参数指的是要通信对象的Class。
public Intent (Context packageContext, Class cls)

具体的实例,通过startActivity(Intent)启动另外的Activity

Intent i = new Intent(QuizActivity.this, CheatActivity.class);
startActivity(i);
  • Intent分显示和隐式。上面的例子是显示调用,隐式调用一般用于App之间的调用。

2.2 Activity间的发送和接受数据

  • Intent对象传递数据是通过Extra数据类型传递,其结构是一种key-value结构
  • 设置Extra值是用putExtra函数,第一个参数是key,第二个参数是value。下面这个例子的value类型是boolean,也可以是其他类型。
public Intent putExtra(String name, boolean value)
  • 获取Extra值是用getXXExtra函数,其中XX指的是类型。函数有两个参数,第一个参数是key值,第二个参数指的是value的默认值。下面的例子是boolean类型
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);

2.3 Activity间获取调用的返回结果

  • A界面调用B界面,有时候再返回时需要获取B界面的结果
  • 这种情况下,启动A界面启动B界面,需要使用startActivityForResult函数。第一个参数是Intent对象,第二个参数是请求代码。
    请求代码的作用是,当启动多个Activity时,需要判断区分回馈消息时,需要用到请求代码。
public void startActivityForResult(Intent intent, int requestCode)

当不需要区分时,requestCode填写0即可。

startActivityForResult(i, 0);
  • 返回结果有两种方法可以调用
public final void setResult(int resultCode)
public final void setResult(int resultCode, Intent data)

resultCod预定义有两种常量

Activity.RESULT_OK
Activity.RESULT_CANCELED
  • 如果不调用setResult函数,用户点击返回键后,activity会收到Activity.RESULT_CANCELED的结果代码
  • ActivityManager会调用onActivityResult函数,来处理setResult函数设置的返回结果
protect void onActivityResult(int requestCode, int resultCode, Intent data)
  • 例子
    A界面调用B界面,B界面返回值
    B界面设置返回结果
private void setAnswerShownResult(boolean isAnswerShown) {    
      Intent data = new Intent();    
      data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);     
      setResult(RESULT_OK, data);
}

A界面处理返回结果

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {   
      if (data == null) {        
            return;    
      }    
      mIsCheater = data.getBooleanExtra(CheatActivity.EXTRA_ANSWER_SHOWN, false);
}

3 Activity的使用和管理

3.1 默认启动的Activity

启动App其实是启动一个Activity。默认启动的Activiy在AndroidManifest.xml文件中定义了,被设置为launcher Activity。具体声明如下:

    
              
                    
                
      

3.2 Activity间调用的log分析

  • 启动App
    启动了主界面
11-11 01:41:21.899 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onCreate called
11-11 01:41:21.939 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onStart called
11-11 01:41:21.941 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onResume called
  • 调用第2个Activity
    暂停主Activity -> 启动第2个Activity -> OpenGLRenderer: endAllActiveAnimators -> 保存主Activity数据 -> 停止主Activity
11-11 01:44:01.177 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onPause called
11-11 01:44:01.196 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onCreate called
11-11 01:44:01.211 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onStart called
11-11 01:44:01.215 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onResume called
11-11 01:44:01.314 4511-4644/geoquiz.android.bignerdranch.com.geoquiz D/OpenGLRenderer: endAllActiveAnimators on 0xa4058c00 (RippleDrawable) with handle 0x956994c0
11-11 01:44:01.644 4511-4511/geoquiz.android.bignerdranch.com.geoquiz I/QuizActivity: onSavedInstanceState
11-11 01:44:01.644 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onStop called
  • 在第2个Activity按回退键
    暂停第2个Activity -> 主Activity处理返回的结果(onActivityResult called) -> 重新启动主Activity -> 停止并销毁第2个Activity
11-11 01:49:23.463 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onPause called
11-11 01:49:23.469 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onActivityResult called
11-11 01:49:23.471 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onStart called
11-11 01:49:23.472 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/QuizActivity: onResume called
11-11 01:49:23.779 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onStop called
11-11 01:49:23.780 4511-4511/geoquiz.android.bignerdranch.com.geoquiz D/CheatActivity: onDestroy called
  • 总结
    从调用者到被调用者时,调用Activity没有销毁,只是暂停
    被调用者返回调用者时,被调用的Activity则会被销毁

3.3 原理

  • 实际上ActivityManager维护着一个Activity栈,所有的应用都在一个共享的Activity栈中
  • 当主Activity调用第2个Activity时,两个Activity都在栈中,而第2个Activity在栈顶。
  • 当按回退键回退到主Activity时,第2个Activity被弹出栈外,被销毁;而主Activity则回到栈顶。

你可能感兴趣的:(Android编程权威指南 - 第5章 第二个Activity)