文章目录
1.活动的基本概念
活动:它是一种可以包含用户界面的组件,主要用于和用户进行交互。活动提供了应用程序绘制其UI的窗口。此窗口通常填充屏幕,但可能小于屏幕并浮动在其它窗口的顶部。通常一个应用活动在应用程序中实现一个屏幕。大多数应用包含多个屏幕,即多个活动,一般会指定一个活动为主要活动,及用户启动程序显示的第一个活动。
2.活动的基本用法
2.1活动创建的完整流程
1.新建活动,并重写活动的onCreate()方法。
2.新建一个布局文件,可以在其中绘制UI。
3.在活动中调用setContentView(布局文件)引入我们写好的布局。
4.进行注册,所有活动都需要在AndroidManifest.xml进行注册才能生效,活动的注册声明要放在 < application > 标签内,在< activity >标签中用android:name属性来指定是哪一个活动。
注意:任何有活动的应用程序都必须指定一个活动为主活动才能正常运行。
示例:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2.2在活动中使用Toast
Toast是一种提示方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后消失,并且不会占用任何屏幕空间。
语法:Toast.makeText(Context(上下文),String(要弹出的内容),显示的时长(Toast有两个内置常量可供选择)).show
2.3在活动中使用Menu
Menu可以帮助我们显示菜单项,且可以不占用任何屏幕空间。
创建方式:
1.在res目录下新建menu目录,然后在其中新建Menu resource file文件。
2.在文件中加入你想要的菜单项。
示例:
<item
android:id="@+id/back"//给菜单项注册点击事件时有用
android:title="Back" />//在菜单中该菜单项的名称
3.在活动中重写onCreateOptionsMenu()和onOptionsItemSelected()方法。
onCreateOpitionsMenu():该方法是为了在活动中加载菜单的布局,可以在其中调用getMenuInflater().inflate(菜单文件,menu)方法实现。
onOptionsItemSelected():该方法是为了给每一个菜单项注册点击事件用的,可以在其中用switch (item.getItemId())来表示各个菜单项,再在不同的case里注册点击事件即可。
2.4销毁一个活动
只需按一下Back键即可销毁当前活动,或是在活动中调用finish()方法(效果相当于按下Back)。
3.使用Intent实现跳转活动
要实现在不同的活动之间进行跳转共有两种方式:使用显示Intent,使用隐式Intent
3.1适用显示Intent
该方法直接指明要跳转的目标活动,因此称作显示Intent。
1.获得Intent实例,例:Intent intent=new Intent(Context,Class(指定想要启动的目标活动))。
2.调用startActivity(Intent)方法启动目标活动。
完整示例:
Intent intent=new Intent(MainActivity.this,SecoundActivity.class);
startActivity(intent);
3.2使用隐式Intent
该方法不直接指明要跳转的目标活动,而是用活动的配置信息来判断要启哪一个活动,因此称作隐式Intent。
1.给想要启动的活动配置信息。
示例:
<activity android:name=".SecoundActivity">
<intent-filter>
<action android:name="android.intent.action.MY_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
2.获得Intent实例,例:Intent intent=new Intent(String(action信息))。
3.调用intent.addCategory(String(category信息))方法给Intent配置category信息。
4.调用startActivity(Intent)方法启动活动。
完整示例:
Intent intent=new Intent("android.intent.action.MY_ACTION");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
注意:只有action于category信息同时匹配才会启动相应活动,每个活动只能配置一个action信息,但可以配置多个category信息。
4.实现活动之间的信息传递
一个应用程序的各个活动之间有时不仅仅是简单的跳转,还可能需要在一个活动中获取一些信息传递给下一个活动或者是返回上一个活动,接下来我们就来看看具体的实现方法。
4.1向下传递数据
事实上Intent不止可以用来启动一个活动,还可以暂存一些数据,启动了另一个活动后,只需将这些数据从Intent中取出即可。
1.调用intent.putExtra(键,值)方法将数据暂存在Intent中。
示例:
Intent intent=new Intent(MainActivity.this,SecoundActivity.class);
intent.putExtra("name","Tom");//注意这里是以键值对的形式存储的
startActivity(intent);
2.在下一个活动中,先获取Intent实例,再调用intent.getStringExtra(键)方法取出数据即可。
示例:
Intent intent=getIntent();
String name=intent.getStringExtra("name");//这里你想要获取的数据类型是什么就调用什么数据的get方法
4.2向上传递数据
1.在启动下一个活动时调用startActivityForResult(Intent,请求码)方法,该方法期望在第二个活动销毁时能返回一个结果给第一个活动。(请求码用于判断是哪一个活动返回的数据)
2.在第二个活动中获取Intent实例,再调用Intent.putExtra(键,值)方法存储数据,最后调用setResult(返回结果,Intent)。
示例:
Intent intent=new Intent();
intent.putExtra("name","Tom");
setResult(RESULT_OK,intent);
3.在第一个活动中重写onActivityResult()方法,当第二个活动销毁后,其所返回的数据就会进入该方法。当判断求起码和返回结果均正常后就可以调用intent.getStringExtra(键)方法取出数据了。
示例:
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 1:
if(resultCode==RESULT_OK){
String name;
name=data.getStringExtra("name");
}
break;
default:
}
}
5.活动的生命周期
5.1返回栈
Android的活动是可以层叠的,当我们启动一个新的活动就会覆盖原先的活动,然后当我们点击Back键就好销毁最上面的活动,下面的一个活动就会重新显示出来。
事实上Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也称作返回栈。系统总是会显示栈顶的活动给用户。
5.2活动状态
每个活动在其生命周期中最多可能会有4个状态。
-
1.运行状态
当一个活动位于返回栈的栈顶时,这是活动就处于运行状态。 -
2.暂停状态
当一个活动不再处于栈顶位置,但仍然可见时,这时活动就会处于暂停状态。 -
3.停止状态
当一个活动不再处于栈顶位置,且完全不可见时,就进入了停止状态。 -
4.销毁状态
当一个活动自从返回栈中移除后就变成了销毁状态。
5.3活动的生命周期
Activity类中定义了7个回调方法,覆盖了生命周期的每一个环节。
-
onCreate():该方法会在活动第一次被创建时调用,应该在该方法中完成活动的初始化操作。
-
onStart():该方法在活动由不可见变为可见时调用。
-
onResume():该方法在活动准备与用户进行交互时调用,此时活动一定处于栈顶且处于运行状态。
-
onPause():该方法在系统准备去启动或恢复另一个活动时调用。该方法的执行速度一定要快,否则会影响到新栈顶活动的使用。
-
onStop():该方法在活动完全不可见时调用,与onPause()方法的区别在于,若启动的新活动是一个对话框活动,那么onPause()方法会得到执行,而onStop()方法并不会执行。
-
onDestroy():该方法会在活动销毁前执行,之后活动的状态就会变为销毁状态。
-
onRestart():该方法会在活动由停止状态变为运行状态之前调用,也会就是活动被重新启动了。
活动的完整生命周期如下如图所示:
以上方法中除了onRestart()方法外都是两两相对的,从而又可以将活动分为3种生存期。
-
完整生存期:onCreate()方法和onDestroy()方法之间的所经历的就是完整生存期。
-
可见生存期:onStart()方法和onStop()方法之间所经历的就是可见生存期。活动对于用户总是可见的,即便可能无法与用户进行交互。
-
前台生存期:onResume()方法和onPause()方法之间所经历的就是前台生存期。活动总是处于运行状态,此时活动可以与用户进行交互。
5.4活动被收回了怎么办
如果一个活动进入了停止状态,那么该活动是有可能被系统回收的,因此可能会导致数据丢失。那么我们就来看看怎样才能在系统回收活动之前将数据保存起来。
1.重写onSaveInstanceState()方法,该方法可以保证在活动被回收之前获得调用,可以在其中调用putString(键,值)方法来保存数据。
示例:
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("name","Tom");//根据类型调用不同的方法
}
2.在活动的onCreate()方法中调用getString(键)方法取出数据。
示例:
if(savedInstanceState!=null){
String name=savedInstanceState.getString("name");
}
6.活动的启动模式
活动共有4种启动模式,分别是standard,singleTop,singleTask,singleInstance,可以在AndroidManifest.xml中通过给< activity >标签指定android:launchMode属性来选择启动模式。
-
standard:
默认模式,每当启动一个新的活动,就会在返回栈中入栈,并处于栈顶位置。该模式下无论这个活动是否在返回栈中存在,每次启动都会创建该活动的新实例。 -
singleTop:
该模式下,每当启动一个新的活动,如果发现返回栈的栈顶已是该活动,则可以直接使用它而不会再创建新的实例。 -
singleTask:
该模式下,每当启动一个新的活动,系统首先会在返回栈中检查是否存在该活动的实例,若存在就直接使用,并让该活动之上的所有活动出栈,若不存在则创建新的实例。 -
singleInstance
该模式下的活动会启用一个新的返回栈来管理这个活动。这个模式解决了其它程序和我们的程序共享一个活动实例的问题。
7.补充知识
7.1知晓当前是在哪一个活动
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
Log.e("MyActivity",getClass().getSimpleName());
super.onCreate(savedInstanceState);
}
}
新建一个java类MyActivity让其继承自AppCompatActivity类,并重写onCreate()方法让其打印当前实例的类名。最后让所有的活动都继承自MyActivity类即可。
7.2随时随地退出程序
//基础Activity类
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
Log.e("MyActivity",getClass().getSimpleName());
ActivityList.add(this);
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
ActivityList.remove(this);
super.onDestroy();
}
}
//Activity管理类
public class ActivityList {
private static List<Activity> list=new ArrayList<>();
public static void add(Activity activity){
list.add(activity);
}
public static void remove(Activity activity){
list.remove(activity);
}
public static void finishAll(){
for(Activity activity:list){
if(!activity.isFinishing()){
activity.finish();
}
}
}
}
当你想要彻底的退出程序时只需调用ActivityList.finishAll()方法即可。
7.3启动活动的最佳写法
public static void startActivity(Context context,String data1,String data2){
Intent intent=new Intent(context,SecoundActivity.class);
intent.putExtra("data1",data1);
intent.putExtra("data2",data2);
context.startActivity(intent);
}
在你想要启动的活动中加入该方法,参数上可以加上自己想要的各种参数。这样别人在启动你这个活动时,就知道需要传入哪些参数了。
7.4Bundle联合Intent一起传递参数
//存储数据
Bundle bundle=new Bundle();
bundle.putString("name","Tom");
Intent intent=new Intent(MainActivity.this,SecoundActivity.class);
intent.putExtras(bundle);
startActivity(intent);
//取出数据
Intent intent=getIntent();
Bundle bundle=intent.getExtras();
String name=bundle.getString("name");
在上述代码中,事实上可以把Bundle理解为一个封装数据的箱子,而传递时只需传递箱子即可。
7.5一些零散的问题
横竖屏切换时活动生命周期的变化
答:当屏幕发生横竖屏切换时会销毁当前活动并重新创建一个新的活动实例,活动周期变化如下:
onPause–>onStop–>onDestory–>onCreate–>onStart–>onResume。
Home键相关操作下活动生命周期的变化
答:按下Home键程序只是挂起并不会销毁,因此活动周期变化为:onPause–>onStop。
从手机App界面重新打开该活动,该活动会从停止状态变为运行状态,因此活动周期变化为:onRestart–>onStart–>onResume。
两个Activity之间跳转时必然会执行那些生命周期的回调方法
答:假设从A活动跳转到B活动。当我们从A活动中启动B活动,A活动执行onPause方法,B活动执行onCreate–>onStart–>onResume此时B活动覆盖了整个屏幕(B不为对话框类的活动),A再调用onStop方法。
前台切换到后台,再从后台切换到前台活动生命周期的流程
答:假设A,B两个活动之间的跳转。启动A活动:A活动执行onCreate–>onStart–>onResume;从A中启动B:A活动执行onPause方法,B活动执行onCreate–>onStart–>onResume,A活动再执行onStop方法;退出B活动A活动返回前台:B活动执行onPause方法,A活动执行onRestart–>onStart–>onResume,B再执行onStop–>onDestop。