Android实习生 —— 四大组件之Activity

Android实习生 —— 四大组件之Activity_第1张图片

目录

一、基础知识回顾。
    1.定义及功能
    2.启动和栈
    3.基本用法
    4.创建和注册
二、生命周期。
    1.四种状态
    2.七个回调方法
    3.生命周期图
    4.详解
    5.扩展
三、Activity跳转(Intent)。
    1.可以开启另一个Activity通过传递一个Intent并且startActivity()方法启动它。描述了你希望启动的Activity。
    (1)显示Intent一般使用方法
    (2)隐式Intent一般使用方法
    (3)两者的使用区别
    2.Intent可以指定你希望启动或描述完成的动作(操作系统会为你选择合适的Activity,可能来自定不同的应用程序)。
一个Intent可以传输小量数据被启动的activity使用。
    (1)Intent传递String字符串
    (2)Intent传递Bundle对象
    (3)Intent传递Object对象(Serializable接口Parcelable接口)
        【补充】parcelable和Serializable的区别
    3.Activity退出时返回结果至前一个Activity
四、启动模式。
    1.standard、singleTop、singleTask、singleInstance
    详解standard
    详解singleTop
    详解singleTask
    详解singleInstance
    2.启动模式应用场景
    3.总结
五、其他补充
    1.Activity中finish() onDestroy() 和System.exit()的区别
    2.AppCompatActivity、ActionBarActivity、FragmentActivity和Activity的区别
    3.资源内存不足导致低优先级Activity被杀死
    4.ActivityManager--获得正在运行的activity与service.
【附录】
    常用Intent意图表

一、基础知识回顾。

  • 定义及功能

一个Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,例如拨号、拍照、发送email、看地图。每一个activity被给予一个窗口,在上面可以绘制用户接口。窗口通常充满屏幕,但也可以小于屏幕而浮于其它窗口之上。

  • 启动和栈

一个应用程序通常由多个activities组成,他们通常是松耦合关系。通常,一个应用程序中的activity被指定为"main"activity,当第一次启动应用程序的时候呈现给用户的那个activity。每一个activity然后可以启动另一个activity为了完成不同的动作。每一次一个activity启动,前一个activity就停止了,但是系统保留activity在一个栈上(“back stack”)。当一个新activity启动,它被推送到栈顶,取得用户焦点。Back Stack符合简单“后进先出”原则,所以,当用户完成当前activity然后点击back按钮,它被弹出栈(并且被摧毁),然后之前的activity恢复。

  • 基本用法

基本用法:Activity的本质是一个Java类,如:由我们创建工程生成的MainActivity;一般的每个Activity都会存在一个与它匹配的布局文件(xml文件),由它来写入我们需要Activity展示的各种控件和布局。有了布局文件之后,就需要在类里通过OnCreate方法的setContentView方法调用文件资源ID来初始化UI界面和显示。

  • 创建和注册

每个需要显示的Activity都需要我们在工程包下的AndroidMainifest.xml文件进行注册!(注意:程序每次打开时显示的Activity我们称为主界面,它的注册和其他Activity注册有区别)


  
  
  
  
  
  

主界面显示的Activity加入了标签和内部的两句声明,这也是必须的。
元素指定这是一个"main"入口点对这个应用程序。元素指定,这个activity应该被列入系统应用程序列表中(为了允许用户启动这个activity)。
此外如果你的应用程序里没有声明任何主活动,它也是可以安装的,只是你无法在启动器中看见或打开,这种程序一般作为第三方服务供其他应用在内部进行调用,如支付宝的快捷支付应用。

二、生命周期。

  • 四种状态

运行状态:当Activity位于栈顶时,此时正好处于屏幕最前方。
暂停状态:当Activity失去了焦点但仍然对用于可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕)。
停止状态:当Activity被其他Activity完全遮挡,此时此Activity对用户不可见。
销毁状态:当Activity由于人为或系统原因(如低内存等)被销毁。

  • 七个回调方法

1.onCreate:活动第一次创建被调用。
2.onStart:活动由不可见变为可见的时候调用。
3.onResume:活动处于与用户交互状态时候调用。
4.onPause:活动失去焦点时被调用。
5.onStop:活动完全不可见的时候调用(如果新活动是一个对话框式活着半透明的活动,onPause会执行,而onStop不会执行)。
6.onDestroy:在活动被销毁之前调用。
7.onRestart:由停止状态变为运行状态之前调用。

  • 生命周期图

