黑马程序员_android笔记6

---------------------- android培训java培训、期待与您交流! ----------------------



  第五天

1、 为应用添加新的Activity:

 第一步:新建一个继承Activity的类,如:NewActivity

public class NewActivity extends Activity {

    @Override protected void onCreate(Bundle savedInstanceState) {

                   super.onCreate(savedInstanceState);

   //这里可以使用setContentView(R.layout.xxx)显示某个视图....

     }

}

第二步:需要在功能清单AndroidManifest.xml文件中添加进上面Activity配置代码(红色部分):……

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        .....

<activity android:name=".NewActivity" android:label="新activity的页面标题"/>

    </application>……

android:name属性值的前面加了一个点表示NewActivity是当前包cn.itcast.action下的类,如果类在应用的当前包下,可以省略点符号,如果类在应用的子包下必须加点,如:NewActivity类在cn.itcast.action.user包下可以这样写:<activity android:name=“.user.NewActivity“ />

打开新的Activity:

第一种:打开新的Activity,不传递参数

public class MainActivity extends Activity {

  protected void onCreate(Bundle savedInstanceState) {

.......

Button button =(Button) this.findViewById(R.id.button);

    button.setOnClickListener(new View.OnClickListener(){

public void onClick(View v) {

//三种打开Activity的方法:

/* 1、 intent.setClass(MainActivity.this, OtherActivity.class);//设置要激活的组件

2、intent.setComponent(new ComponentName(MainActivity.this, OtherActivity.class));//设置要激活的组件

startActivity(intent);*/

//显式意图,第一个参数为当前Activity类对象,第二个参数为你要打开的Activity类

3、     startActivity(new Intent(MainActivity.this, NewActivity.class));

}});       }}

第二种:打开新的Activity,并传递若干个参数给它:

public class MainActivity extends Activity {

  @Override protected void onCreate(Bundle savedInstanceState) {

.......

 button.setOnClickListener(new View.OnClickListener(){

public void onClick(View v) {

Intent intent = new Intent(MainActivity.this, NewActivity.class)

Bundle bundle = new Bundle();//该类用作携带数据

bundle.putString("name", "传智播客");

bundle.putInt("age", 4);

intent.putExtras(bundle);//附带上额外的数据

startActivity(intent); }}); }

}

在新的Activity中接收前面Activity传递过来的参数:

public class NewActivity extends Activity {

            @Override protected void onCreate(Bundle savedInstanceState) {

     ........

     Bundle bundle = this.getIntent().getExtras();

     String name = bundle.getString("name");

                     int age = bundle.getInt("age");           }}

为Intent附加数据的两种写法:

第一种写法,用于批量添加数据到Intent:

Intent intent = new Intent();

Bundle bundle = new Bundle();//该类用作携带数据

bundle.putString("name", "传智播客");

intent.putExtras(bundle);//为意图追加额外的数据,意图原来已经具有的数据不会丢失,但key同名的数据会被替换

第二种写法:这种写法的作用等价于上面的写法,只不过这种写法是把数据一个个地添加进Intent,这种写法使用起来比较方便,而且只需要编写少量的代码。

Intent intent = new Intent();

intent.putExtra("name", "传智播客");

Intent提供了各种常用类型重载后的putExtra()方法,如: putExtra(String name, String value)、 putExtra(String name, long value),在putExtra()方法内部会判断当前Intent对象内部是否已经存在一个Bundle对象,如果不存在就会新建Bundle对象,以后调用putExtra()方法传入的值都会存放于该Bundle对象。

2、 得到新打开Activity 关闭后返回的数据

如果你想在Activity中得到新打开Activity 关闭后返回的数据,你需要使用系统提供的startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新的Activity 关闭后会向前面的Activity 传回数据,为了得到传回的数据,你必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法:

public class MainActivity extends Activity {

      @Override protected void onCreate(Bundle savedInstanceState) {

.......

Button button =(Button) this.findViewById(R.id.button);

     button.setOnClickListener(new View.OnClickListener(){

public void onClick(View v) {

//第二个参数为请求码,可以根据业务需求自己编号

startActivityForResult (new Intent(MainActivity.this, NewActivity.class),  1); }});         }

    //第一个参数为请求码,即调用startActivityForResult()传递过去的值

    //第二个参数为结果码,结果码用于标识返回数据来自哪个新Activity

   @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {//得到新Activity 关闭后返回的数据

String result = data.getExtras().getString(“result”));    }}   

 当新Activity关闭后,新Activity返回的数据通过Intent进行传递,android平台会调用前面Activity 的onActivityResult()方法,把存放了返回数据的Intent作为第三个输入参数传入,在onActivityResult()方法中使用第三个输入参数可以取出新Activity返回的数据。

