android学习笔记(三)——Activity

本文是关于Android中Activity的学习笔记,介绍了Activity的基本概念、Intent的使用(显式与隐式)、Activity的生命周期以及如何在Activity间传递数据。通过实例展示了如何启动Activity、关闭Activity以及在不同状态下进行数据交互。此外,还探讨了Activity的生命周期,包括创建、启动、暂停、停止和销毁等各个阶段,帮助开发者更好地理解和控制Activity的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、写在前面的话

上一篇我们知道了android的常用的四个布局,还有一些常用的控件的用法,当然我这只是杯水车薪,更多的用法还是得在实际项目中去学习。今天这一篇博客也是拖了好几天才写,一是这几天工作也比较忙,二是这个Activity是四大组件之一,比较重要,细说起来也很复杂,但他又是我们在实际操作中遇到的最多的。思考之下,这一篇只是粗略的说一下,等以后有机会再深入了解Activity。

二、初探Activity——Intent

首先我们要知道什么是Activity(活动),他是一种可以包含用户界面的组件,主要用于和用户进行交互。一个程序里至少要有一个Activity(至少我们现在写的程序都是让人拿来用的)。其实我们在第一篇的时候就已经接触过Activity了,当时我们是创建了一个MainActivity继承自Activity来实现了HelloWorld。那么接下来我们来看看两个Activity是怎么运行的。

  • Intent
    我们先新建一个项目ActivityTest,首先我们要知道多个Activity之间是如何跳转的,这里我们用到了一个新的东西叫——Intent。让我们先来看看他是如何运用的。
public class MainActivity extends ActionBarActivity {

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });
    }

}
public class SecondActivity extends ActionBarActivity{

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.secondlayout);
        initView();
    }

    private void initView() {
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

效果如下:
这里写图片描述

这里我们看到在MainActivity里,我们的button的点击方法实现了Activity的跳转。在SecondActivity 里我们用了finish() 方法来关闭活动(类似点击了返回键)。在MainActivity里我们new了一个新的Intent对象,并给他传入了两个参数,第一个要求提供一个启动活动的上下文,一般传入我们当前的activity,第二个就是我们想要启动的activity了。这样是不是很简单呢,只需要new一个新的Intent对象就好了。这种方法是我们比较常用的一种显示Intent的用法,下面我们来介绍他的另一种用法——隐式Intent。

隐式Intent的用法并不会明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的的action和category等信息,然后交给系统去分析这个Intent并帮我们找到合适的活动去启动。那系统是怎么帮我们找到的呢,那就需要我们在AndroidManifest里去设置了。

        <activity android:name=".SecondActivity">
            <intent-filter>
                <action android:name="com.jiang.joey.activitytest.ACTION_START"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

然后我们在MainActivity里修改button的点击事件

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.jiang.joey.activitytest.ACTION_START");
                startActivity(intent);
            }
        });

这里我们看到,我们直接将action的字符串传给了intent,表明我们要启动能响应这个action的活动,在这里还有category ,如果我们没有指定特定的category ,那么系统会自动给我们带上默认的category ,也就是我们在AndroidManifest里添加的"android.intent.category.DEFAULT"

隐式Intent还有更多的用法,他并不局限于我们自己程序里的activity,他还可以启动其他程序的活动,比如调用系统浏览器去打开个网页啊,打开拨号界面打电话啊等等。

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("http://www.baidu.com"));
                startActivity(intent);
            }
        });

这里写图片描述

这里多出了个setData 方法,他接受一个Uri对象,主要用于指定当前的Intent正在操作的数据,这里我们传入了一个http对象,那么他就打开这个http。我们还可以打开拨号盘。

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("tel:10086"));
                startActivity(intent);
            }
        });

这里写图片描述

  • Intent传递数据
    我们有很多时候在activity跳转的时候需要将一个或多个值传给下一个要打开的activity,那Intent是怎么传值的呢,下面我们来演示一下
public class MainActivity extends ActionBarActivity {

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String data = "这是第一个Activity传递给第二个Activity的值";
                Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                intent.putExtra("data",data);
                startActivity(intent);
            }
        });
    }

}
public class SecondActivity extends ActionBarActivity{

    private Button button;
    private String data;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.secondlayout);
        initView();
    }

    private void initView() {
        Intent intent = getIntent();
        data = intent.getStringExtra("data");
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(SecondActivity.this,data,Toast.LENGTH_SHORT).show();
            }
        });
    }
}

这里写图片描述