Android实习生 —— 四大组件之Activity_第2张图片
生命周期图
  • 详解

在实际应用场景中,假设A Activity位于栈顶,此时用户操作,从A Activity跳转到B Activity。那么对AB来说,具体会回调哪些生命周期中的方法呢?回调方法的具体回调顺序又是怎么样的呢?
开始时,A被实例化,执行的回调有A:onCreate -> A:onStart -> A:onResume。
当用户点击A中按钮来到B时,假设B全部遮挡住了A,将依次执行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop。
此时如果点击Back键,将依次执行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。
至此,Activity栈中只有A。在Android中,有两个按键在影响Activity生命周期这块需要格外区分下,即Back键和Home键。我们先直接看下实验结果:
此时如果按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。
此时如果按下Home键(非长按),系统返回到桌面,并依次执行A:onPause -> A:onStop。由此可见,Back键和Home键主要区别在于是否会执行onDestroy。

  • 扩展

不少应用程序都是采取如Home键的效果,当点击了Back键,系统返回到桌面,然后点击应用程序图标,直接回到之前的Activity界面,这种效果是怎么实现的呢?
通过重写按下Back键的回调函数,转成Home键的效果即可。

@Override
public void onBackPressed() {
    Intent home = new Intent(Intent.ACTION_MAIN);
    home.addCategory(Intent.CATEGORY_HOME);
    startActivity(home);
}

当然,此种方式通过Home键效果强行影响到Back键对Activity生命周期的影响。注意,此方法只是针对按Back键需要退回到桌面时的Activity且达到Home效果才重写。
或者,为达到此类效果,Activity实际上提供了直接的方法。
activity.moveTaskToBack(true);
moveTaskToBack()此方法直接将当前Activity所在的Task移到后台,同时保留activity顺序和状态。

三、Activity跳转(Intent)。

  • 可以开启另一个Activity通过传递一个Intent并且startActivity()方法启动它。描述了你希望启动的Activity。

Intent的两种用法:显示Intent和隐式Intent。
(1)显示Intent一般使用方法:

Intent intent=newIntent(FirstActivity.this,SecondActivity.class);  
startActivity(intent);  
//简单的两行就能实现第一个活动跳转到第二个活动界面。

(2)隐式Intent一般使用方法:


  
  
  
  
  
   
  
  

这样我们就可以用声明的标签来启动隐式Intent

Intent intent=new Intent(“包名.ACTION_START”);  
startActivity(intent);  

(3)两者的使用区别
显式意图一般在应用的内部使用,因为在应用内部已经知道了组件的名称,直接调用就可以了。当一个应用要激活另一个应用中的Activity时,只能使用隐式意图,根据Activity配置的意图过滤器建一个意图,让意图中的各项参数的值都跟过滤器匹配,这样就可以激活其他应用中的Activity。所以,隐式意图是在应用与应用之间使用的。

  • Intent可以指定你希望启动或描述完成的动作(操作系统会为你选择合适的Activity,可能来自定不同的应用程序)。

你的应用程序或许希望执行一些动作,例如发送一份邮件、文件消息或者状态更新,使用你的Activity的数据。在这种情况下,你的应用程序或许没有它自己的Activity来完成这个动作,因此你可以促使设备上其它应用程序提供的Activity来完成你的动作。这才是Intent真正有价值的地方--你可以创建一个Intent描述一个你希望执行的动作,然后系统启动一个合适的activity从其它应用程序。如果有多种Activities可以处理这个Intent,那么 用户可以选择哪一个来执行。例如,如果你希望允许用户发送邮件,你可以创建下面的Intent:

Intent intent= new Intent(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_EMAIL,"");
        startActivity(intent);

(常用意图见文章末尾附录。)

  • 一个Intent可以传输小量数据被启动的activity使用。

在启动活动时,Intent中提供了一系列putExtra()方法的重载,可以将我们需要传递的数据暂存在Intent中,在打开另一个活动时,从Intent中取出即可。
具体例子:
(1)比如我们想要传递一个String字符串

