Android笔记之Activity的生命周期

前言

mars老师的视频只更新到第二季,从2015年开始就不再更新了。所以这部分笔记就只能记到第二季了。但是学习Android的步伐不会停下,后面可能会接着看mars重制版之前的视频或者看看慕课网、极客学院等关于安卓的知识。极客学院的那个讲安卓的老师讲的不好,说了半天不知道在说什么。看情况吧,之后还是会记笔记的,不过可能会和这部分内容衔接的不太好。

在这季中,mars老师将UI、网络、线程等知识串着讲,都只是谈谈初级知识。我觉得这样挺好,不至于学了一大块内容还做不出什么东西来,枯燥乏味之后就搁置的半途而废。

内容

Activity的生命周期

如何在一个应用程序中定义多个Activity

三步走:
1、定义一个类,继承Activity;
2、在该类中,复习Activity当中的onCreate方法;
3、在AndroidManifest.xml文件(安卓主配置文件,所有控件都要在这个文件中注册)当中注册该Activity。
具体方法:
1、在Java文件夹下新建一个Activity,此时也会对应产生一个布局的xml文件,如图:

2、在第二个Activity中打印文字

1
2
3
4
5
6
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
System.out.println("这是第二个Activity");
}

3、设置manifests文件夹下的AndroidManifest.xml文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >

<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Main2Activity" >
</activity>
</application>

<application>标签代表整个app;
<activity>代表某个Activity;
中间几行代码:

1
2
3
4
5
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

代表默认的Activity,如果哪个Activity设置这个,那么启动程序时,首先开始的Activity就是他。

如何启动一个Activity

当这个页面完成任务后,想跳转到另一个页面。那么怎么实现Activity之间的跳转呢?
生成一个Activity并跳转,并不是程序员完成的,而是安卓系统自己完成的。程序员要做的是通知系统去生成。怎么去通知呢?
1、生成一个意图对象(Intent)
2、调用setClass方法设置所要启动的Activity
3、调用starActivity方法启动Activity

意图(Intent):封装了“你想做什么”这件事,发消息、打电话、GPS定位都需要Intent;
它表示一个动作的发生。

具体步骤:
1、在第一个Activity中设置一个按钮,当点击按钮后,页面跳转到第二个Activity。
2、在按钮监听器下输入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 class ButtonListener implements View.OnClickListener
{


@Override
public void onClick(View v)
{

Intent intent = new Intent();//生成一个意图对象
intent.setClass(MainActivity.this, Main2Activity.class);
//setClass函数的第一个参数是一个Context对象;
//Context是一个类,Activity是Context类的子类,也就是说,所有的Activity对象,都可以向上转型为Context对象;
//setClass函数的第二个参数是一个Class对象,在当前场景下,需要跳转的那个Activity类的class对象
startActivity(intent);//启动Activity
}
}

3、在onCreate()函数中设置button,主界面的完整java代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.demoniaccube.chobits.course_activity;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity
{

private Button button;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new ButtonListener());

}

class ButtonListener implements View.OnClickListener
{


@Override
public void onClick(View v)
{

Intent intent = new Intent();
intent.setClass(MainActivity.this, Main2Activity.class);
startActivity(intent);
}
}
}

Android当中的back stack

back stack(后退栈或者叫历史栈)
它是用来存储Activity对象的,这使得用户可以返回上一个Activity,这和网页浏览器的返回按钮的功能差不多。它遵循栈的一般特点:先进后出。安卓只显示back stack最上面的Activity。

Activity的生命周期函数

生命周期函数 调用时机
onCreate 在Activity对象被第一次创建时调用
onStart 在Activity变得可见时调用该函数
onResume 当Activity开始准备与用户交互时调用该方法
onPause 当系统即将启动另外一个Activity之前调用该方法
onStop 当前Activity变得不可见时调用该方法
onDestroy 当前Activity被销毁之前将会调用该方法
onRestart 当一个Activity再次启动之前将会调用该方法