这里我们使用了putExtragetStringExtra 来传递数据,并用Toast将传递的值显示了出来,那当SecondActivity按下返回键返回到MainActivity时能否传递个数据给MainActivity呢?这当然是可以的,我们接着来看。

public class MainActivity extends ActionBarActivity {

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String data = "这是第一个Activity传递给第二个Activity的值";
                Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                intent.putExtra("data",data);
                startActivityForResult(intent,1);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case 1:
                if (resultCode== RESULT_OK){
                    String data_return = data.getStringExtra("data_return");
                    Log.d("MainActivity===>",data_return);
                }
                break;
            default:
                break;
        }
    }
}
public class SecondActivity extends ActionBarActivity{

    private Button button;
    private String data;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.secondlayout);
        initView();
    }

    private void initView() {
        Intent intent = getIntent();
        data = intent.getStringExtra("data");
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent1 = new Intent();
                intent1.putExtra("data_return","这是第二个Activity返回给第一个Activity的值");
                setResult(RESULT_OK,intent1);
                finish();
            }
        });
    }
}

这里我们看到,在MainActivity里我们的点击事件里,和之前不同的地方我们使用了startActivityForResult 这也是用来启动活动的一种方法,传入了二个参数,第一个是intent,第二个是请求码,用于在之后的回调中判断数据的来源,这里我们传入1,然后我们在SecondActivity 的点击事件里添加了返回数据的逻辑,这里的setResult() 方法用于向上一个活动返回数据,一般传入两个参数,第一个是用于向上一个活动返回处理结果,一般传入RESULT_OKRESULT_CANCELED 这两个值,第一个则是将带有数据的intent传递过去。然后在SecondActivity 销毁后会调用上一个活动里的onActivityResult 方法来得到返回的数据,我们在MainActivity里来重写这个方法,将返回的数据给打印出来。

这里写图片描述

这里需要注意下就是如果你和我一样传回的值里带有汉字,android对汉字需要UTF-8编码,把编码格式改为UTF-8即可显示正常。studio修改单个文件的编码格式就在该界面的右下角处修改。修改整个工程的编码格式,在File->Setting->Editor->File Encodings里修改。

onActivityResult 方法有三个参数,第一个requestCode 就是我们之前的请求码,第二个resultCode 就是我们的返回数据时传入的处理结果RESULT_OKRESULT_CANCELED,第三个参数data 就是携带者返回数据的intent。

三、Activity的生命周期

在了解Activity的生命周期之前,我们先来了解一下android里的返回栈。在前面的过程中,我们发现android中活动是可以层叠的,每启动一个新的activity就会覆盖在原来的activity上,然后点击返回键又会销毁activity并返回到原来的activity。这里android就是使用了Task(任务)来管理活动的。Task就是一组存放在栈里的活动的集合,这个栈就是返回栈。

返回栈是后进先出的一种数据结构,默认下当我们启动了一个activity,他就会进入到返回栈中,并处于栈顶的位置,当我们按下返回键或者调用finish() 方法时,位于栈顶的activity就会出栈,这时前一个入栈的activity就会重新位于栈顶。系统总是会显示位于栈顶的activity给用户。(图片为《第一行代码》里图2.19)
这里写图片描述

这样根据在栈的位置,我们把activity的活动状态分为四种

  • 运行状态
    位于栈顶的时候,这个activity就处于运行状态。系统最不倾向于回收此状态的activity,因为这个activity还在活动中,回收会带来很差的用户体验。
  • 暂停状态
    当一个activity并不位于栈顶,但他仍可见,即暂停状态。比如一些对话框形式的activity,虽然并不位于栈定了,但仍可见。
  • 停止状态
    当一个activity并不位于栈顶,而且也不可见时,就是停止状态。系统仍会给这个activity保存相应的状态和数据,但当内存不足时,系统就可能会回收此状态的activity。
  • 销毁状态
    当一个activity从返回栈中移除后就是销毁状态,系统会最倾向与回收此状态的activity。

我们了解了android内关于activity的一些状态后就可以来学习activity的生命周期,掌握Activity的生命周期对于程序的开发是非常重要的,这里我们只是初略的讲一下他的生命流程。
这里写图片描述

