第一行代码学习笔记:Android基础----Activity
活动:是一种可以包含用户界面的组件,主要用于和用户进行交互。
基本用法:任何活动都要重写Activity的onCreate()方法,用setContentView();方法给当前活动加载一个布局。活动需要在AndroidManifest中注册。
销毁一个活动:finish();
使用Intent在活动之间跳转
Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景。
Intent分为两种:显式Intent和隐式Intent。
显式Intent:在MainActivity(图1)中通过Button的点击事件跳转到SecondActivity(图2)中,代码如下
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
这种方式就是显式Intent传递图1
图2
隐式Intent:不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮助我们找出合适的活动去启动。
什么叫合适的活动呢?简单来说就是可以响应我们这个隐式Intent的活动。
在AndroidManifest文件中做如下设置
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.zsp.firstcode.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
通过在<activity> 标签下配置<intent-filter>的内容,可以指定当前活动能够响应的activity和category。
<action android:name="com.zsp.firstcode.ACTION_START"/>
指明了当前活动可以响应com.zsp.firstcode.ACTION_START这个action
MainActivity中Button的点击事件改为
Intent intent = new Intent("com.zsp.firstcode.ACTION_START");
startActivity(intent);
同样可以从MainActivity跳转到SecondActivity,这就是隐式Intent启动启动。每个Intent只能指定一个action,却能指定多个category。
使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的功能共享成为可能。
活动的生命周期
返回栈
Android是使用任务(Task)来管理活动,一个任务就是一组放在栈里的活动的集合,这个栈也被称作返回栈(Back Task)
每个活动在其生命周期中最多可能会有四种状态
运行状态:位于返回栈的栈顶时活动处于运行状态。
暂停状态:当一个活动不在处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。
停止状态:当一个活动不在处于栈顶位置,并且完全不可见的时候,就进入了停止状态。
销毁状态:当一个活动从返回栈中移除的的时候,就变成了销毁状态。
活动的生存期
Activity类中定义了7个回调方法,覆盖了活动生命周期的每一个环节。
onCreate():活动第一次被创建的时候调用,完成活动的初始化操作。
onStart():活动由不可见变为可见的时候调用。
onResume():活动准备好和用户进行交互的时候调用。此时活动一定位于返回栈的栈顶,并且处于运行状态。
onPause():系统在准备去启动或者恢复另一个活动的时候调用,通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个放法的执行速度一定要快,不然会影响新的栈顶活动的使用。
onStop():活动完全不可见的时候调用,和onPause()方法的主要区别在于,如果启动的新活动是一个对话框式的活动,那么onPause()方法会得到执行,而onStop()方法并不会执行。
onDestroy():活动被销毁之前调用,之后活动的状态将变为销毁状态。
onRestart():活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
这七个方法中除了onRestart()其他都是两两相对的,从而又可以将活动分为3种生存期。
完整生存期:活动在onCreate()和onDestroy()方法之间所经历的,就是完整生存期。一般情况下活动会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。
可见生存期:活动在onStart()和onStop()方法之间所经历的,就是可见生存期,在可见生存期内,活动对于用户总是可见的,即便又可能无法和用户进行交互。可以通过这两个方法合理的管理那些对用户可见的资源。
前台生存期:活动在onResume()和onPause()方法之间所经历的,就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的。
活动被回收了怎么办?
Activity还提供了一个onSavaInstanceState()回调方法,这个方法可以保证在活动在被回收之前一定会被调用,因此我们可以通过这个方法来解决活动被回收时临时数据得不到保存的问题。
在Activity中添加代码保存数据。
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String str = "test";
outState.putString("data",str);
}
在onCreate方法中获取保存的数据
if (savedInstanceState!=null){
String temp = savedInstanceState.getString("data");
}
活动的启动模式
活动的启动模式有四种,分别是standard、singleTop、singleTask、singleInstance,可以在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式。
standard:活动默认的启动模式,在此模式下每当启动一个新的活动它就会在返回栈中入栈,并处于栈顶的位置。系统不会在乎这个活动在返回栈中是否存在,每次启动都会创建该活动的一个新的实例。
singleTop:在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。但是当Activity未处于栈顶时,再次启动Activity还是会创建新的实例。
singleTask:当活动的启动模式指定为singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例,保证活动在整个应用程序的上下文中只存在一个实例。
singleInstance:指定为singleInstance模式的活动会启用一个新的返回栈来管理这个活动。允许其他程序调用,实现其他程序和我们的程序共享这个活动实例。在singleInstance模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。
知晓当前是哪一个活动
根据程序当前的界面就能判断出是哪一个活动。
创建一个BaseActivity继承自AppCompatActivity,且不需要在AndroidManifest.xml中注册。并且重写onCreate()方法。
public class BaseAtivity extends AppCompatActivity {
private static final String TAG = "BaseAtivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, getClass().getSimpleName());
}
}
这样,每当进入一个活动时,该活动的类名就会被打印出来,就可以时时刻刻知晓当前界面对应哪一个活动啦。
随时随地退出程序
当从一个活动跳转到另一个活动,并且跳转了多个活动,如FirstActicity---->SecondActivity---->ThirdActivity,当处于ThirdActivity时,要退出程序需要按三次back键,如果程序需要一个注销或者退出的功能,只需要用一个专门的集合类对所有的活动进行管理。
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<>();
public static void addActivity(Activity activity){
activities.add(activity);
}
public static void removeActivity(Activity activity){
activities.remove(activity);
}
public static void finishAll(){
for (Activity activity:activities){
if (!activity.isFinishing()){
activity.finish();
}
}
activities.clear();
}
}
在BaseActivity中做如下修改
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, getClass().getSimpleName());
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
之后想要退出程序,只需要调用ActivityCollector.finishAll()就可以了。
启动活动的最佳方法
举个例子,当程序要跳转到SecondActivity界面去,而SecondActivity是由别人开发的,这时候想要知道启动这个活动需要传递哪些参数,除了阅读SecondActivity的代码,和负责SecondActivity编写的同事外,还有一种简洁的方法。
修改SecondActivity的代码
public static void actionStart(Context context ,String data1,String data2){
Intent intent = new Intent(context,SecondActivity.class);
intent.putExtra("param1",data1);
intent.putExtra("param2",data2);
context.startActivity(intent);
}
这样SecondActivity所需要的的数据在方法的参数中完全体现出来了,另外简化了启动SecondActivity的代码
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SecondActivity.actionStart(MainActivity.this,"data1","data2");
}
});
推荐阅读
-
Android学习笔记--Activity中使用Intent传值示例代码
-
Android学习笔记--使用剪切板在Activity中传值示例代码
-
Android学习笔记--使用剪切板在Activity中传值示例代码
-
Android学习笔记--Activity中使用Intent传值示例代码
-
温习Android基础知识——《第一行代码(第三版)》读书笔记 Chapter 14 高级技巧
-
荐 「「第一行代码(第二版)」」学习笔记 5 碎片(连载中)
-
《第一行代码》学习笔记:更强大的滚动控件——RecyclerView(增强版的 ListView)
-
第一行代码学习笔记:跨程序共享数据----内容提供器
-
《从零开始学Swift》学习笔记(Day1)——我的第一行Swift代码
-
温习Android基础知识——《第一行代码(第三版)》读书笔记 Chapter 10 Service