String data=”Hello world!”;  
Intent intent=newIntent(FirstActivity.this,SecondActivity.class);  
Intent.putExtra(“extra_data”,data);
//extra_data是一个标签,data是传入的数据。 
//相当于Intent对象具有Map键值对功能。
startActivity(intent);  

然后在SecondActivity的Oncreate方法里取出Intent存入的数据

Intent intent=getIntent();  
String data=intent.getStringExtra(“extra_data”);
//用String接收带extra_data标签的数据  
Log.d(“SecondActivity”,data);//打印出data  

(2)新建一个Bundle对象 ,想该对象中加入键值对,然后将该对象加入Intent中

Intent intent=new Intent();
Bundle bundle = new Bundle();  
bundle.putString("first", "zhang");  
bundle.putInt("age", 20);  
intent.putExtras(bundle);  
intent.setClass(ActivityMain.this, SecondActivity.class);
intent.putExtras(bundle);
startActivity(intent);   

然后在第二个Activity中接收

Bundle bundle = new Bundle();
bundle = this.getIntent().getExtras();
String a = bundle.getString("first");
int b = Integer.parseInt(bundle.getString("age"));

(3)Intent传递Object对象

Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象。要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。Intent中传递这2种对象的方法:

Bundle.putSerializable(Key,Object);  //实现Serializable接口的对象
Bundle.putParcelable(Key, Object); //实现Parcelable接口的对象

以下以最常用的Serializable方式为例 :

假设由登录界面(Login)跳转到主界面(MainActivity)传递的对象为登录的用户信息 User类

首先创建一个序列化类:User

    import java.io.Serializable;
    public class User implements Serializable {
    private int ID;
    private String UserName;    
    private String PWD;    
    public final void setID(int value)
    {
        ID = value;
    }
    public final int getID()
    {
        return ID;
    }    
    public final void setUserName(String value)
    {
        UserName = value;
    }
    public final String getUserName()
    {
        return UserName;
    }  
    public final void setPWD(String value)
    {
        PWD = value;
    }
    public final String getPWD()
    {
        return PWD;
    }    
}

MainActivity传递内容

Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("user", user);
intent.putExtras(bundle);
this.startActivity(intent);

SecondActivity接收

Intent intent = this.getIntent(); 
user=(User)intent.getSerializableExtra("user");

以上就可以实现对象的传递。
补充:
如果传递的是List,可以把list强转成Serializable类型,而且object类型也必须实现了Serializable接口
Intent.putExtras(key, (Serializable)list)
接收
(List)getIntent().getSerializable(key)

【补充】
parcelable和Serializable的区别又是什么呢?
Serializable的作用是保存对象的属性到本地文件,数据库,网络流等方便数据传输,也可程序之间传递。

parcelable的设计的目的是为了解决Serializable效率不高的问题,内存开销小,所以在内存间传递数据的方式用parcelable,缺点是不能持久化。

  • Activity退出时返回结果至前一个Activity
//  1.通过startActivityForResult方式启动一个新Activity 
Intent intent=newIntent(FirstActivity,this,SecondActivity.class);   
startActivityForResult(intent, 200);  
//参数为intent对象, requestCode请求码
//  2.新Activity设定setResult方法,通过该方法可以传递responseCode 和 Intent对象  
Intent intent=new Intent();  
//Intent中也可以传递Bundle
Intent.putExtra(“data_return”,”Helloworld!”);  
setResult(101,intent);  
 //参数为responseCode响应码 和 intent对象  
finish();  
//  3.在MainActivity中覆写onActivityResult方法,新Activity一旦退出,就会执行该方法  
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
super.onActivityResult(requestCode, resultCode, data);
        //如果请求标识与返回标识一样,则把数据返回到tv上
        if (requestCode == 200 & resultCode ==101) {
            String s = data.getStringExtra("data_return");
            tv.setText(s);
        }
}  

四、启动模式。

  • standard、singleTop、singleTask、singleInstance

standard(标准模式):每当启动一个新活动,它都会进入返回栈并位于栈顶的位置,这种模式下,系统不会在乎这个活动是否已经存在于返回栈中,每次启动都会创建并都放在栈顶。

singleTop(栈顶复用):在启动活动时如果发现栈中该活动已经位于栈顶,则重用该实例( 会调用实例的onNewIntent() )而不会创建新的实例。若不在栈顶,则会创建新的实例。

