Android常用控件,四大组件,intent应用

常用控件:TextView、 Button、 EditText、 ImageView、 ProgressBar、AlterDailog、 ProgressDailog

四大组件: 

  1.  Activity(活动)  
  2. Serverce(服务)
  3.  BroadcastReceiver(广播)
  4.  ContentProvider(内容提供者)

 

  1. Activity

      是Android四大组件之一,用于显示view,是一个负责与用户交互的组件,可以通过setContentView(view)来显示指定的控件(一个Activity通常可以理解为一个可以看见的界面)

 生命周期:

Activity是由Activity栈来管理,当来到一个新的Activity后,此Activity将被加入到Activity栈顶,之前的Activity位于此Activity底部。Acitivity一般意义上有四种状态:

1.当Activity位于栈顶时,此时正好处于屏幕最前方,此时处于运行状态

2.当Activity失去了焦点但仍然对用于可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕),此时处于暂停状态

3.当Activity被其他Activity完全遮挡,此时此Activity对用户不可见,此时处于停止状态

4.当Activity由于人为或系统原因(如低内存等)被销毁,此时处于销毁状态;

在每个不同的状态阶段,Adnroid系统对Activity内相应的方法进行了回调。因此,我们在程序中写Activity时,一般都是继承Activity类并重写相应的回调方法。

Activity的启动模式:

   4种,分别是standard.singleTop. SingleTask. singleInstance,可以在AndroidMainifest.xml文件中指定每一个Activity的启动模式。一个Android应用一般都会有多个Activity,系统会通过任务栈来管理这些Activity,栈是一种后进先出的集合,当前的Activity就在栈顶,按返回键,栈顶Activity就会退出。Activity启动模式不同,系统通过任务栈管理Activity的方式也会不同,以下将分别介绍。

  1. Standard模式是Android的默认启动模式,你不在配置文件中做任何设置,那么这个Activity就是standard模式,这种模式下,Activity可以有多个实例,每次启动Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例,以下是实验验证。

    新建一个FirstActivity,用一个Button去启动它本身:

    Android常用控件,四大组件,intent应用_第1张图片

     

    发现每次都会启动一个新的FristActivity, Log信息如下

     

    什么时候用standard模式呢?standartd模式是activity的默认模式,大部分情况下,都应该使用这种模式,也就是在配置文件中什么都不用做,当确实有特殊需求时,再考虑其他模式。

    2 SingleTop模式

    SingleTop模式和standard模式非常相似,主要区别就是当一个singleTop模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例,现在把配置文件中FirstActivity的启动模式改为SingleTop,我们的应用只有一个Activity,FirstActivity自然处于任务栈的栈顶。

             当应用第一次启动后,我们再按Button去启动新的FirstActivity,发现Log信息中不再打印onCreate函数,说明不再创建新的FirstActivity实例。

             这里有一个新的问题,对于每次启动Activity,我们该如何分别处理。答案就是onNewIntent()函数,虽然系统不会调用onCreat(),但会调用onNewIntent,我们可以在这个函数做相应的处理。

     

             当一个Activity已经在栈顶,但依然有可能启动它,而你又不想产生新的Activity实例,此时就可以用singleTop模式。例如,一个搜索Activity,可以输入搜索内容,也可以产生搜索结果,此时就可以用singleTop模式,不会用户每次搜索都会产生一个实例。

             3 SingleTask模式

             SingleTask模式的Activity在同一个Task内只有一个实例,如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈。修改上面的程序,新建一个SecondActivity,将FirstActivity设置为singleTask启动模式,并让它启动SecondActivity,再让SecondActivity来启动FirstActivity。

                Android常用控件,四大组件,intent应用_第2张图片

             Log信息如下

     

    当SecondActivity启动FirstActivity时,并不会调用FirstActivity的onCreate函数,但会调用onNewIntent函数,同时会调用SecondActivity的onDestroy函数,SecondActivity实例被销毁。

    singleTask模式和前面两种模式的最大区别就是singleTask模式是任务内单例的,所以我们是否设定Activity为singleTask模式,就是看我们activity是否需要单例,例如你的某个Activity

    里面有一个列表,如果有多个实例,有可能导致用户看到的列表不一致,有的Activity需要经常启动,如果每次都创建实例,会导致占用资源过多,这些情况都可以使用singleTask模式,但启动singleTask模式的Activity会导致任务栈内它上面的Activity被销毁,有可能会影响用户体验,使用时要注意。

    4 SingleInstance模式

    singleInstance模式也是单例的,但和singleTask不同,singleTask只是任务栈内单例,系统里是可以有多个singleTask Activity实例的,而singleInstance Activity在整个系统里只有一个实例,启动一singleInstanceActivity时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity。

    SingleInstance模式并不常用,如果我们把一个Activity设置为singleInstance模式,你会发现它启动时会慢一些,切换效果不好,影响用户体验。它往往用于多个应用之间,例如一个电视launcher里的Activity,通过遥控器某个键在任何情况可以启动,这个Activity就可以设置为singleInstance模式,当在某应用中按键启动这个Activity,处理完后按返回键,就会回到之前启动它的应用,不影响用户体验。

    以上分析了Activity的4种启动模式,将Activity设置为哪种启动模式并没有标准答案,有时候,你可能发现将某个Activity设置为一种启动模式或者另一种启动模式,并没有明显区别,而具体的评判标准就是看哪种模式更满足应用功能,更有利于用户体验。

