Android基础再回首——四大组件之Activity、Service俩兄弟

来源:互联网 发布:网络割接回退方案 编辑:程序博客网 时间:2024/04/24 20:35

Android基础再回首——四大组件之Activity、Service俩兄弟

偶尔的回首过去,总是有不一样的收获。今天就来回顾下Activity和service吧,不用嫌弃太基础了,打好基础是取得成功的一切源泉,加油!

Android中最重要的是四大组件,即Activity、Service、ContenProvider、Broadcast。这4个组件分工明确,共同构成了可重用、灵活、低耦合的Android系统。

  • Activity负责UI元素的加载与页面之间的跳转,代表了一个页面单元。
  • Service负责与UI无关的工作,如在后台执行耗时操作等。
  • ContentProvider负责存储、共享数据,使得数据可以在多个应用之间共享。
  • Broadcast则是在各个组件、应用之间进行通信,简化了Android开发中的通信问题。

1.1Activity

Activity大家应该都非常熟悉了,它在应用中就是一个用户界面,Activity可以在不同的Activity之间跳转,将不同的页面串连在一起,共同完成特定的操作流程。每个应用都是有一个或者多个Activity组成,它是Android应用程序中不可缺少的部分。

每个Activity都有生命周期,在不同的阶段会调用不同的生命周期函数,我们来一起学习Activity的生命周期。

  • onCreate( )

    我们在创建继承自Activity的类时都会默认生成这个函数。它会在Activity第一次被创建时调用,通常会在这个函数中完成Activity的初始化操作,如设置布局、初始化视图、绑定事件等。

  • onStrart( )

    这个函数在Activity的onCreate函数调用之后被调用,此时的Activity还处在不可见状态,它的下一个状态就是Activity变得可见的时候,也就是这个函数在Activity可见之前被调用

  • onResume( )

    这个函数在Activity变为可见时被调用,执行完onResume之后,Activity就会请求AMS渲染它所管理的视图。此时的Activity一定位于返回栈的栈顶,并且处于运行状态。

  • onPause( )

    这个函数在系统准备去启动或者恢复另一个Activity时调用,也就是在Activity即将从可见状态变为不可见时。我们通常会在这个函数中将一些消耗CPU的资源释放掉,以及保存一些关键数据。

  • onStop( )

    这个函数在Activity完全不可见时调用。它和onPause()函数的主要区别在于,如果新启动的Activity是一个对话框的Activity,那么onPause()函数会得到执行,而onStop()函数并不会执行。

  • onDestory( )

    这个函数在Activity被销毁之前调用,之后Activity的状态将变为销毁状态

  • onRestart( )

    这个函数在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。

从onCreate()函数到onDestory()函数运行的时期就是一个Activity的完整生命周期。一般情况下,我们会在一个Activity的onCreate()函数中完成各种初始化操作,而在onDestroy()函数中完成释放内存的操作。

  • Activity生命周期图

这里写图片描述

1.2Activity的四种启动模式

每个应用程序都是由一个或者多个Activity组成,因此,Activity内部通过返回栈来管理Activity实例。
栈是一种后进先出的集合,对于Activity来说,当前显示的Activity就在栈顶,当用户点击后退键或者点击应用的返回按钮,系统就会将栈顶的Activity出栈,此时原来栈顶下的Activity就会变为栈顶显示到设备上。

当然我们遇到的情况并不是那么简单,在一些特殊情况下我们可能需要对Activity实例做一些特殊的处理。所以Activity系统为我们提供了这些功能,也就是Activity的四种启动模式。用户可以在ActivityMainfext.xml注册Activity时设置他的启动模式。比如:

    <activity         android:name=".MainActivity"        android:launchMode="singTask"        adnroid:label="@string/app_name">    </activity>

