Activity的作用:加载UI布局,在活动间跳转。

活动Activity - 图1

活动Activity - 图2w

启动一个Activity 的几种方式

  1. startActivity(new Intent(当前Act.this,要启动的Act.class));
  1. ComponentName cn = new ComponentName("当前Act的全限定类名","启动Act的全限定类名") ;
  2. Intent intent = new Intent() ;
  3. intent.setComponent(cn) ;
  4. startActivity(intent) ;
  1. Intent intent = new Intent("android.intent.action.MAIN");
  2. intent.setClassName("当前Act的全限定类名","启动Act的全限定类名");
  3. startActivity(intent);

Activity如何

传递基本数据?

活动Activity - 图3

Activity, Task, Back Stack的一些概念

活动的状态

  • 运行状态:位于栈顶
  • 暂停: 不在栈顶,但是是可见的
  • 停止:不在栈顶,也不可见
  • 销毁:从栈中移除

activity的构成

image.png
实际上视图会被设置给一个Window类,这个Window中含有一个DecorView,这个DecorView才是整个窗口的顶级视图。开发人员设置的布局会被设置到这个DecorView的mContentParent布局中。也就是说Android中实际上内置了一些系统布局文件xml,我们在xml中定义的视图最终会被设置到这些系统布局的特定节点之下,这样就形成了整个DecorView。结构如图1-2所示。

activity的生命周期

  • onCreate() 创建时被的调用,通常会在这个函数中完成Activity的初始化操作,如设置布局、初始化视图、绑定事件等。
  • onStart() 由不可见到变成可见的时候调用.
  • onResume() 返回栈顶,与用户交互, 启用后Activity就会请求AMS渲染它所管理的视图
  • onPause() 系统去启动或者恢复另外一个activity的时候调用,也就是在Activity即将从可见状态变为不可见时。我们通常会在这个函数中将一些消耗CPU的资源释放掉,以及保存一些关键数据。
  • onStop() 活动完全不可见的时候调用。它和onPause()函数的主要区别在于,如果新启动的Activity是一个对话框式的Activity,那么onPause()函数会得到执行,而onStop() 函数并不会执行。
  • onDestroy() 销毁之前调用,释放内存。
  • onRestart() 重新调用

另一种分类方式:

  • 完整生存期
  • 可见生存期
  • 前台生存期

    活动被回收:

  • onSaveInstanceState()方法

  • onSaveInstanceState()方法会携带一个Bundle类型的参数,Bundle提供了一系列的方法用于保存数据,比如可以使用putString()方法保存字符串,使用putInt()方法保存整型数据,以此类推。每个保存方法需要传入两个参数,第一个参数是键,用于后面从Bundle中取值,第二个参数是真正要保存的内容。

活动的启动模式

用户可以在AndroidManifext.xml 注册Activity时设置它的启动模式
image.png

  • standard:在standard模式(即默认情况)下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。可能在栈中存在多个相同的activity。如果ActivityA是一个非常耗资源的类,那么将会使它所依附的应用消耗更多的系统资源。

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

  • singleTop: 如果一个以singleTop模式启动的Activity的实例已经存在于任务栈的栈顶,那么再启动这个Activity时,不会创建新的实例,而是重用位于栈顶的那个实例,并且会调用该实例的onNewIntent()函数将Intent对象传递到这个实例中。如果不在栈顶,则创建新的实例。

    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)

  • singleTask: singleTask模式是常用的启动模式,如果一个Activity设置了该启动模式,那么在一个任务栈中只能有一个该Activity的实例。如果任务栈中还没有该Activity,会新创建一个实例并放在栈顶。但是,如果已经存在Activity,系统会销毁处在该Activity上的所有Activity,最终让该Activity实例处于栈顶。最终让该Activity实例处于栈顶,同时回调该Activity的onNewIntent()函数。

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

  • singleInstance: 设置了singleInstance模式的Activity会在一个独立的任务中开启,并且这个新的任务中有且只有这一个实例,也就是说Activity会自动运行于另一个任务中。当再次启动该Activity实例时,会重用已存在的任务和实例。并且会调用该实例的onNewIntent()函数,将Intent实例传递到该实例中。

