本文介绍的是android基础的相关概念,基本都是来自android开发者网站以及个人的理解
android最基础的两个优点:
1、应用提供多个入口点
2、应用可适应不同的设备
Q:经常听到android的优点之一是:提供多个入口点(entry point)去启动应用程序APP;怎么理解这句话呢?
A:安卓APP是由多个相对独立的组件(如activity,service,broadcast receiver等)组成的,这些组件都可以作为一个独立的入口点去启动该应用运行起来。典型例子是:你在应用A中想要开启拍照功能,可以直接通过接口去启动系统自带的“相机”,然后去拍照。并不用退出桌面后通过点击“相机”图标去拍照。所以安卓的入口点不单单是桌面上的“icon图标”。而是桌面上的 “icon图标” + “组成该APP的相关组件”
Q:android系统的另一个优点是:支持App层方便的兼容不同的设备;怎么理解这句话呢?
A:因为android系统的初衷是让所有的移动设备上都能安装android系统,运行由android系统开发的App,所以android系统在设计之初就考虑到了支持不同的设备类型,并由此在系统层设计了一整套资源匹配框架。具体为:系统FrameWork层支持APP根据设备的不同特性存放不同的资源,APP层只需要根据相关规则(如文件名称,文件存放路径等)供对应的资源(如匹配中文,需要将string.xml文件放在res/values-zh-rCN/路径下)。然后在APP运行的时候,系统层会根据设备相关参数(如屏幕分辨率,地区等)去选择最佳的资源适配该设备。
Q:activity上的View是怎么显示出来的呢?
A:android activity的界面是通过"容器+元件"组成的
容器:即ViewGroup,是存放其他子View的一个容器。如LinearLayout,FrameLayout等等
元件:即子View,用于显示内容的具体控件。如TextView,ImageView等等
ViewGroup_View.png
Q:在app中的layout布局文件中,通过属性android:onClick为控件增加"单击"时回调的方法有什么具体的要求吗?
A:有条件限制的;对于android:onClick属性回调的方法,该方法必须满足:
(1)是public访问修饰符修饰的
(2)方法返回值必须是void
(3)View是唯一的参数,该View实际上就是发生"单击"事件的View
如:
public void sendMsg(View v){
//该方法就能被用到android:onClick属性中
}
具体回调的源码,需要进一步分析
Q:怎么初步理解android的intent?
A:intent是android系统中相互独立的组件之间提供运行时绑定的对象,该对象定义了特定的消息去告知系统,用于激活对应的组件。众所周知,android系统中的4大组件(activity,broadcast receiver, service, content provider)是相互独立的,而他们之间的联系就需要通过intent作为一个中间信使。这样,使得android在app层级组件之间的耦合性降到最低,这也是android系统的优点之一。
注意:android四大组件中,只有三种(activity,service,broadcast receiver)是由为intent的异步消息去启动激活的。即通过发送intent(里面携带一条拥有特定action,category等信息)告知系统,让系统去激活对应的组件。而Content Provider并不是通过intent方式去激活的
Q:怎么理解4大组件之间相互独立呢?
A:即假设有activityA 和 activityB,这两个activity之间不管缺少了activityA或者缺少了activityB,另一个activity都能正常运行。这就是组件之间的相互独立性
Q:acitivity有什么具体的作用?
A:activity的具体作用如下:
(1)展示信息给用户
(2)监听并响应用户的操作
(3)让系统知道当前哪个app的进程优先级最高,这样在内存紧张的时候,最后kill在前台展示activity的app进程
(4)提供了一种交互方式,让用户流在app之间流通。最典型的例子就是分享图片,拍照,去调用别的app中的activity,实现用户流的流转。
Q:service有什么具体的作用?
A:service的具体作用如下:
(1)没有UI界面,在后台长时间执行一些耗时\非耗时操作,如访问网络数据等
(2)后台运行的服务类型影响着系统对该后台服务的app的管理情况;
如在后台播放音乐:由于音频交互是用户可感知的,仅次于activity的UI交互。所以该服务所对应的app的优先级更高,在内存紧张的时候,不会轻易kill该app去释放内存;
如在后台下载视频数据:该过程对用户来说是非实时的,所以在内存紧张的时候,可以先kill该服务对应的进程,后面内存富足之后再启动该服务继续下载视频数据。
对于android系统来说,kill app的优先级管理策略的核心依据是:该app和用户的交互状态。如果当前处于强交互状态,那么优先级就更高,更不容易被kill;如果处于弱交互甚至无交互状态,那么优先级就低,内存不足的时候会优先kill这些进程
(3)可以通过绑定服务来提高该服务的优先级。如可以将一个前台Activity A绑定到服务B上,那么会大幅提高该服务的优先级至Activity A相等的优先级;因为绑定服务相当于告知系统,该前台Activity A的正常运行需要用到服务B。所以为了保证前台该Activity A的正常运行以及用户体验,在内存紧张的时候,也不会优先kill该服务B。
Q:broadcast有什么具体的作用?
A:broadcast的具体作用如下:
(1)系统能够在常规用户流之外将事件传递给应用程序的组件,使应用程序能够响应系统范围的广播。常规用户流:应该是指用户操作触发的事件,是常规的交互方式。如在App A中通过点击拍照按钮,会去启动系统相机App B,这是最常规,也是最重要的交互方式,直接去启动对应的activity去传递事件。而广播接收器是以另一种方式进行交互,通过广播,将常规用户操作之外的事件(尤其是系统的相关事件,如电源不足事件等等)传递给app,让app去做对应的处理
(2)系统能够将广播传递给所有的app,甚至是没有处在运行状态的app(只需要静态注册对应的broadcast recevier就可以)
Q:启动android 组件activity,service,broadcast receiver的方式有哪些?
A:具体的启动方式有如下这些:
(1)activity启动方式:startActivity() 或 startActivityForResult(),参数是intent
(2)service启动方式:android 5.0之前,是 startService() 或 bindService(),参数是intent。android 5.0之后,通过JobScheduler类来调度操作
(3)broadcast receiver启动方式:通过 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast() 等方法发送广播,让系统去启动对应的broadcast receiver处理,参数是intent
Q:android系统是基于Linux系统开发的吗?为什么要基于Linux系统?
A:安卓系统是基于Linux内核开发而成的,所以可以说,安卓系统本质上就是一个Linux操作系统。因此,android系统拥有Linux操作系统的绝大多数特性。而Linux最大的特性就是:多用户,多任务,多cpu,多线程。android系统完美的继承了这些优点。所以android系统的特性为:
1、Android 操作系统是一种多用户Linux系统,其中的每个应用都是一个不同的用户。就像ubuntu系统可以创建多个用户一样,如linsiyan,junlinge等用户帐号。而android系统是将每一个应用当作一个用户,这样就完美的继承了Linux为多用户设计的安全机制(访问权限等等),使得每一个应用在运行时能最大程度保证安全性,独立性,不受其他应用干扰;
2、默认情况下,系统会为每个应用分配一个唯一的Linux用户ID(该ID仅由系统使用,应用并不知晓)。系统会为应用中的所有文件设置权限,使得只有分配给该应用的用户ID才能访问这些文件;这个就是Linux的多用户安全机制。这里会有一个疑问:为什么说是默认情况下呢?难道还有非默认情况?
是的,非默认情况就是android系统支持不同的应用共享同一个 User id。通过这种方式,可以使不同应用之间互相访问数据等
3、每个进程(Process)都拥有自己的虚拟机(VM),因此应用代码独立于其他应用而运行。这也是Linux系统支持多进程的优点
4、默认情况下,每个应用都在其自己的Linux进程内运行。Android系统会在需要执行任何应用组件时启动该进程,然后当不再需要该进程或系统必须为其他应用恢复内存时,其便会关闭该进程。这里会有一个疑问:为什么说是默认情况下呢?难道还有非默认情况?
是的,非默认情况就是android系统允许一个应用可以有多个进程,甚至不同的activity都能运行在不同的进程中(只要在AndroidManifest.xml对应的activity节点下设置就可以);也允许不同的应用运行在同一个进程中。这里要表达的是,进程与进程之间是独立封闭的,所以一个进程的运行不会影响另一个进程的运行。最常见的例子是:应用A crash了,并不会导致应用B跟着crash
5、安卓系统实现了"最小权限"原则。即:每个应用只能访问执行其工作所需的组件,而不能访问其他组件。这样便能创建非常安全的环境,在此环境中,应用无法访问其未获得权限的系统部分。那这样会有一个疑问:如果实在要实现应用之间数据访问呢?怎么办?
安卓给出的答案是:
(1)可以安排两个应用共享同一 Linux 用户 ID,在此情况下,二者便能访问彼此的文件。为节省系统资源,也可安排拥有相同用户 ID 的应用在同一 Linux 进程中运行,并共享同一 VM。应用还必须使用相同的证书进行签名。
(2)应用可以请求访问设备数据(如用户的联系人、短信消息、可装载存储装置(SD 卡)、相机、蓝牙等)的权限。但是必须申请对应的权限并得到用于的允许。如果是系统app,那就不用,系统app拥有所有的权限
Q:怎么理解android app没有单个入口点(即没有main()函数)?
A:个人理解之所有没有单个入口点是基于app层,对于系统FrameWork层,还是有唯一的入口点的。具体理解如下:(如果有不对的地方,欢迎指正)
1、android系统设计的时候就将每个组件(activity,broadcast receiver,service,content provider)设计成相对独立,这样降低了组件之间的耦合度,并且为android将每个组件设计成单独的可启动app的入口点创造了条件
2、基于1,安卓系统将每个组件都设计成可以启动该应用的入口点。相当于任何程序都可以启动另一个程序的组件。当然,启动另外一个应用是需要通过android系统的协助进行的,相当于将需要启动的组件"告知"系统,系统找到包含该组件的app后,启动该进程;然后调用该组件运行起来。这样设计给应用开发带来了极大的好处。举个例子:你想在你的应用中去拍照,不用开发一个"相机"APP,而只需要告知系统将系统自带的"相机"APP运行起来即可。更方便的是,不需要集成任何关于"相机"APP的代码到你的应用中
(3)基于以上两点,对于一个android app来说,每一个组件都是一个入口点,每一个入口点都能让系统启动该app正常运行起来。对于其他系统来说,由于系统在单独的进程中运行每个应用程序,并且文件权限限制了对其他应用程序的访问,因此应用程序无法直接从另一个应用程序激活组件。而android系统在系统层面上将该缺陷解决掉了,这样从app层看来,android的应用程序拥有了多个入口点。而如果从系统层看来,启动app的过程的入口点还是那一个。
所以,个人理解,android app没有入口点(没有main()函数)是从app层来看的;对于系统层,启动一个应用,还是需要有对应的唯一入口点的,如第一步一定要先执行init()函数去初始化相关配置等等,因为启动一个应用的流程是固定的
网友评论