Android四大组件-Activity

http://www.jianshu.com/p/7529faae9a37

 

一、基础知识回顾。

  • 定义及功能

    一个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-->
<activity  
Android:name=”.MainActivity”>  
<intent-filter>  
<action android:name=”android.intent.action.MAIN”/>  
<category android:name=”android.intent.category.LAUNCHER”/>  
</intent-filter>  
</activity>

 

主界面显示的Activity加入了<intent-filter>标签和内部的两句声明,这也是必须的。
<action>元素指定这是一个"main"入口点对这个应用程序。<category>元素指定,这个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:由停止状态变为运行状态之前调用。

    • 生命周期图

    • 详解

      在实际应用场景中,假设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一般使用方法:

<!--首先需要在注册第二个活动时加入标签-->
<!-- 必须指定CATEGORY_DEFAULT,只有这样startActivity(intent)才能找到 -->  
<!--注意 Intent Filter顾名思义就是Intent的过滤器,组件通过定义Intent Filter可以决定哪些隐式 -->  
<activity android:name=”.SecondAcivity”>  
<intent-filter>  
<action android:name=”包名.ACTION_START”/>  
<category android:name=”android.intent.category.DEFAULT”/>   
</intent-filter>  
</activity>

 

这样我们就可以用声明的标签来启动隐式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<Object>,可以把list强转成Serializable类型,而且object类型也必须实现了Serializable接口
Intent.putExtras(key, (Serializable)list)
接收
(List<YourObject>)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模式是默认的启动模式,不用为<activity>配置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界面。
      然后我们连续点击几次按钮,将会出现下面的现象

我们注意到都是FirstActivity的实例,但序列号不同,并且我们需要连续按后退键两次,才能回到第一个FristActivity。standard模式的原理如下图所示

    • 如图所示,每次跳转系统都会在task中生成一个新的FirstActivity实例,并且放于栈结构的顶部,当我们按下后退键时,才能看到原来的FirstActivity实例。
      这就是standard启动模式,不管有没有已存在的实例,都生成新的实例。

    • 详解singleTop

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

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

正如上图所示,跳转时系统会先在栈结构中寻找是否有一个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。演示结果如下:

我们看到,两个FirstActivity的序列号是不同的,证明从SecondActivity跳转到FirstActivity时生成了新的FirstActivity实例。原理图如下:

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

    • 详解singleTask

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

我们注意到,在上面的过程中,FirstActivity的序列号是不变的,SecondActivity的序列号却不是唯一的,说明从SecondActivity跳转到FirstActivity时,没有生成新的实例,但是从FirstActivity跳转到SecondActivity时生成了新的实例。singleTask模式的原理图如下图所示:

在图中的下半部分是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());

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

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

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

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

<activity android:name=".ShareActivity" android:launchMode="singleInstance">  
  <intent-filter>  
      <action android:name="android.intent.action.MAIN" />  
      <category android:name="android.intent.category.LAUNCHER" />  
  </intent-filter>  
  <intent-filter>  
      <action android:name="android.intent.action.SINGLE_INSTANCE_SHARE" />  
      <category android:name="android.intent.category.DEFAULT" />  
  </intent-filter>  
</activity>

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

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

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

  • 启动模式应用场景

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<ActivityManager.RunningAppProcessInfo> appList1 = mActivityManager  
        .getRunningAppProcesses();  
for (RunningAppProcessInfo running : appList1) {  
    System.out.println(running.processName);  
}  
System.out.println("================");  
//获得当前正在运行的service  
List<ActivityManager.RunningServiceInfo> appList2 = mActivityManager  
        .getRunningServices(100);  
for (ActivityManager.RunningServiceInfo running : appList2) {  
    System.out.println(running.service.getClassName());  
}  
System.out.println("================");  
//获得当前正在运行的activity  
List<ActivityManager.RunningTaskInfo> appList3 = mActivityManager  
        .getRunningTasks(1000);  
for (ActivityManager.RunningTaskInfo running : appList3) {  
    System.out.println(running.baseActivity.getClassName());  
}  
System.out.println("================");  
//获得最近运行的应用  
List<ActivityManager.RecentTaskInfo> 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:someone@domain.com"); 
Intent intent = new Intent(Intent.ACTION_SENDTO, uri); 
startActivity(intent); 
//给someone@domain.com发邮件发送内容为“Hello”的邮件 
Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra(Intent.EXTRA_EMAIL, "someone@domain.com"); 
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 = {"1@abc.com", "2@abc.com"}; // 收件人 
String[] ccs = {"3@abc.com", "4@abc.com"}; // 抄送 
String[] bccs = {"5@abc.com", "6@abc.com"}; // 密送 
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);

 

posted @ 2017-04-10 23:28  qlky  阅读(410)  评论(0编辑  收藏  举报