Acitivity的横竖屏切换走的生命周期:

Activity的  android:configchanged(Activity的属性)  切屏重新调用各个的生命周期,竖屏切横屏时会调用一次,再次切竖屏时,生命周期执行两次。

 Activity的configchangs = "orientation",切横屏、竖屏的生命周期只执行一次

Activity的android:configChanges = "keyboardHidden|orientation",横竖屏切换只执行onConfigurationChanged()

Activity横竖屏切换时如何保存数据:

它会首先销毁横屏的Activity,创建竖屏,要先通过onSaveInstanceState()保存数据--->再通过onCreate()创建竖屏--->通过onDestroy()销毁横屏--->再通过onCreate()创建竖屏--->onStart()--->通过onRestoreInstanceState()来保存横屏的数据--->onResume

生命周期: 

onSaveInstanceState()存数据

onPause()

onStop()

onDestroy()销毁横屏

onCreate()创建竖屏

onStart()

onRestoreInstanceState()取数据

onResume()

 

2.Service(服务):

            通常总是称之为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面,因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件:①并不依赖于用户可视的UI界面(当然,这一条其实也不是绝对的,如前台Service就是与Notification界面结合使用的)②具有较长时间的运行特性。

Service的两种启动方式:

   1、StartService

   2、bindService

区别:

1、startService启动的service,service会一直在后台运行,就算调用者已经死掉,服务还是会运行

2、bindService是将调用者和service是绑定在一起的关系,如果调用者已经死掉,服务会调用onUnBind进行解绑,然后onDestory销毁

两种启动方式的生命周期:

1\  StartService: onCreate --->onStartCommand(执行多次) --->onDestroy(只执行一次)

应用退出,但是后台没有杀死,服务还在

2\ bindService: onCreate ---> onBind--->onunBind --->onDestroy(都执行一次)

应用退出,服务就被杀死

Acitvity和Service如何进行通信?

1、StartService

可以通过广播来实现通信

2、BindService

当Activity通过bindService来绑定一个Service时,bindService会立即返回,它不会返回Ibinder给客户端,要接受Ibinder,客户端Activity必须创建一个长连接ServiceConnection的实例并传给bindService(),ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder

Service能否执行耗时操作:

        不能执行耗时操作,因为service是再主线程运行的。但是可以用开启一个子线程来进行耗时操作或者用IntentService来做一些耗时操纵,IntentService是继承并处理异步请求的一个类,IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,在onHandlerIntent方法中做耗时操作就可以了

Thread和Service的区别:

        Thread是程序执行的最小单元,它是分配CPU的基本单位。可以用Thread来执行一些异步的操作,是由应用程序托管

         Service是系统的组件,它由系统进程托管

         Thread的运行是独立于Activity的,你没有办法在不同的Activity中对同一个Thread进行控制;Service是运行在进程中的,而你可以在任何有Context的地方调用  Context.startService、Context.stopService、Context.bindService、Context.unBindService来控制它,你也可以在Service里注册广播,在其他地方通过发送广播来控制它,这些都是Thread做不到的