使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新Activity关闭前向前面的Activity返回数据需要使用系统提供的setResult(int resultCode, Intent data)方法实现:

public class NewActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) {

......

        button.setOnClickListener(new View.OnClickListener(){

public void onClick(View v) {

Intent intent = new Intent();//数据是使用Intent返回

intent.putExtra(“result”, “传智播客的学生很可爱”);//把返回数据存入Intent

 NewActivity.this.setResult(RESULT_OK, intent);//设置返回数据

 NewActivity.this.finish(); }}); }}

请求码的作用:

使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是哪个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由哪个按钮打开的,并且要做出相应的业务处理,这时可以这样做:

 @Override  public void onCreate(Bundle savedInstanceState) {

        ....

     button1.setOnClickListener(new View.OnClickListener(){

      public void onClick(View v) {

 startActivityForResult(new Intent(MainActivity.this, NewActivity.class), 1); }});

    button2.setOnClickListener(new View.OnClickListener(){

       public void onClick(View v) {

 startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2); }}); 

    

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

               switch(requestCode){

                   case 1:

                       //来自按钮1的请求,作相应业务处理

                   case 2:

                 //来自按钮2的请求,作相应业务处理

                }         }}

结果码的作用:

在一个Activity中,可能会多个按钮或一个按钮使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,在onActivityResult()方法中可以这样做(ResultActivity和NewActivity为要打开的新Activity):

public class ResultActivity extends Activity {

       .....

       ResultActivity.this.setResult(1, intent);

       ResultActivity.this.finish();}

public class NewActivity extends Activity {

       ......

        NewActivity.this.setResult(2, intent);

        NewActivity.this.finish();}

public class MainActivity extends Activity {

 // 在该Activity会打开ResultActivity和NewActivity

       @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

               switch(resultCode){

                   case 1:

                       // ResultActivity的返回数据

                   case 2:

                // NewActivity的返回数据

                }      }}

3、 意图

Intent提供了一种通用的消息系统,它允许在你的应用程序与其它的应用程序间传递Intent来执行动作和产生事件。使用Intent可以激活Android应用的三个核心组件:活动、服务和广播接收器。

Intent可以划分成显式意图和隐式意图。

显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。

隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。

例:MainActivity中:

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);    

        Button button = (Button) this.findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

Intent intent = new Intent();

intent.setAction("cn.itcast.lao.li");

intent.setDataAndType(Uri.parse("itcast://www.itcast.cn/person"), "image/gif");

startActivity(intent); }});    }

OtherActivity:

public class OtherActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {                    

// TODO Auto-generated method stub   

super.onCreate(savedInstanceState);    

setContentView(R.layout.other);           }}

manifest中:

<application android:icon="@drawable/icon" android:label="@string/app_name">

        ……

<activity android:name=".OtherActivity"  android:label="@string/app_name">

            <intent-filter>

                <action android:name="cn.itcast.lao.li" />

                <action android:name="cn.itcast.lao.zhang" />

                <category android:name="android.intent.category.DEFAULT" />

                <category android:name="cn.itcast.category.li" />

                <data android:scheme="itcast" android:host="www.itcast.cn" 

android:path="/person"/>

                <data android:mimeType="image/gif"/>

  </intent-filter></activity>  </application>

对于同时具有数据和数据类型(mimeType)的意图(如上),当匹配类型和数据时,需要用setDataAndType()方法同时匹配数据和数据类型,不能用setData()和setType()方法分别匹配。

匹配原则:

对于隐式意图,Android是怎样寻找到这个最合适的组件呢?记的前面我们在定义活动时,指定了一个intent-filter,Intent Filter(意图过滤器)其实就是用来匹配隐式Intent的,当一个意图对象被一个意图过滤器进行匹配测试时,只有三个方面会被参考到:动作、数据(URI以及数据类型)和类别。

动作测试(Action test)

  一个意图对象只能指定一个动作名称,而一个过滤器可能列举多个动作名称。如果意图对象或过滤器没有指定任何动作,结果将如下:

• 如果过滤器没有指定任何动作,那么将阻塞所有的意图,因此所有的意图都会测试失败。没有意图能够通过这个过滤器。 

• 另一方面,只要过滤器包含至少一个动作,一个没有指定动作的意图对象自动通过这个测试

类别测试(Category test)

对于一个能够通过类别匹配测试的意图,意图对象中的类别必须匹配过滤器中的类别。这个过滤器可以列举另外的类别,但它不能遗漏在这个意图中的任何类别。