image.png
用intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)启动的activty一旦退出就不在栈中。

参考:
https://www.jianshu.com/p/537aa221eec4

一些技巧

  • 如何知晓当前在哪个活动?

重写onCreate()方法
image.png
Log.d() 第一个参数是tag,一般传入当前的类名就好,主要用于对打印信息进行过滤;第二个参数是msg,即想要打印的具体的内容。

  • 另一种注册监听器的方法

比较重要

  1. implements View.OnClickListener{}
  2. Button.SetOnClickListener()
  3. Override OnClick方法

image.png

BroadcastReceiver

BroadcastReceiver是一个广播机制,可以在应用程序间通信的全局大喇叭。

  • 分类:
    • 标准广播
    • 有序广播

活动Activity - 图9

  • 如何接收系统广播?2种注册广播的方式:
    • 动态注册
    • 静态注册

活动Activity - 图10
活动Activity - 图11
代码实现:动态注册监听系统的联网情况变化
自定义一个BroadcastReceiver,在onReceive()方法中完成广播要处理的事务,比如这里的提示Toast信息: MyBRReceiver.java

  1. public class MyBRReceiver extends BroadcastReceiver{
  2. @Override
  3. public void onReceive(Context context, Intent intent) {
  4. Toast.makeText(context,"网络状态发生改变~",Toast.LENGTH_SHORT).show();
  5. }
  6. }

MainActivity.java

  1. public class MainActivity extends AppCompatActivity {
  2. MyBRReceiver myReceiver;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. //核心部分代码:
  8. myReceiver = new MyBRReceiver();
  9. IntentFilter itFilter = new IntentFilter();
  10. itFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
  11. registerReceiver(myReceiver, itFilter);
  12. }
  13. //别忘了将广播取消掉哦~
  14. @Override
  15. protected void onDestroy() {
  16. super.onDestroy();
  17. unregisterReceiver(myReceiver);
  18. }
  19. }

代码实现:如何接受开机广播:静态注册

  1. public class BootCompleteReceiver extends BroadcastReceiver {
  2. private final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
  3. @Override
  4. public void onReceive(Context context, Intent intent) {
  5. if (ACTION_BOOT.equals(intent.getAction()))
  6. Toast.makeText(context, "开机完毕~", Toast.LENGTH_LONG).show();
  7. }
  8. }
  1. <receiver android:name=".BootCompleteReceiver">
  2. <intent-filter>
  3. <action android:name = "android.intent.cation.BOOT_COMPLETED">
  4. </intent-filter>
  5. </receiver>
  6. <!-- 权限 -->
  7. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Intent的基本使用

  • Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景.

    Intent使用分2种

  • 显示intent

  • 隐式intent

Intent有多个构造函数的重载,其中一个是Intent(ContextpackageContext, Class<? >cls)。这个构造函数接收两个参数,第一个参数Context要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动的目标活动,通过这个构造函数就可以构建出Intent的“意图”。然后我们应该怎么使用这个Intent呢?Activity类中提供了一个startActivity()方法,这个方法是专门用于启动活动的,它接收一个Intent参数,这里我们将构建好的Intent传入startActivity()方法就可以启动目标活动了。
**

  • startActivity(Intent)/startActivityForResult(Intent):来启动一个Activity
  • startService(Intent)/bindService(Intent):来启动一个Service
  • sendBroadcast:发送广播到指定BroadcastReceiver
  • 另外别忘了我们在注册四大组件时,写得很多的Intent-Filter哦~

Intent的7属性

  • ComponentName是组件名称

活动Activity - 图12

  • Action

活动Activity - 图13

  • Category

活动Activity - 图14

  • Data 和Type都是定义Action操作的数据类型的
  • Extras: 用于多个action之间的数据交换
  • Flags: 表示不同来源的标记