singleTask(栈内复用):启动活动时如果发现栈中已经存在该活动,则重用该实例(会调用实例的 onNewIntent() ),并且将位于它之上的活动统统出栈,如果没有发现就会新建一个实例。

singleIntance(单例模式):会有一个单独的返回栈来管理这个活动,而且栈中只有此活动,不管是任何一个程序来访问这个活动,都共用这个返回栈,也就解决了共享活动的问题。

设置方法:在AndroidMainifest.xml文件中activity标签name之下加入声明:Android:launchMode=” standard、singleTop、singleTask、singleInstance(四选一)”这样就可以配置活动的启动模式了。
  • 详解standard

standard模式是默认的启动模式,不用为配置android:launchMode属性即可,当然也可以指定值为standard。
我们将会一个Activity,命名为FirstActivity,来演示一下标准的启动模式。FirstActivity代码如下:

public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.first);  
        TextView textView = (TextView) findViewById(R.id.textView);  
        textView.setText(this.toString());  
        Button button = (Button) findViewById(R.id.button);  
        button.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Intent intent = new Intent(FirstActivity.this, FirstActivity.class);  
                startActivity(intent);  
            }  
        });  
    }  

我们FirstActivity界面中的TextView用于显示当前Activity实例的序列号,Button用于跳转到下一个FirstActivity界面。
然后我们连续点击几次按钮,将会出现下面的现象

Android实习生 —— 四大组件之Activity_第3张图片
跳转

我们注意到都是FirstActivity的实例,但序列号不同,并且我们需要连续按后退键两次,才能回到第一个FristActivity。standard模式的原理如下图所示
Android实习生 —— 四大组件之Activity_第4张图片
跳转
如图所示, 每次跳转系统都会在task中生成一个新的FirstActivity实例,并且放于栈结构的顶部,当我们按下后退键时,才能看到原来的FirstActivity实例。
这就是standard启动模式,不管有没有已存在的实例,都生成新的实例。

  • 详解singleTop

我们在上面的基础上为指定属性android:launchMode="singleTop",系统就会按照singleTop启动模式处理跳转行为。我们重复上面几个动作,将会出现下面的现象:


Android实习生 —— 四大组件之Activity_第5张图片
跳转

我们看到这个结果跟standard有所不同,三个序列号是相同的,也就是说使用的都是同一个FirstActivity实例;如果按一下后退键,程序立即退出,说明当前栈结构中只有一个Activity实例。singleTop模式的原理如下图所示:


Android实习生 —— 四大组件之Activity_第6张图片
跳转

正如上图所示,跳转时系统会先在栈结构中寻找是否有一个FirstActivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。也许朋友们会有疑问,我只看到栈内只有一个Activity,如果是多个Activity怎么办,如果不是在栈顶会如何?我们接下来再通过一个示例来证实一下大家的疑问。
我们再新建一个Activity命名为SecondActivity,如下:
 protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.second);  
        TextView textView = (TextView) findViewById(R.id.textView);  
        textView.setText(this.toString());  
        Button button = (Button) findViewById(R.id.button);  
        button.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Intent intent = new Intent(SecondActivity.this, FirstActivity.class);  
                startActivity(intent);                
            }  
        });  
    }  

然后将之前的FirstActivity跳转代码改为:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);  
startActivity(intent); 

是的,FirstActivity会跳转到SecondActivity,SecondActivity又会跳转到FirstActivity。演示结果如下:

Android实习生 —— 四大组件之Activity_第7张图片
跳转

我们看到,两个FirstActivity的序列号是不同的,证明从SecondActivity跳转到FirstActivity时生成了新的FirstActivity实例。原理图如下:
Android实习生 —— 四大组件之Activity_第8张图片
跳转

我们看到, 当从SecondActivity跳转到FirstActivity时,系统发现存在有FirstActivity实例,但不是位于栈顶,于是重新生成一个实例。
这就是singleTop启动模式,如果发现有对应的Activity实例正位于栈顶,则重复利用,不再生成新的实例。

  • 详解singleTask

在上面的基础上我们修改FirstActivity的属性android:launchMode="singleTask"。演示的结果如下:

Android实习生 —— 四大组件之Activity_第9张图片
跳转

我们注意到,在上面的过程中,FirstActivity的序列号是不变的,SecondActivity的序列号却不是唯一的,说明从SecondActivity跳转到FirstActivity时,没有生成新的实例,但是从FirstActivity跳转到SecondActivity时生成了新的实例。singleTask模式的原理图如下图所示:
Android实习生 —— 四大组件之Activity_第10张图片
跳转

在图中的下半部分是SecondActivity跳转到FirstActivity后的栈结构变化的结果,我们注意到, SecondActivity消失了,没错,在这个跳转过程中系统发现有存在的FirstActivity实例, 于是不再生成新的实例,而是将FirstActivity之上的Activity实例统统出栈,将FirstActivity变为栈顶对象,显示到幕前。也许朋友们有疑问,如果将SecondActivity也设置为singleTask模式,那么SecondActivity实例是不是可以唯一呢?在我们这个示例中是不可能的,因为每次从SecondActivity跳转到FirstActivity时,SecondActivity实例都被迫出栈,下次等FirstActivity跳转到SecondActivity时,找不到存在的SecondActivity实例,于是必须生成新的实例。但是如果我们有ThirdActivity,让SecondActivity和ThirdActivity互相跳转,那么SecondActivity实例就可以保证唯一。
这就是singleTask模式,如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。

  • 详解singleInstance

这种启动模式比较特殊,因为它会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。
我们修改FirstActivity的launchMode="standard",SecondActivity的launchMode="singleInstance",由于涉及到了多个栈结构,我们需要在每个Activity中显示当前栈结构的id,所以我们为每个Activity添加如下代码:

TextView taskIdView = (TextView) findViewById(R.id.taskIdView);  
taskIdView.setText("current task id: " + this.getTaskId());  

然后我们再演示一下这个流程:


Android实习生 —— 四大组件之Activity_第11张图片
跳转

我们发现这两个Activity实例分别被放置在不同的栈结构中,关于singleInstance的原理图如下:


Android实习生 —— 四大组件之Activity_第12张图片
跳转

我们看到从FirstActivity跳转到SecondActivity时,重新启用了一个新的栈结构,来放置SecondActivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在SecondActivity中再次跳转到FirstActivity,这个时候系统会在原始栈结构中生成一个FirstActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?是因为从SecondActivity跳转到FirstActivity的时候,我们的起点变成了SecondActivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。
如果我们修改FirstActivity的launchMode值为singleTop、singleTask、singleInstance中的任意一个,流程将会如图所示:
Android实习生 —— 四大组件之Activity_第13张图片
跳转

singleInstance启动模式可能是最复杂的一种模式,为了帮助大家理解,我举一个例子,假如我们有一个share应用,其中的ShareActivity是入口Activity,也是可供其他应用调用的Activity,我们把这个Activity的启动模式设置为singleInstance,然后在其他应用中调用。我们编辑ShareActivity的配置:

  
      
          
          
      
      
          
          
      
  

然后我们在其他应用中这样启动该Activity:

Intent intent = new Intent("android.intent.action.SINGLE_INSTANCE_SHARE");  
startActivity(intent);  

当我们打开ShareActivity后再按后退键回到原来界面时,ShareActivity做为一个独立的个体存在,如果这时我们打开share应用,无需创建新的ShareActivity实例即可看到结果,因为系统会自动查找,存在则直接利用。大家可以在ShareActivity中打印一下taskId,看看效果。关于这个过程,原理图如下:


Android实习生 —— 四大组件之Activity_第14张图片
跳转
  • 启动模式应用场景

singleTop适合接收通知启动的内容显示页面。例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。所以要从外界尽可能多的跳转到一个界面。

singleTask适合作为程序入口点。例如浏览器的主界面、联系人activity。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。

singleInstance适合需要与程序分离开的页面。这种模式的使用情况比较罕见,例如闹铃提醒,将闹铃提醒与闹铃设置分离。呼叫来电界面。
singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,再次启动,首先打开的是B。

  • 总结