原则上一个没有类别的意图对象应该总能够通过匹配测试,而不管过滤器里有什么。大部分情况下这个是对的。但有一个例外,Android把所有传给startActivity()的隐式意图当作他们包含至少一个类别:"android.intent.category.DEFAULT" (CATEGORY_DEFAULT常量)。 因此,想要接收隐式意图的活动必须在它们的意图过滤器中包含"android.intent.category.DEFAULT"。(带"android.intent.action.MAIN"和"android.intent.category.LAUNCHER"设置的过滤器是例外)

数据测试(Data test)

当一个意图对象中的URI被用来和一个过滤器中的URI比较时,比较的是URI的各个组成部分。例如,如果过滤器仅指定了一个scheme,所有具有该scheme的URIs都能够和这个过滤器相匹配;如果过滤器指定了一个scheme、主机名但没有路经部分,所有具有相同scheme和主机名的URIs都可以和这个过滤器相匹配,而不管它们的路经;如果过滤器指定了一个scheme、主机名和路经,只有具有相同scheme、主机名和路经的URIs才可以和这个过滤器相匹配。当然,一个过滤器中的路径规格可以包含通配符,这样只需要部分匹配即可。

数据测试同时比较意图对象和过滤器中指定的URI和数据类型。规则如下:

a. 一个既不包含URI也不包含数据类型的意图对象仅在过滤器也同样没有指定任何URIs和数据类型的情况下才能通过测试。

b. 一个包含URI但没有数据类型的意图对象仅在它的URI和一个同样没有指定数据类型的过滤器里的URI匹配时才能通过测试。这通常发生在类似于mailto:和tel:这样的URIs上:它们并不引用实际数据。

c. 一个包含数据类型但不包含URI的意图对象仅在这个过滤器列举了同样的数据类型而且也没有指定一个URI的情况下才能通过测试。

d. 一个同时包含URI和数据类型(或者可从URI推断出数据类型)的意图对象可以通过测试,如果它的类型和过滤器中列举的类型相匹配的话。如果它的URI和这个过滤器中的一个URI相匹配或者它有一个内容content:或者文件file: URI而且这个过滤器没有指定一个URI,那么它也能通过测试。换句话说,一个组件被假定为支持content:和file: 数据如果它的过滤器仅列举了一个数据类型。

4、Activity的生命周期:

Activity有三个状态:

l  当它在屏幕前台时(位于当前任务堆栈的顶部),它是激活或运行状态。它就是响应用户操作的Activity。 

l  当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时(如右图),它处于暂停状态。在它之上的Activity没有完全覆盖屏幕,或者是透明的,被暂停的Activity仍然对用户可见,并且是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接)。如果系统处于内存不足时会杀死这个Activity。 

l 当它完全被另一个Activity覆盖时则处于停止状态。它仍然保留所有的状态和成员信息。然而对用户是不可见的,所以它的窗口将被隐藏,如果其它地方需要内存,则系统经常会杀死这个Activity。 

当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:

void onCreate(Bundle savedInstanceState)      void onStart()

void onRestart()                              void onResume()

void onPause()                                void onStop()

void onDestroy()



这七个方法定义了Activity的完整生命周期。实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环:

l  Activity的完整生命周期自第一次调用onCreate()开始,直至调用onDestroy()为止。Activity在onCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。例如,如果Activity有一个线程在后台运行从网络下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。 

l  Activity的可视生命周期自onStart()调用开始直到相应的onStop()调用结束。在此期间,用户可以在屏幕上看到Activity,尽管它也许并不是位于前台或者也不与用户进行交互。在这两个方法之间,我们可以保留用来向用户显示这个Activity所需的资源。例如,当用户不再看见我们显示的内容时,我们可以在onStart()中注册一个BroadcastReceiver来监控会影响UI的变化,而在onStop()中来注消。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。 

l  Activity的前台生命周期自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity位于前台最上面并与用户进行交互。Activity会经常在暂停和恢复之间进行状态转换——例如当设备转入休眠状态或者有新的Activity启动时,将调用onPause() 方法。当Activity获得结果或者接收到新的Intent时会调用onResume() 方法。关于前台生命周期循环的例子请见PPT下方备注栏。

Activity的onSaveInstanceState()和 onRestoreInstanceState()方法:

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState()才会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

另外,当屏幕的方向发生了改变, Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activity的 onSaveInstanceState() 和 onRestoreInstanceState()方法,如下:

public class PreferencesActivity extends Activity {

    private String name;

    protected void onRestoreInstanceState(Bundle savedInstanceState) {

name = savedInstanceState.getString("name"); //被重新创建后恢复缓存的数据

super.onRestoreInstanceState(savedInstanceState);    }

    protected void onSaveInstanceState(Bundle outState) {

outState.putString("name", "liming");//被摧毁前缓存一些数据

super.onSaveInstanceState(outState);  }}




---------------------- android培训java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值