一个活动的生命周期包含了7个方法:onCreate(),onStart(),onResume(),onPause(),onStop(),onDestroy(),onRestart()这7种方法,每一个方法

  • onCreate()
    这个我们见过很多次了,他会在程序第一次被创建的时候调用,里面主要完成一些初始化的操作等。
  • onStart()
    这个方法在活动由不可见变为可见的时候调用
  • onResume()
    这个方法是在活动准备好和用户进行交互时调用,此时活动位于返回栈的栈顶,并处于运行状态。
  • onPause()
    这个方法是系统准备去启动或者恢复另一个活动时调用,这里我们通常会释放资源以及保存一些关键数据,但这个方法的执行速度一定要快。
  • onStop()
    这个方法是在活动完全看不见的时候调用。他和onPause()的区别是,如果启动的活动是一个对话框活动,那么onPause()会执行,而onStop()不会执行。
  • onDestroy()
    这个方法在活动销毁前调用。调用后活动的状态为销毁状态
  • onRestart()
    这个方法在活动由停止状态变为运行状态之前调用。

我们来用运行程序来具体说明

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("MainActivity=====>", "onCreate");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("MainActivity=====>", "onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("MainActivity=====>", "onDestroy");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("MainActivity=====>", "onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("MainActivity=====>", "onResume");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("MainActivity=====>", "onStart");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("MainActivity=====>", "onRestart");
    }

这里我们就只是将这7个方法全部重写,并在里面只写了打印的句子,我们运行程序,就能明白的看到activity的生命周期了。这是我们打开程序:
这里写图片描述

我们看到程序第一次运行时执行的方法是onCreate => onStart => onResume,接下来我们来按下返回键退出程序:
这里写图片描述

我们看到执行的方法是onPause => onStop => onDestroy。那么单个活动的生命周期就很明确了onCreate => onStart => onResume =>onPause => onStop => onDestroy。那么有两个活动的话,生命周期又将怎么样呢,还是用程序来说明,在之间的基础上添加个button跳转到SecondActivity,并打印SecondActivity的生命周期(在用studo里复写方法的快捷键可以像我第一篇里说的到keymap里修改,也可以直接按Alt + Insert 调出菜单,这个菜单里有很多常用的,比如自动写构造方法,自动写set/get方法,复写方法等。写完SecondActivity后记得到manifest里注册

这里写图片描述
这里我们可以看到(自动过滤掉中间那些无关紧要的警告,那些W开头的),MainActivity执行了onCreate => onStart => onResume后MainActivity在界面显示,然后我们点击button跳转到SecondActivity,这时我们看到首先是MainActivity执行了onPause 方法,然后才执行SecondActivity的onCreate 方法。这里设计的好处是先让第一个活动在准备要跳转到第二个活动时,先暂停第一个活动不让他去影响到第二个活动。举个例子,比如你正在听歌,这时来了个电话,这种情况就是活动的跳转,那么如果我们不先暂停第一个活动,即听歌这个活动,那么歌曲这个声音将会影响到我们打电话这个活动,这样用户体验非常差。所以要先执行MainActivity的onPause 方法再执行SecondActivity的onCreate 方法。我们再往下看在执行完SecondActivity的onResume 方法,活动已经变的可见了,这时候才会执行MainActivity的onStop 方法。接下来我们按下返回键,回到MainActivity:

这里写图片描述

我们看到在执行完SecondActivity的onPause 方法后,MainActivity并没有去再执行onCreate 而是执行了onRestart方法,然后再onStart 、onResume,接着SecondActivity执行onStop ,接着销毁SecondActivity执行onDestroy方法。这样activity的生命周期大致就清楚了。还有一种activity——DialogActivity,跳转到这种activity时,DialogActivity并不会完全遮住第一个activity,所以这种生命周期是有点不一样的,这里我就不细说了,感兴趣的可以再写个button跳转到个DialogActivity(DialogActivity的写法就是在manifest中将android:theme设置为@android:style/Theme.Dialog)。到这里关于activity我们就学习了个大概,要深入了解activity还需要之后多学多用多了解,最后开发出好的APP。

四、写在后面的话

这篇真的是拖了好久,最近每天只能晚上回家写写,有时候玩性上来了就想玩会,拖拖拉拉的用了两周多,也是醉了。。。

前几天还看了个电影——尔冬升导演的《我是路人甲》,看完感触颇深,也许是最近碰到了很多问题。。。同是漂着,剧里那些路人甲的梦想,那些聚会时义愤填膺,批评别人的时候的心灵鸡汤也并没有像以前电影里那么令人反感,反而更加真实。因为像我这种小人物在鹏城这种大地方,心中没有点激情,没有点鸡汤还怎么去坚持下去呢,怎么去继续往下走呢。我这里也不是说鸡汤的好,只是觉得我这种小人物在还没锻炼出钢铁般的内心前还是需要点来支撑的,比如我会一直坚信我会成功的,嗯,是的,我会成功的。

代码比较简单,就不上传源码了。

转载请注明:http://blog.csdn.net/jiang89125/article/details/48475277

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值