LauncherMode 分为两组:
第一组standard和SingleTop是一组用的比较多,他们二个唯一的区别就是SingleTop如果在当前Task的顶部,同时在startActivity()这个Activity的时候就不会再创建新的实例,而是执行该实例的onNewIntent()方法,其他情况下的用法是一样的;
第二组SingleTask和SingleIntance这一组用的比较少,要结合特定情况来使用,这一组的使用区别是比较大的,在我们开发APP的过程中要合理的使用Activity的启动模式来使我们的APP更加的快捷,流畅,提高用户体验。如果有写的不好的还忘指点。

五、其他补充

  • Activity中finish() onDestroy() 和System.exit()的区别

Activity.finish()
Call this when your activity is done and should be closed.
在你的activity动作完成的时候,或者Activity需要关闭的时候,调用此方法。当你调用此方法的时候,系统只是将最上面的Activity移出了栈,并没有及时的调用onDestory()方法其占用的资源也没有被及时释放。因为移出了栈,所以当你点击手机上面的“back”按键的时候,也不会再找到这个Activity。

Activity.onDestory()
the system is temporarily destroying this instance of the activity to save space.
系统销毁了这个Activity的实例在内存中占据的空间。
在Activity的生命周期中,onDestory()方法是他生命的最后一步,资源空间等就被回收了。当重新进入此Activity的时候,必须重新创建,执行onCreate()方法。

System.exit(0)
这玩意是退出整个应用程序的,是针对整个Application的。将整个进程直接KO掉。

finish函数仅仅把当前Activity退出了,但是并没有释放他的资源。安卓系统自己决定何时从内存中释放应用程序。当系统没有可用内存到时候,会按照优先级,释放部分应用。

  • AppCompatActivity、ActionBarActivity、FragmentActivity和Activity的区别

support v4 FragmentActivity 兼容2.x模式下使用Fragment
support v7 AppCompatActivity 兼容2.x模式下使用Fragment和ActionBar,ActionBarActivity是AppCompatActivity过时产品
如果3.0以上直接继承Activity,便可使用Fragment和ActionBar

  • 资源内存不足导致低优先级Activity被杀死

Activity优先级
前台Activity——正在和用户交互的Activity,优先级最高
可见但非前台Activity——Activity中弹出的对话框导致Activity可见但无法交互
后台Activity——已经被暂停的Activity,优先级最低
系统内存不足是,会按照以上顺序杀死Activity,并通过onSaveInstanceState和onRestoreInstanceState这两个方法来存储和恢复数据。

  • ActivityManager--获得正在运行的activity、service、进程、最近运行的应用。
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE) ;    
//获得系统运行的进程  
List appList1 = mActivityManager  
        .getRunningAppProcesses();  
for (RunningAppProcessInfo running : appList1) {  
    System.out.println(running.processName);  
}  
System.out.println("================");  
//获得当前正在运行的service  
List appList2 = mActivityManager  
        .getRunningServices(100);  
for (ActivityManager.RunningServiceInfo running : appList2) {  
    System.out.println(running.service.getClassName());  
}  
System.out.println("================");  
//获得当前正在运行的activity  
List appList3 = mActivityManager  
        .getRunningTasks(1000);  
for (ActivityManager.RunningTaskInfo running : appList3) {  
    System.out.println(running.baseActivity.getClassName());  
}  
System.out.println("================");  
//获得最近运行的应用  
List appList4 = mActivityManager  
        .getRecentTasks(100, 1);  
for (ActivityManager.RecentTaskInfo running : appList4) {  
    System.out.println(running.origActivity.getClassName());  
    } 

【附录】

  • 常用Intent意图表