Activity的4种启动模式分别为standard、singleTop、singleTask、singleInstance,下面我们逐个介绍他们

  • 1、standard(标准启动模式)

    这是Activity的标准启动模式,也是Activity的默认启动模式。在这种模式下启动的Activity可以被多次实例化,即在同一个任务栈中可以存在多个Activity实例,每个实例都会处理一个Intent对象。如果ActivityA的启动模式为standard,并且已经有一个ActivityA被启动,在该ActivityA中调用startActivity时会启动一个新的ActivityA实例。

  • 2、singleTop(栈顶复用模式)

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

    例如,ActivityA的启动模式为singleTop,并且ActivityA的一个实例已经存在于栈顶中。那么再调用startActivity启动另一个ActivityA时,不会再次创建ActivityA的实例,而是重用原来的实例,并且调用原来实例的onNewIntent()方法。此时任务栈中还是这一个ActivityA的实例。

    如果以singleTop模式启动的Activity的一个实例已经存在于任务栈中,但是不在栈顶,那么他的行为和standard模式相同也会创建一个新的实例。

  • singleTask(栈内复用模式)

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

  • singleInstance(单实例模式 - 加强的singleTask模式)

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

    和singleTask不同的是,同一时刻在系统中只会存在一个这样的Activity实例,而singleTask模式的Activity是可以有多个实例的,只要这些Activity在不同的任务栈中即可,例如,应用A启动了一个启动模式为singleTask的ActivityA,应用B又通过Intent想要启动一个ActivityA,此时由于应用A和应用B都有自己的任务栈,因此,在这两个任务栈中分别都有一个ActivityA示例。而singleInstance能够保证Activity在系统中只有一个实例,不管多少应用要启动该Activity,这个Activity有且只有一个。

1.3 Service

Service在Android程序中实现了后台运行的解决方案,它适合去执行那些不需要和用户交互而且还要求长期运行的任务。但是Service并不会运行在子线程中,他也不运行在一个独立的进程中,它同样执行在UI线程中,因此,不用在Service中执行耗时操作,除非在Service中创建了子线程来完成耗时操作。

Service的运行不依赖任何用户界面,就是说即使程序别切换到后台或者用户打开了另外一个应用程序,Service仍然能够保持正常运行,这也是Service的使用场景。当某个应用程序进程被杀掉时,所有依赖于该进程的Service也会停止运行

普通Service

Service的生命周期比Activity简单的多,只有三个,分别是onCreate、onStarCommand、onDestory。一旦我们在项目中任何位置调用了starService()函数,相应的服务就会启动起来,首次创建服务时会调用onCreate方法,然后调用onStartCommand方法。服务启动了之后会一直保持运行状态,直到stopService或stopSelf方法被调用。

虽然每次调用一次startService方法,onStarCommand方法就会就会执行一次,但实际上每个服务都只会存在一个实例。所以不管你调用了多少次startService方法,只需要调用一个stopService或stopSelf方法,服务就会被停止。

    public class MyService extends Service {        @Override public int onStartCommand(Intent intent, int flags, int startId) {            doMyJob(intent);            return super.onStartCommand(intent, flags, startId);        }        private void doMyJob(Intent intent) {            //子线程中执行相关操作            new Thread(){                   @Override public void run() {                    //耗时操作                }            }.start();        }        @Nullable @Override public IBinder onBind(Intent intent) {            return null;        }    }

Service和Activity一样也是需要在AndroidManifest.xml中进行注册

    <service android:name=".MyService"/>

上面我们注册了MyService的服务之后,当用户调用startService(new Intent(this,MyService.class))时会调用onStartCommand函数,我们在该函数中调用doMyJob,在doMyJob中我们创建了一个线程来执行耗时操作,以避免阻塞UI线程。当我们的Service完成使命时,需要调用stopService来停止服务。

IntentService

上面我们完成一个简单的后台任务需要这么多操作,当然Android也感觉到了,因此为我们提供了一个IntentService来完成这样的操作,IntentService将用户的请求执行在一个子线程中,用户只需要覆写onHandleIntent函数,并且在该函数中完成自己的耗时操作即可。

要注意的是,在任务执行完毕之后IntentService会调用stopSelf自我销毁,因此,它适合完成一些短期的耗时操作

    public class MyIntentService extends IntentService {        public MyIntentService() {            super(MyIntentService.class.getName());        }        @Override protected void onHandleIntent(Intent intent) {            //在这里执行耗时操作        }    }

运行在前台的Service

Service 默认是运行在后台的,因此,它的优先级相对比较底,当系统出现内存不足的情况时,它就有可能被回收掉。如果我们希望Service可以一直保持运行状态,而不会由于系统内存不足被回收,可以将Service运行在前台。前台的服务不仅不会被系统无情的回收,它还会在通知栏显示一条消息,下拉状态栏后可以看到更加详细的信息。

(其实就是我们在Service的OnCreate中开启一个Notification,并且在最后要调用StartForeground,将服务设置为前台服务。记得在Androidmanifest.xml注册之后我们就可以启动该Service了)

这都是一些基础概念性的东西,大家在平时的工作中肯定经常使用,但是对于概念就知道的没这么细了,所以我们还是要了解一下的。

欢迎有兴趣的同学加我朋友的QQ群:点击直接加群555974449

1 0
原创粉丝点击