调用生命周期函数的时机:
当一个Activity1被创建时,onCreate、onStart、onResume被依次调用;
当跳转到下一个Activity2时,Activity1的onPause方法会先被调用,然后依次调用Activity2的onCreate、onStart、onResume方法,接着调用Activity1的onStop方法;
当点击返回按钮,返回到Activity1时,先调用Activity2的onPause方法,再依次调用Activity1的onRestart、onStart、onResume方法,最后依次调用Activity2的onStop、onDestroy方法。

Activity对象的状态

1、Resumed:Activity对象处于运行状态
2、Paused:另一个Activity位于前端,但是本Activity还可见
3、Stopped:另一个Activity位于前端,完全遮挡本Activity
note:停止和暂停状态,依然在后台占用资源和内存。

成对的生命周期函数


onCreate和onDestroy
onStart和onStop
onResume和onPause
在编写代码时,注意选择周期函数的时机。比如音乐播放器,在播放音乐时,突然来了一个电话,那么在电话打完后回到界面应当继续播放音乐,如果将播放的代码放在了onCreate函数中,那么就不会再继续播放音乐了。

Intent对象初步

Intent对象的基本概念

1、Intent是Android应用程序组件之一;
2、Intent对象在Android系统当中表示一种意图;
3、Intent当中最重要的内容是action与data。

Intent对象的基本使用方法

使用Intent在Activity之间传递数据的方法

1、在Activity之间可以通Intent对象传递数据;
2、使用putExtra()系列方法向Intent对象当中存储数据;
3、使用getXXXExtra()系类方法从Intent对象当中取出数据;
具体方法:
运用上节所学,新建两个Activity,并实现点击按钮跳转到第二个Activity;在第一个Activity中使用putExtra()系列方法向Intent对象当中存储数据;在第二个Activity中使用getXXXExtra()系类方法从Intent对象当中取出数据。
代码如下:
第一个Activity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class MainActivity extends AppCompatActivity
{

private Button button;
@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new ButtonListener());

}

class ButtonListener implements View.OnClickListener
{


@Override
public void onClick(View v)
{

Intent intent = new Intent();
//setClass函数的第一个参数是一个Context对象;
//Context是一个类,Activity是Context类的子类,也就是说,所有的Activity对象,都可以向上转型为Context对象
intent.setClass(MainActivity.this, Main2Activity.class);
//setClass函数的第二个参数是一个Class对象,在当前场景下,需要跳转的那个Activity类的class对象
intent.putExtra("com.demoniaccube.chobits.course_activity.Age", 10);//传入数据
startActivity(intent);
}
}
}

第二个Activity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Main2Activity extends AppCompatActivity
{

private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState)
{


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);

textView = (TextView)findViewById(R.id.text);

Intent intent = getIntent();//返回激活这个Activity的intent
int age = intent.getIntExtra("com.demoniaccube.chobits.course_activity.Age", 20);
//getXXXExtra中的XXX取决于传入的值的数据类型,比如这里的20是整型,就是getIntExtra();
//getIntExtra返回的是上一个intent传入的值,这里是在MainActivity中传入的10;
// 如果上一个intent中并没有传入这样一个值,那么则返回设置的默认值20
System.out.println(age);//这样就没问题
//但是像下面这样就有问题了,报错:貌似是空指针;好像是布局的id和获取控件出来问题,但是改过来还是不行,好像没有重新载入的感觉。
//textView = (TextView)findViewById(R.id.m_text);
//textView.setText(age);
}
}

Android中的线程

Main Thread与Worker Thread

主线程和其他工作线程;
UI都在主线程中;

关于线程方面的知识讲的比较浅,我也不是很了解,还需要查阅一些资料,这里先暂时这样记着吧。

一个简单的实现一个线程的方法:

Android当中的线程使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MainActivity extends AppCompatActivity
{

private TextView textView;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState)
{


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.textViewId);
button = (Button)findViewById(R.id.buttonId);
}

class ButtonLisener implements OnClickListener
{

@Override
public void onClick(View v)
{

Thread t = new MyThread();
t.start();
}
}
class MyThread extends Thread
{

@Override
public void run()
{

try{Thread.sleep(1 * 1000);}
catch(InterruptedException e)
{
e.printStackTrace();
}
textView.setText("来自线程的修改");
}
}
}

原则上是不允许在主线程之外修改UI的