(1).调用拨号程序
Uri uri = Uri.parse("tel:10086"); 
Intent intent = new Intent(Intent.ACTION_DIAL, uri); 
startActivity(intent); 
(2).发送短信或者彩信
//发生短信
Uri uri = Uri.parse("smsto:10086"); 
Intent intent = new Intent(Intent.ACTION_SENDTO, uri); 
intent.putExtra("sms_body", "Hello"); 
startActivity(intent); 
//发送彩信,相当于发送带附件的短信
Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra("sms_body", "Hello"); 
Uri uri = Uri.parse("content://media/external/images/media/23"); 
intent.putExtra(Intent.EXTRA_STREAM, uri); 
intent.setType("image/png"); 
startActivity(intent); 
(3).通过浏览器打开网页
Uri uri = Uri.parse("http://www.google.com"); 
Intent intent  = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent);
(4).发送电子邮件
Uri uri = Uri.parse("mailto:[email protected]"); 
Intent intent = new Intent(Intent.ACTION_SENDTO, uri); 
startActivity(intent); 
//给[email protected]发邮件发送内容为“Hello”的邮件 
Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra(Intent.EXTRA_EMAIL, "[email protected]"); 
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject"); 
intent.putExtra(Intent.EXTRA_TEXT, "Hello"); 
intent.setType("text/plain"); 
startActivity(intent); 
// 给多人发邮件 
Intent intent=new Intent(Intent.ACTION_SEND); 
String[] tos = {"[email protected]", "[email protected]"}; // 收件人 
String[] ccs = {"[email protected]", "[email protected]"}; // 抄送 
String[] bccs = {"[email protected]", "[email protected]"}; // 密送 
intent.putExtra(Intent.EXTRA_EMAIL, tos); 
intent.putExtra(Intent.EXTRA_CC, ccs); 
intent.putExtra(Intent.EXTRA_BCC, bccs); 
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject"); 
intent.putExtra(Intent.EXTRA_TEXT, "Hello"); 
intent.setType("message/rfc822"); 
startActivity(intent); 
(5).显示地图与路径规划
// 打开Google地图中国北京位置(北纬39.9,东经116.3) 
Uri uri = Uri.parse("geo:39.9,116.3"); 
Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent); 
// 路径规划:从北京某地(北纬39.9,东经116.3)到上海某地(北纬31.2,东经121.4) 
Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9 116.3&daddr=31.2 121.4"); 
Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent); 
(6).播放多媒体
Intent intent = new Intent(Intent.ACTION_VIEW); 
Uri uri = Uri.parse("file:///sdcard/foo.mp3"); 
intent.setDataAndType(uri, "audio/mp3"); 
startActivity(intent); 
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); 
Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent); 
(7).拍照
// 打开拍照程序 
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
startActivityForResult(intent, 0); 
// 取出照片数据 
Bundle extras = intent.getExtras();  
Bitmap bitmap = (Bitmap) extras.get("data"); 
(8).获取并剪切图片
// 获取并剪切图片 
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
intent.setType("image/*"); 
intent.putExtra("crop", "true"); // 开启剪切 
intent.putExtra("aspectX", 1); // 剪切的宽高比为1:2 
intent.putExtra("aspectY", 2); 
intent.putExtra("outputX", 20); // 保存图片的宽和高 
intent.putExtra("outputY", 40);  
intent.putExtra("output", Uri.fromFile(new File("/mnt/sdcard/temp"))); // 保存路径 
intent.putExtra("outputFormat", "JPEG");// 返回格式 
startActivityForResult(intent, 0); 
// 剪切特定图片 
Intent intent = new Intent("com.android.camera.action.CROP");  
intent.setClassName("com.android.camera", "com.android.camera.CropImage");  
intent.setData(Uri.fromFile(new File("/mnt/sdcard/temp")));  
intent.putExtra("outputX", 1); // 剪切的宽高比为1:2 
intent.putExtra("outputY", 2); 
intent.putExtra("aspectX", 20); // 保存图片的宽和高 
intent.putExtra("aspectY", 40); 
intent.putExtra("scale", true); 
intent.putExtra("noFaceDetection", true);  
intent.putExtra("output", Uri.parse("file:///mnt/sdcard/temp"));  
startActivityForResult(intent, 0); 
(9).打开Google Market
// 打开Google Market直接进入该程序的详细页面 
Uri uri = Uri.parse("market://details?id=" + "com.demo.app"); 
Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent); 
(10).安装和卸载程序
Uri uri = Uri.fromParts("package", "com.demo.app", null);   
Intent intent = new Intent(Intent.ACTION_DELETE, uri);   
startActivity(intent); 
(11).进入设置界面
// 进入无线网络设置界面(其它可以举一反三)   
Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
startActivityForResult(intent, 0); 

整理作者:汪博
少壮不努力,老大徒悲伤。
本文为Android学习规划打造,如有不好的地方请多多指教。

Android实习生 —— 四大组件之Activity_第15张图片

你可能感兴趣的:(Android实习生 —— 四大组件之Activity)