如何让你的Srvice成为前台Service?

         在Activity的onCreate方法中: 首先创建一个Notification对象,然后调用它的setLastEventInfo方法进行初始化布局和控件,并在这个方法里设置点击通知打开主页面,然后调用startForeground方法

Service的优先级:

          Android系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运行,系统内部会自动分配、控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保证一些优先级搞的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然运行。如果你的Service碰上了这种情况,多半会先被杀掉。但如果你增加Service的优先级就能让他多留一会,我们可以用setForeground(true)来设置Service的优先级

为什么是foreground?默认启动的Service是被标记为background,当前运行的Activity一般被标记为foreground,也就是说你给Service设置了foreground那么他就和正在运行的Activity类似优先级得到了一定的提高。当然这并不能保证你的Service永远不被杀掉,只是提高了它的优先级

BroadcastReceiver(广播):

按注册方式分为静态注册和动态注册。

     动态注册:在编写的APP代码中书写

      静态注册:在manifest.xml中注册

按发送广播的方式分为:

     有序广播

     无序广播

无序广播:通过sendBroadcast()发送广播,完全异步,但是没有顺序可言,速度比较快

有序广播:通过sendOrderedBroadcast(),同步的。

说到有序广播不得不说的优先级的问题:

       可以在AndroidMenifest的过滤器中设置priority的大小为广播优先级(-1000~1000),数值越大优先级越高,同一优先级的执行速度不确定。代码中注册的话可以动态设置priority的大小(setPrority()),同一优先级的执行速度不确定。如果静态注册的和动态注册的优先级相同,先注册的(运行顺序越早)就先接收广播

有序广播如何终止传递?

场景:有序广播设置优先级,如果三个广播,优先级为100,200.,300.,第三个广播会先执行,然后第二个,第一个,如果在第三个广播之后调用abortBroadCast()方法,它就不会传到比它优先级低的广播

静态注册和动态注册广播的区别?

       静态注册是在AndroidMainfest中注册的,不与App的生命周期绑定,也就是说当这个App被销毁之后静态注册的广播还会接收到数据;动态注册时在代码中实现的,绑定当前页面的生命周期,必须解绑(unregisterReceiver()【关闭广播的方法】必放在页面的onDestory()中),不然会造成内存泄漏

常见的系统广播有哪些?

电话监听,短信监听,开屏关屏,开关机

粘性广播?

粘性广播发送调用sendStickyBroadcast(),使用这个广播需要添加一个权限

android.Manifest.permission.BROADCAST_STICKY,这个广播的特点是Intent会一直保留到广播时间结束,并且没有10S限制(10S限制是指广播如果OnReceive方法执行时间太长,超过10S,系统会将这个广播设置为可以销毁,一旦系统资源不够就可以干掉它)

发送广播的事件:

短信,接电话,系统重启,手机短按长按开关机,按钮屏幕开屏,关屏,开关机,电池:电量充满,电量不足,存储:内存不足,内存从不足到充足,插入SD卡,取出SD卡,程序安装:程序安装,程序卸载 其他:插入耳机,打开或者关闭飞行模式,日期改变,时间改变,壁纸改变等

如何监听手机开关机的广播?

注册相对应的广播事件(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)。

ContentProvider(内容提供者):

          作用:进程间 进行 数据交互 & 共享,即跨进程通信

          原理:ContentProvider的底层是采用Android中的Binder机制

          Contentresolver就是通ContentProvider提供的URI来查询它对外提供的数据的,不仅要知道URI,还需要知道我们要获取的字段名称和字段的数据类型,并且Contentresolver也是向数据库一样对ContentProvider提供都得数据进行操作的

如何把自己应用程序的数据暴露出去?

          Android提供了ContentProvider(内容提供者),我们的App实现了一个ContentProvider的接口将自己的数据(类似数据库的形式)暴露出去,通过这种方式让其他应用可以访问到数据,这个方法是唯一一个应用程序之间共享数据的方法

让应用程序的数据公开化:

      两种方式:

           1、创建属于自己的ContentProvider

            2、将我们的数据添加到一个ContentProvider,有前提条件就是数据类型必须相同并且有读写

 

你可能感兴趣的:(Android常用控件,四大组件,intent应用)