1.介绍一下四大组件
Activity:代表手机上的一个界面,用于和用户交互。
Service:可以在后台长期运行,没有界面的组件。
ContentProvider:用于不同APP间存储和交换数据。
BroadCastReceiver:广播接收器,用于APP内部或APP间的信息传输。
Fragment:和Activity一样,拥有布局,生命周期,和用户交互。但Fragment依赖于Activity,生命周期由Activity调用。
2.Activity启动模式和用于场景
a:standard:默认启动模式,每次启动都会在栈顶创建一个新实例。
b:singleTop,栈顶模式,每次启动时,判断要启动的Activity是否位于栈顶,如果位于栈顶,直接复用。如果不位于栈顶,则创建实例。复用时调用onNewIntent()方法。防止多次点击时创建多个,阅读类 APP 的内容界面。
c:singleTask,栈内复用。判断栈内是否已经有Activity实例,如果有,直接复用,并将该Activity上的实例全部出栈。只调用一次onNewIntent()方法。常用于主页和登陆页。
d:singleInstance,单例模式。系统启动新的栈来管理Activity,实例在系统只有一个。
例如系统电话。
设置启动模式:在清单文件 AndroidManifest.xml 中配置 launchMode,当然可以用 Intent 标签说事儿。通过设置 Intent.setFlags(int flags) 来设置启动的 Activity 的启动模式。
3.Activity生命周期
onCreate(),正在创建。做初始化工作。加载布局,数据初始化,绑定等
onStart(),正在启动,Activity可见,但无法和用户交互。
onResume(),Activity获得焦点,在前台,可以与用户交互。
onPause(),正在停止,系统准备去启动或者回复另一个活动的时候调用,不可见
onStop(),即将停止,被下一个activity覆盖。做一些回收工作,例如网络取消,若启动的新活动是个对话框,onPause会执行,onStop不会执行.
onDestory(),即将销毁,做回收和资源释放。
onRestart(),Activity由后台切换到前台,由不可见到可见,Activity重新启动。
4.fargment生命周期
onAttach()->onCreate()-> onCreateView()->onActivityCreated()->onStart()->onResume()->onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()
与Activity不同的有:
onAttach():当Fragment和Activity建立关联时调用
onCreateView():当Fragment创建视图时调用
onActivityCreated():当与Fragment相关联的Activity完成onCreate()之后调用
onDestroyView():在Fragment中的布局被移除时调用
onDetach():当Fragment和Activity解除关联时调用
使用方法:
如果用replace()就会每次都初始化Fragment
正确的切换方式是add(),切换时hide(),add()另一个Fragment;再次切换时,只需hide()当前,show()另一个。这样就能做到多个Fragment切换不重新实例化
5.为什么要用Fragment
模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
可重用(Reusability):多个Activity可以重用一个Fragment。
可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好。
使用场景:
非常经典的例子,即用两个Fragment封装两个界面模块,这样只使一套代码就能适配两种设备,达到两种界面效果;单一场景切换时使用Fragment更轻量化,如ViewPager和Fragment搭配使用。
6.service启动模式
第一种,其他组件调用Context的 startService() 方法可以启动一个Service,并回调服务中的onStartCommand()。如果该服务之前还没创建,那么回调的顺序是onCreate()->onStartCommand()。服务启动了之后会一直保持运行状态,直到stopService() 或 stopSelf() 方法被调用,服务停止并回调onDestroy()。另外,无论调用多少次startService()方法,只需调用一次stopService()或stopSelf()方法,服务就会停止了。
第二种,其它组件调用Context的 bindService() 可以绑定一个Service,并回调服务中的onBind()方法。类似地,如果该服务之前还没创建,那么回调的顺序是onCreate()->onBind()。之后,调用方可以获取到onBind()方法里返回的IBinder对象的实例,从而实现和服务进行通信。只要调用方和服务之间的连接没有断开,服务就会一直保持运行状态,直到调了unbindService() 方法服务会停止,回调顺序onUnBind()->onDestroy()。多个组件可以绑定到一个Service,当它们都解绑时,Servive被销毁。
7.IntentService
IntentService是Service的子类,IntentService在执行onCreate操作的时候,内部开了一个线程,去你执行你的耗时操作。通过Handler looper message的方式实现了一个多线程的操作,同时耗时操作也可以被这个线程管理和执行,同时不会产生ANR的情况。
比较:
Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程(比喻成没有界面的activity),也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。
不同于线程,IntentService是服务,优先级比线程高,更不容易被系统杀死,因此较适合执行一些高优先级的后台任务;不同于普通Service,IntentService可自动创建子线程来执行任务,且任务执行完毕后自动退出。
8.Activity与Service通信
1.通过BroadCastReceiver:这种方式是最简单的,只能用来交换简单的数据;
2.通过Messager:这种方式是通过一个传递一个Messager给对方,通过这个它来发送Message对象。这种方式只能单向传递数据。可以是Service到Activity,也可以是从Activity发送数据给Service。一个Messeger不能同时双向发送;
3.通过Binder来实现远程调用(IPC):这种方式是Android的最大特色之一,让你调用远程Service的接口,就像调用本地对象一样,实现非常灵活,写起来也相对复杂。
binder流程如下:
1、在Service子类创建 binder子类,返回当前服务的this对象。让前端能够通过 binder 类实现对 service 的调用。
2、service 中的 onbinder方法返回 binder 实例。
3、在前端中的 onserviceconnected 中接收返回的 binder 实例。通过binder 实例获得服务的this对,通过对象调用公共方法,实现通信。
9.广播种类
a:普通广播:一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们接收的先后是随机的。
b:有序广播:一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以此时的广播接收器是有先后顺序的,且优先级(priority)高的广播接收器会先收到广播消息。有序广播可以被接收器截断使得后面的接收器无法收到它。 sendOrderedBroadcast(intent, null, null, null, “这是初始数据”, );
c:本地广播:发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收本应用程序发出的广播。(Hander实现,高效)
d:粘性广播:这种广播会一直滞留,当有匹配该广播的接收器被注册后,该接收器就会收到此条广播。
e:无序广播:所有的接收者都会接收事件,不可以被拦截,不可以被修改。sendBroadcast(intent);
10.广播的注册方式
静态注册:也可成为常驻型广播,这种广播需要在Androidmanifest.xml中进行注册,这中方式注册的广播,不受页面生命周期的影响,即使退出了页面,也可以收到广播这种广播一般用于想开机自启动啊等等,由于这种注册的方式的广播是常驻型广播,所以会占用CPU的资源。
使用:生成一个类去继承BroadcastReceiver,并复写onReceiver()方法,并且在清单文件中注册Receiver,在标签中定义action唯一标识属性。
动态注册:而动态注册的话,是在代码中注册的,这种注册方式也叫非常驻型广播,收到生命周期的影响,退出页面后,就不会收到广播,我们通常运用在更新UI方面。这种注册方式优先级较高。最后需要解绑,否会会内存泄露。unregisterReceiver(dynamicReceiver);
使用:新建一个类继承BroadcastReceiver,重写onReceiver()方法.然后再Activity当中复写onStart()和onStop()方法,在onStart()当中,我们需要构造一个IntentFilter对象,并执行这个对象的addAction方法,参数为action标识符,再执行registerReceiver()方法,参数为广播接收器对象和IntentFilter对象。在onStop()中执行unregisterReceiver()方法,参数为广播接收器对象。
11.contentProvider
ContentProvider主要负责存储和共享数据。实际上是对SQLiteOpenHelper的进一步封装,以一个或多个表的形式将数据呈现给外部应用,通过Uri映射来选择需要操作数据库中的哪个表,并对表中的数据进行增删改查处理。ContentProvider其底层使用了Binder来完成APP进程之间的通信,同时使用匿名共享内存来作为共享数据的载体。ContentProvider支持访问权限管理机制,以控制数据的访问者及访问方式,保证数据访问的安全性。
使用步骤:
过程:
1、创建自己的数据列表;
2、自定义ContentProvider实现相关的抽象方法;
3、在AndroidManifest中声明provider以及定义相关访问权限;
4 、通过ContentResolver根据URI进行增删改查。