当前位置:文档之家› android系统按键从linux到java流程

android系统按键从linux到java流程

android系统按键从linux到java流程
android系统按键从linux到java流程

android系统按键从linux到java流程

概述:

android系统的键值转换,从linux到java共经历3个层次,分别是:

1 linux系统层,原始ir键值读取,转变为linux层键值

2 framework层,linux层键值转换为android键值

3 framework层,android键值上报java层

关系图:

剩余疑问:dev/vinput和dev/input之间到底怎么关联的

目前没查到这二者是怎么关联的,但是从用户组可以看出,vinput应该是input的输入。

猜测:这二者之间类似一个软连接处理,避免键值读写都在同一个文件,在不同进程之间造成数据异常;二者由系统负责同步。

后续查到相关资料再补充.

1 原始ir键值读取,转变为linux层键值

核心输入:系统启动android_ir_user后台进程

核心输出: 虚拟设备dev/vinput,写入linux键值1.1 流程图

1.2转换流程详细说明:

1.2.1/device/hisilicon/bigfish/system/ir_user/key_pars/key.xml:

该文件编译后输出到/etc目录下。

定义原始硬件码值和对应linux层通用键名:

< key value="0x639c4db2" name="KEY_MUTE"/>

1.2.2/device/hisilicon/bigfish/system/ir_user/key_pars/linux_key.h:

定义linux层通用键名和linux层键值的对应关系:

{"KEY_MUTE", 113 },

结构linux_keycode_ary类型的数组Linux_KeyCode_Ary[512].

1.2.3/device/hisilicon/bigfish/system/ir_user/key_pars/ key_pars.c:

提供接口get_keycode解析xml建立原始码值和linux层键值的映射数组

get_keycode(_key_arry *keyarry, int keyarry_num)解析:

a:调用readXml读取/etc/ key.xml,返回xml根节点:

key.xml中分别各一个节点,我们的遥控器原始键值配置在中。

b:调用Pars_Key解析每个节点下的所有按键:

解析节点下的所有children节点,通过value属性获取xml定义的原始键值,通过name属性获取xml定义的键名字符串,再调用find_linux_key_code查询这个字符串对应的linux层键值。

把这个映射关系存储到:

keyarry->hi_keycode[keynum].ir_keycode = ir_keycode;

keyarry->hi_keycode[keynum].linux_keycode = linux_keycode;

c: find_linux_key_code函数遍历在linux_key.h定义的Linux_KeyCode_Ary数组,找到参数str(即键名字符串)对应的linux层键值。

1.2.4/device/hisilicon/bigfish/system/ir_user/ir_user.cpp:

1)编译为后台进程android_ir_user独立运行;

2)进程启动,执行main入口函数,调用get_keycode完成key.xml存储原始码值和linux 层键值的映射关系到数组keyarry;

3)建立ir_sample_thread线程读取原始码值,根据keyarry转换为linux层键值,通过ReportKeyEvent写入dev/vinput设备,其他进程可以读取键值

1.3总结

出差拷机,如果不想其他厂家操作我们的盒子,只需要离开的时候删除/system/bin下面的android_ir_user这个bin文件即可。

2 linux层键值转换为android键值

核心输入:/dev/input, 输入linux键值

核心输出: 1)getEvents(),输出RawEvent* buffer,存储linux层键值;

2)mapKey(),将linux层键值转换为android键值

2.1流程图

2.2详细说明

2.2.1 /device/hisilicon/bigfish/prebuilts/Vendor_0001_Product_0001.kl:

定义linux键值和对应的键名字符串

key 113 MUTE

2.2.2 /frameworks/native/include/input/KeycodeLabels.h

定义键名字符串和android的java层键值对应关系结构数组KEYCODES:

{ "MUTE", 91 }

2.2.3\frameworks\native\libs\input\Keyboard.cpp

提供函数loadKeyLayout和getPath,定位linux到android键第一转换映射文件为Vendor_0001_Product_0001.kl:

提供函数getKeyCodeByLabel,从KeycodeLabels.h的KEYCODES数组中,查询返回android的java键值。

2.2.4\frameworks\native\libs\input\KeyLayoutMap.cpp

提供函数load和parse等解析Vendor_0001_Product_0001.kl,并调用Keyboard.cpp的getKeyCodeByLabel,通过“linux键值---键名字符串---android的java 层键值”的直接建立“linux键值--- android的java层键值”map集合;

提供函数mapKey基于此集合供上层转换linux键值为android的java键值

2.2.5 \frameworks\base\services\input\EventHub.cpp

1 提供getEvents,完成两个事:

1):建立linux键值--- android的java层键值”map集合。

2):扫描linux键值,存储到参数RawEvent* buffer。

2 提供mapKey,调用KeyLayoutMap.cpp的mapKey函数,完成转换linux 键值为android的java键值。

2.2.6关于建立linux键值--- android的java层键值”map集合,代码流程:

1)\frameworks\base\services\input\EventHub.cpp

a)getEvents()->scanDevicesLocked():

b)scanDevicesLocked-> scanDirLocked():

static const char *DEVICE_PATH = "/dev/input";

c)scanDirLocked()->openDeviceLocked()

d) openDeviceLocked()->loadKeyMapLocked()

e) loadKeyMapLocked调用Keyboard.cpp下load()函数:

2)\frameworks\native\libs\input\Keyboard.cpp

f) load()->probeKeyMap():

g) probeKeyMap ()->loadKeyLayout():

h) loadKeyLayout()->getPath():

这里才确定path为:./system/usr/keylayout/Vendor_0001_Product_0001.kl 再继续调用KeyLayoutMap::load加载并解析

3)\frameworks\native\libs\input\KeyLayoutMap.cpp

i)load()->parse()

j)parse ()->parseKey()

解析Vendor_0001_Product_0001.kl得到linux层code,

再调用getKeyCodeByLabel查询code对应的android层键值keyCode

将两个键值存入map集合

到此完成linux层键值到android的java层键值的转换并存储为map集合;后面真正扫描到linux键值后,调用mapKey根据存储的map集成转换为android键值进行上报。

2.3总结:

这个部分可以看出,其完全是个中间过程,如果我们要修改某个键在android的表现,完全不用改这其中相关的任何文件,只需要在java层(后面会讲到,keyevent.java)对收到的android键进行再转换即可。

3 Android键值上报java层

核心输入: eventhub.cpp的getEvents()和mapkey()

核心输出:PhoneWindowManager.java的interceptKeyBeforeQueueing和

interceptKeyBeforeDispatching

3.1流程图

太多,省略....

3.2详细说明

3.2.1\frameworks\base\services\input\InputReader.cpp

该文件主要负责:

linux按键的读取;

转换为android键值;

通过listener启动按键上报,注意这里仅仅是启动按键上报。

1)InputReader 类构造函数InputReader

两个极其重要的参数:

eventHub和listener,前者用来读取linux键值,后者用来分发上报按键。

说明:

参数eventHub,赋值给变量mEventHub;listener作为参数创建了mQueuedListener。

2) loopOnce函数及其调用的一连串函数

调用mEventHub->getEvents读取linux按键到RawEvent 类型的mEventBuffer成员变量;

调用processEventsLocked分发上报。

3)重点阐述processEventsLocked是如何分发上报按键的:

a)processEventsLocked调用processEventsForDeviceLocked

b) processEventsForDeviceLocked从InputReader 的(InputDevice类型)变量mDevices变量中找出当前对应的device,调用其process

c) process调用InputDevice的变量(InputMapper类型)mMappers的process函数

d)这里的mapper是KeyboardInputMapper类

这里process开始调用eventhub类的mapKey()启动参数rawEvent中的linux键值scanCode的转换,变为android键值keyCode,继续调用processKey上传.

e) processKey调用getListener()->notifyKey(&args);

完成键值上报到其他模块

注意这里的getListener就是取得inputreader类初始化时用参数“const

sp& listener”初始化的mQueuedListener。

到这里,inputread.cpp模块的按键分发上报全部完成,后续只要搞清楚

sp& listener”到底是谁,就知道按键分发到哪里去了。

4)阐述按键分发中的关键衔接一环:

上述C)步的mMappers是如何和KeyboardInputMapper关联的?

为什么KeyboardInputMapper的getListener()是inputreader的mQueuedListener?

仍然是从loopOnce调用processEventsLocked开始:

a) processEventsLocked找不到按键rawEvents的设备来源时调用addDeviceLocked:

b) addDeviceLocked调用createDeviceLocked:

(所以上面第3)点钟的B)步能找到有效的device)

c) createDeviceLocked调用device->addMapper

到这里就完成了inputreadr----inputdevice---mappers的关联.

getListener的来源:

InputReader构造函数用参数sp& listener创建了mQueuedListener对象实例,mQueuedListener是InputReader的成员变量;

mContext也是InputReader对象的成员,其类型是InputReader的内部类ContextImpl,该类继承自InputReaderContext,ContextImpl的getListener函数直接返回mQueuedListener。

createDeviceLocked在添加inputdevice设备时,使用mContext转换为InputReaderContext作为参数创建了device,直接赋值给inpudevice的成员变量mContext。

createDeviceLocked继续addMapper创建了KeyboardInputMapper实例,即(new KeyboardInputMapper(device, keyboardSource, keyboardType)); device用于创建InputMapper对象,device的mContext成员赋值给InputMapper的mContext;KeyboardInputMapper又继承自InputMapper。

所以KeyboardInputMapper的成员mContext等价于InputReader的mContext;getListener等价于调用InputReader的mContext->getListener即mQueuedListener。

5)InputReaderThread线程类

构造函数InputReaderThread使用InputReader 类对象作为参数,赋值给变量mReader。

threadLoop方法中调用mReader->loopOnce();

只要创建了InputReader实例,并以此启动InputReaderThread线程,就会反复mEventHub->getEvents读键和调用processEventsLocked分发上报。

3.2.2\frameworks\base\services\input\InputDispatcher.cpp

该文件是真正的按键数据上报的起点,InputReader中的listener实际就是这个InputDispatcher,该类继承自接口InputDispatcherInterface。

完成3个事情:

interceptKeyBeforeQueueing,按键入列前的截获处理

interceptKeyBeforeDispatching,按键从队列分发上层app前的截获处理

startDispatchCycleLocked,完成按键最终分发上报

1)InputDispatcher类

a)构造函数以参数policy直接初始化成员变量mpolicy。

b) notifyKey函数被之前的inputreader调用,notifyKey调用interceptKeyBeforeQueueing

进行第一次按键上报,供上层截获按键,在按键被压入队列前进行必要的处理,如设置,桌面等在keyfuntion.xml中配置的快捷键,或待机键等的处理。

到这里完成按键进入Queue队列前的上报处理,如果interceptKeyBeforeQueueing 没有处理这个按键,将会继续调用步骤c)。

c)enqueueInboundEventLocked将按键结构参数entry压入队列

d) InputDispatcherThread线程类不断循环,检测到队列中的按键

InputDispatcherThread调用InputDispatcher的dispatchOnce。

e)dispatchOnce调用dispatchOnceInnerLocked

f)dispatchOnceInnerLocked调用dispatchKeyLocked

g)dispatchKeyLocked调用doInterceptKeyBeforeDispatchingLockedInterruptible

h)doInterceptKeyBeforeDispatchingLockedInterruptible调用

mPolicy->interceptKeyBeforeDispatching

到这里完成进入队列的按键在上报app前的截获处理,比如特殊处理home键,添加工装菜单的按键调用等,如果这些按键仍然没被截获,将继续进行分发,继续下面的步骤i).

i)dispatchKeyLocked调用addMonitoringTargetsLocked,获取所有上层注册过需要按键的channel,创建目标通道集合inputT argets;

继续调用dispatchEventLocked开始按键分发。

j)dispatchEventLocked对每一个通道获取其connection,再调用prepareDispatchCycleLocked

k) prepareDispatchCycleLocked调用enqueueDispatchEntriesLocked

l)enqueueDispatchEntriesLocked调用enqueueDispatchEntryLocked把按键eventEntry和目标通道inputTarget写入connection

再调用startDispatchCycleLocked开始分发

m)startDispatchCycleLocked调用connection->inputPublisher.publishKeyEvent 完成最终分发按键。

2)InputDispatcherThread线程类

构造函数InputDispatcherThread使用InputDispatcherInterface类对象作为参数,赋值给变量mDispatcher。

threadLoop方法中调用mDispatcher->dispatchOnce();

只要创建了mDispatcher实例,并以此启动InputReaderThread线程,就会反复mDispatcher->dispatchOnce(),完成按键分发。

3.2.3\ frameworks\base\services\input\InputManager.cpp

该文件负责启动前面阐述的InputReader和InputDispatcher。

1)创建InputReader和InputDispatcher实例,初始化到mDispatcher和mReader。

2)创建InputReaderThread和InputDispatcherThread两个线程

3)启动线程循环运行start

3.2.4 \frameworks\base\services\jni\

com_android_server_input_InputManagerService.cpp (InputManagerService.java的JNI)

1)nativeInit()调用NativeInputManager(),后者调用new

InputManager(eventHub, this, this);完成创建InputManager对象的实例mInputManager。

//////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////

NativeInputManager 是多重继承,其父类之一为虚类InputDispatcherPolicyInterface,所以最后一个this参数实际就是NativeInputManager 自己;

InputManager运行InputDispatcher,后者调用的interceptKeyBeforeQueueing和interceptKeyBeforeDispatching实际就是NativeInputManager的同名函数。也就是说从JNI初始化InputManager,启动InputReader和InputDispatcher,而InputDispatcher最终回调JNI的interceptKeyBeforeQueueing和interceptKeyBeforeDispatching完成按键截获处理。

2)nativeStart调用mInputManager的start启动两个线程InputReaderThread 和InputDispatcherThread.

3)NativeInputManager的interceptKeyBeforeQueueing调用java层interceptKeyBeforeQueueing

4)NativeInputManager的interceptKeyBeforeDispatching调用java层interceptKeyBeforeDispatching

5)register_android_server_InputManager将interceptKeyBeforeQueueing和interceptKeyBeforeDispatching,与InputManagerService.java的同名函数进行关联

3.2.5 \frameworks\base\services\java\com\android\server\input

\InputManagerService.java:

1)构造函数InputManagerService())调用JNI函数nativeInit();

2)interceptKeyBeforeQueueing()调用WindowManagerCallbacks的interceptKeyBeforeQueueing方法继续上抛按键; interceptKeyBeforeDispatching 同理。

3)WindowManagerCallbacks是内部类,mWindowManagerCallbacks是成员变量,通过setWindowManagerCallbacks()方法设置。

4)start方法调用nativeStart,这里实现调用InputManager的start,启动mDispatcherThread和mReaderThread两个线程。

3.2.6 \frameworks\base\services\java\com\android\server\SystemServer.java initAndLoop ()启动InputManagerService

这里的setWindowManagerCallbacks设置的callback,即WindowManagerService类的getInputMonitor方法

至此,底层的InputReaderThread和InputDispatcherThread全部启动完毕,现在的重点是要找到WindowManagerCallbacks的interceptKeyBeforeQueueing和interceptKeyBeforeDispatching最终指向了哪里,由于两个方法网上的映射机制是一样的,下面只讲interceptKeyBeforeQueueing。

继续往下走。

3.2.7\frameworks\base\services\java\com\android\server\wm

\WindowManagerService.java

////////////////////////////////////////////////////////////////////////////////////// InputMonitor的创建:

////////////////////////////////////////////////////////////////////////////////////// getInputMonitor直接返回InputMonitor:

//////////////////////////////////////////////////////////////////////////////////////

创建mPolicy:

final WindowManagerPolicy mPolicy =

PolicyManager.makeNewWindowManager();

3.2.8\frameworks\base\services\java\com\android\server\wm\ InputMonitor.java:

//////////////////////////////////////////////////////////////////////////////////////

该类继承自InputManagerService 的内部类WindowManagerCallbacks接口。

////////////////////////////////////////////////////////////////////////////////////// interceptKeyBeforeQueueing()函数被重载,并调用调用WindowManagerPolicy接口的interceptKeyBeforeQueueing。

//////////////////////////////////////////////////////////////////////////////////////

该service由构造函数传入,实际就是WindowManagerService:

mPolicy由PolicyManager类的makeNewWindowManager()创建。

3.2.9 \frameworks\base\core\java\com\android\internal\policy\ PolicyManager.java

////////////////////////////////////////////////////////////////////////////////////// makeNewWindowManager调用Policy.java的方法makeNewWindowManager()

////////////////////////////////////////////////////////////////////////////////////// sPolicy的初始化:

3.2.10\frameworks\base\policy\src\com\android\internal\policy\impl\Policy.j ava

makeNewWindowManager调用TVWindowManager.java类的构造函数创建对象实例。

3.2.11\frameworks\base\policy\src\com\android\internal\policy\impl\TVWin dowManager.java

TVWindowManager类自身没有interceptKeyBeforeQueueing方法,但其继承自PhoneWindowManager类

3.2.12\frameworks\base\policy\src\com\android\internal\policy\impl\ PhoneWindowManager.java

PhoneWindowManager.java具备最终形态的interceptKeyBeforeQueueing和interceptKeyBeforeDispatching,到此流程走完。

3.3总结

3.2.5中的步骤4)中setWindowManagerCallbacks实际就是创建并设置了PhoneWindowManager类的实例,InputManagerService实现了调用PhoneWindowManager的interceptKeyBeforeQueueing和interceptKeyBeforeDispatching。

总结:

回头看整个按键转换和分发流程,有两个根节点:

1 第一层次读取linux键值的进程,android_ir_user这个bin文件,由系统脚本开机拉起

2 第二、三层次的按键分发,总源头为SystemServer这个服务的启动,由android系统开机启动,详细流程参见.

以上除了第一层次linux键值的获取外,其他所有层次实际都是一个通用的转换和上报过程,最终到达PhoneWindowManager的interceptKeyBeforeQueueing和interceptKeyBeforeDispatching后,按键是以KeyEvent类实例作为参数传入的,并且必须以getKeyCode来访问实际android键值。

所以:

1)如果系统有增加按键的需求,需要修改:

/device/hisilicon/bigfish/system/ir_user/key_pars/key.xml

/device/hisilicon/bigfish/system/ir_user/key_pars/linux_key.h

/device/hisilicon/bigfish/prebuilts/Vendor_0001_Product_0001.kl

/frameworks/native/include/input/KeycodeLabels.h

/frameworks/base/core/java/android/view/KeyEvent.java

以上文件一一添加,只要最终KeycodeLabels.h和KeyEvent.java中定义的android键是正确的,前面其他文件所有定义只需要能保持一一对应即可。

另外

/frameworks/base/core/res/res/value/attrs.xml这个文件的作用是给上层APP用的一个资源文件,这个文件如果实际没人用,是不需要修改的;当然为防万一,在增加按键的时候还是把这个同步。

2)如果项目只是需要修改某个键值,比如映射为其他键等,可以直接修改KeyEvent.java 这个类的getKeyCode方法即可,其他都不需要修改。

比如

android系统开机启动流程分析

一,系统引导bootloader 加电,cpu执行bootloader程序,正常启动系统,加载boot.img【其中包含内核。还有ramdisk】 二,内核kernel bootloader加载kernel,kernel自解压,初始化,载入built-in驱动程序,完成启动。 内核启动后会创建若干内核线程,在后装入并执行程序/sbin/init/,载入init process,切换至用户空间(user-space) 内核zImage解压缩 head.S【这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令】首先初始化自解压相关环境(内存等),调用decompress_kernel进行解压,解压后调用start_kernel启动内核【start_kernel是任何版本linux内核的通用初始化函数,它会初始化很多东西,输出linux版本信息,设置体系结构相关的环境,页表结构初始化,设置系 统自陷入口,初始化系统IRQ,初始化核心调度器等等】,最后调用rest_init【rest_init 会调用kernel_init启动init进程(缺省是/init)。然后执行schedule开始任务调度。这个init是由android的./system/core/init下的代码编译出来的,由此进入了android的代码】。 三,Init进程启动 【init是kernel启动的第一个进程,init启动以后,整个android系统就起来了】 init进程启动后,根据init.rc 和init. .rc脚本文件建立几个基本 服务(servicemanager zygote),然后担当property service 的功能 打开.rc文件,解析文件内容。【system/core/init/init.c】将service信息放置到service.list中【system/core/init/init_parser.c】。 建立service进程。【service_start(…) execve(…)】 在init.c中,完成以下工作 1、初始化log系统【解析/init.rc和init.%hardware%.rc文件,在两个 文件解析步骤2时执行“early-init”行动】 2、初始化设备【在/dev下创建所有设备节点,下载firmwares】 3、初始化属性服务器【在两个文件解析步骤2时执行“init”行动】

IOS与android手机系统区别

浅谈IOS与android IOS: 2007年推出,属于类Unix的商业操作系统,用Objective-c编写,拥有较多优雅之处,系统结构分为以下四个层次:核心操作系统(the Core OS layer),核心服务层(the Core Services layer),媒体层(the Media layer),Cocoa 触摸框架层(the Cocoa Touch layer)。核心理念就是“应用为王”. IOS 4.0观点: 1.界面和分辨率的统一性 2. 软件商店分级与分类细致 3. 塑造了良好的开发环境 4. 提供云服务与设备的互动 Android: 2008年首次推出,是一种基于Linux的自由及开放源代码的操作系统,主要使用于便携设备,如智能手机和平板电脑。系统结构分为以下四个层次:应用程序层、应用程序框架层、系统运行库层和linux 核心层。核心理念就是“开源” Android 2.3观点: 1. Android将成为智能手机份额第一 2. Android是真正的多任务系统 3. Android安装程序更简单 4. android吸引众多终端厂商

大体功能一览表:

下面我们分开来看看它们系统具体优于对方什么. 一.IOS优势于android分析: iOS设备时便能够确切地知道可以从中得到什么;当可以进行主要功能的升级时,你可以从清晰的计划表中获得相关信息,升级内容的差异最多也只存在于手机和平板电脑之间。而Android则不同,它的差异不仅体现在手机和平板产品之间,就连各种版本的手机之间也是千差万别。IOS完美的流畅性源于系统编程语 言以及细心所带来的优势(用户界面渲染的过程被赋予了很高的优先级,当触摸屏开始 操作,系统将停止所有进程,将所有资源集中对节目进行渲染),这个是android的一直以来的目标。 精美的设计。苹果设计的界面,不管是外观还是易用性,都饱含了体贴细致的理念。人们往往可以迅速掌握iOS设备,甚至很多小孩子都在熟练使用iPad。相比之下Android则稍微欠缺。 近70万的IOS应用,严格控制第三方应用,需要通过审批, 且大多数收费应用带来的是: 一是开发人员能因此获得收益,以促使他们的程序开发工作进入良性循环; 二是将会吸引更多的大牌游戏开发商开发出优秀产品,为用户提供更优质的服务. 比起android通过软件内部广告收费,当然更胜一筹.

Android应用开发基本知识点汇总

Android应用开发基本知识点汇总 Activity 一生命周期 4种状态 running / paused / stopped / killed 生命周期 Activity启动 onCreate -> onStart -> onResume 点Home返回主界面 onPause -> onStop 再次回到原Activity onRestart -> onStart -> onResume 退出Activity onPause -> onStop -> onDestroy 进程优先级前台/可见/服务/后台/空 二任务栈 三启动模式 standard singleTop 栈顶复用 singleTask 栈内复用 singeInstance 四scheme跳转协议 服务器可以定制化告诉App跳转哪个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面 Fragment 一第五大组件 为什么是第五大组件 Fragment相对Activity更节省内存,切换更舒适Fragment加载到Activity的两种方式 静态加载xml 动态加载fragmentTransaction.add(id, fragment, “name”); .commit; FragmentPagerAdapter与FragmentStatePagerAdapter

FragmentStatePagerAdapter在切换时回收内存,适合页面较多的情况FragmentPagerAdapter并没有回收内存,只是detach了Activity 二生命周期 onAttach -> onCreate -> onCreateView -> onViewCreated -> onActivityCreated -> onStart -> onResume -> onPause -> onStop -> onDestroyView -> onDestroy -> onDetach 先创建Activity后创建Fragment,先销毁Fragment后销毁Activity 三Fragment之间的通信 Fragment调用Activity getActivity Activity调用Fragment 接口回调 Fragment调用Fragment方法findFragmentById 四FragmentManager replace add remove Service 一应用场景,与Thread区别 Service是什么后台长时间运行,没有用户界面,运行在主线程,不能有耗时操作 Service与Thread区别 Activity难以与Thread交互,尤其当Activity销毁以后 二开启Service的两种方式 StartService onCreate -> onStartCommand -> onBind -> onDestroy onStartCommand return START_STICKY;

Android 开机启动流程

Android的开机流程 1. 系统引导bootloader 1) 源码:bootable/bootloader/* 2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择 a) 开机按Camera+Power启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式,加载recovery.img,recovery.i mg包含内核,基本的文件系统,用于工程模式的烧写 c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况) 2. 内核kernel 1) 源码:kernel/* 2) 说明:kernel由bootloader加载 3. 文件系统及应用init 1) 源码:system/core/init/* 2) 配置文件:system/rootdir/init.rc, 3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1)源码:frameworks/base/cmds/app_main.cpp等 2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是/system/bin/app_process a)建立Java Runtime,建立虚拟机 b) 建立Socket接收ActivityManangerService的请求,用于Fork应用程序 c) 启动System Server 5. 系统服务system server 1)源码:frameworks/base/services/java/com/android/server/SystemServer.jav a 2) 说明:被zygote启动,通过SystemManager管理android的服务(这里的服务指frameworks/base/services下的服务,如卫星定位服务,剪切板服务等) 6. 桌面launcher 1)源码:ActivityManagerService.java为入口,packages/apps/launcher*实现 2) 说明:系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,桌面程序Home就是在ActivityManagerService.systemReady()通知的过程中建立的,最终调用()启launcher 7. 解锁 1) 源码: frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 2) 说明:系统启动成功后SystemServer调用wm.systemReady()通知WindowManagerService,进而调用PhoneWindowManager,最终通过LockPatternKeyguardView显示解锁界面,跟踪代码可以看到解锁界面并不是一个Activity,这是只是向特定层上绘图,其代码了存放在特殊的位置

基于MT6752的 android 系统启动流程分析报告

基于MT6752的Android系统启动流程分析报告 1、Bootloader引导 (2) 2、Linux内核启动 (23) 3、Android系统启动 (23) 报告人: 日期:2016.09.03

对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动。但根据芯片架构和平台的不同,在启动的Bootloader阶段会有所差异。 本文以MTK的MT6752平台为例,分析一下基于该平台的Android系统启动流程。 1、Bootloader引导 1.1、Bootloader基本介绍 BootLoader是在操作系统运行之前运行的一段程序,它可以将系统的软硬件环境带到一个合适状态,为运行操作系统做好准备,目的就是引导linux操作系统及Android框架(framework)。 它的主要功能包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。在可执行环境创建好之后,接下来把software装载到内存并执行。除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。 由于不同处理器芯片厂商对arm core的封装差异比较大,所以不同的arm处理器,对于上电引导都是由特定处理器芯片厂商自己开发的程序,这个上电引导程序通常比较简单,会初始化硬件,提供下载模式等,然后才会加载通常的bootloader。 下面是几个arm平台的bootloader方案: marvell(pxa935) : bootROM + OBM + BLOB informax(im9815) : bootROM + barbox + U-boot mediatek(mt6517) : bootROM + pre-loader + U-boot broadcom(bcm2157) : bootROM + boot1/boot2 + U-boot 而对MT6752平台,MTK对bootloader引导方案又进行了调整,它将bootloader分为以下两个部分: (1) 第1部分bootloader,是MTK内部(in-house)的pre-loader,这部分依赖平台。 (2) 第2部分bootloader,是LK(little kernel的缩写,作用同常见的u-boot差不多),这部分依赖操作系统,负责引导linux操作系统和Android框架。 1.2、bootloader的工作流程 1.2.1 bootloader正常的启动流程 先来看启动流程图:

android各版本区别

Android 4.0 与4.1 4.1有新的东西尤其帧速提高了3倍 首先,新版系统使用了新的处理架构,Android设备中出现的双核、四核处理器能得到更好的优化,发挥出强劲的性能表现。 其次,在新版系统中,特效动画的帧速提高至60fps,4.1版系统还将会优化最佳性能和很低的触摸延迟,提供一个流畅、直观的用户界面。 为了确保帧速一致,4.1版本的Android框架所有的绘图和动画都将统一VSYNC计时,应用渲染、触摸事件、画面构图、显示刷新等操作都会锁定在16毫秒响应,所有的帧都没有提前或者落后。 Android 4.1新增三重影像缓冲技术,让所有的渲染感觉更顺畅。触摸延时不仅会遵循VSYNC计时,还会在触摸操作时做出预判提前渲染,此外在CPU闲置时会分配更多的处理能力来应对触摸事件,确保触摸没有延迟。 SDK开发工具也将会提供一个新的工具systrace,可以让开发者从Linux内核中直接手机数据,来判断造成渲染中断的原因。 望采纳。 Android 4.1与4.2 没有本质变化。在细节之后做了一些改进与升级,比较重要的包括:Photo Sphere全景拍照;键盘手势输入;Miracast无线显示共享;手势放大缩小屏幕,以及为盲人用户设计的语音输出和手势模式导航功能等。尤其令人关注的是,谷歌在Android 4.2中新加入了新的恶意软件扫描功能。手机有:LG Nexus 4、三星I9250 Galaxy Nexus 红米,小米3啦,魅族mx3等都是基于安卓4.2深度开发的 android 4.2系统十大特性: 1、完整的Chrome浏览器 Android 4.2的Web浏览器的变化将非常受欢迎,支持选项卡浏览系统以及书签同步。这样的设计为了使手机和平板电脑的使用和传统PC使用无异。 2、全新的手机风景模式 作为Android 4.2,将集合手机以及平板电脑一体,在使用手机时,可以使用类似于平板电脑尺寸的风景模式,并且可以进行反转。 3、全新的文件管理器 Android 4.2将集合一个全新的文件管理器,使用户可以方便的管理SD卡上的文件,而不再依赖于第三方软件。 4、文本输入选项的改进 Android 4.2重新设计了键盘的布局,甚至将无用的数字和符号都一并略去了。

《Android应用开发》课程标准

《Android应用开发》 课程标准 内蒙古电子信息职业技术学院计算机科学系

一.课程设置概述 1.1课程在相关专业中的性质与定位 Android应用开发是物联网应用技术专业(应用开发方向)的核心课程之一,是Android应用程序开发方法的主要课程,是Android应用的主要领域。为了适应高职学生的学习情况,该课程以Android应用技术为重点,逐步阐述Android应用体系结构,介绍Android应用常见的几个功能。采用项目+案例教学法,既让学生掌握Android的基本知识,同时,也让学生在潜移默化中了解一些Android 的高级开发技术,从而为今后实现Android应用开发打下基础。 本课程的任务是使学生通过学习和操作实践,了解和掌握Android的主流应用技术及其开发方法,掌握Android的sdk、Activity、高级UI、网络、多媒体体方面的编程技术。为进一步学习移动互联工程师后续课程打下良好的理论和实践基础。 1.2 本课程的基本教学理念 (一)突出学生主体,注重技能培养,回归能力本位 Android应用开发是移动互联工程师的专业核心课程,注重软件开发基本理论、基本方法和基本技能的学习及素质教育,激发学生的学习兴趣,在启发、提示下使其自主地、全面地理解软件的基本理论和基本方法,提高学生的思维能力和实际操作技能,增强他们理论联系实际的能力,培养学生的创新精神,使学生养成观察、独立分析和解决问题的习惯;以提高技能、磨砺意识、活跃思维、展现个性和拓宽视野。 (二)尊重个体差异,注重过程评价,促进学生发展 本课程在教学过程中,倡导自主学习,启发学生对设定问题积极思考、分析,鼓励多种思维方式并将其表达出来,尊重个体差异。采用项目教学法进行教学,每个项目的成绩采取自评、互评、教师综合评价相结合的方式能激励学生的学习兴趣和自主学习能力的发展。教师在给学生评价成绩时应尽量以学习过程中的评价为主,注重培养和激发学生的学习积极性和自信心。最后期末的成绩评价应注重检测学生的知识应用能力。学生的最终课程成绩应由平时的各次项目成绩和期末的评定成绩按一定比例构成,在把握比例构成时要有利于促进学生的知识应用能力。建立以过程培养促进个体发展,以学生可持续发展能力评价教学过程的双向促进机制,以激发兴趣、展现个性、发展心智和提高素质为基本理念。 (三)整合课程资源,开放创新教学,拓展学习渠道 本课程在教学过程中,提醒学生留意观察并思考生活中接触的Android系统应用,鼓励其结合生活中熟悉的操作方法提出问题或假设,在教师引导下,通过分析、推理,使学生自主学习、总结,以便增强学生对Android开发方法基本理论的理解;通过课堂讲解与讨论、案例分析等促进学生对所学理论的理解和运用,以培 养其实际操作技能。充分利用现代教学手段,不断改进教学方式,突出典型案例

linux内核启动 Android系统启动过程详解

linux内核启动+Android系统启动过程详解 第一部分:汇编部分 Linux启动之 linux-rk3288-tchip/kernel/arch/arm/boot/compressed/ head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步 开头有一段宏定义这是gnu arm汇编的宏定义。关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解 另外此段代码必须不能包括重定位部分。因为这时一开始必须要立即运行的。所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错 #ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心 #if defined(CONFIG_DEBUG_ICEDCC)

……具体代码略 #endif 宏定义结束之后定义了一个段, .section ".start", #alloc, #execinstr 这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Section contains executable instructions. 生成最终映像时,这段代码会放在最开头 .align start: .type start,#function /*.type指定start这个符号是函数类型*/ .rept 8 mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader

盘点Android系统版本发展历程1

盘点Android系统版本发展历程 作为手机系统中的后起之秀,Android至今已有六个版本。 Android 1.1 发布时间:发布于2009年2月 Android 1.5 该版本又叫“Cupcake”,这是第一个主要版本,发布于2009年5月。这个升级之后,Android表现出来的能力才真正吸引了开发者的目光。用户界面得到了极大的改良,并且增添了以下功能:录像蓝牙A2DP 自动蓝牙连接上传视频到 YouTube 以及 Picasa 复制/粘贴功能Android 1.6 搭载Android 1.61的HTC Hero获得了意想不到的成功。Android最终获得了非Android用户的关注,并且也让竞争者苹果和微软更加警惕了。Android 1.6 “Donut” 2009 年9月发布。这个版本包含了:主要特性 Android 应用市场集成照相、摄像以及浏览, 多选/删除功能手势搜索语音搜索应用集成极大提升了语音阅读功能对非标准分辨率有了更好的支持 Android 2.0/2.1

2009年10月26日,又一个主要版本升级以创纪录的速度放出。这次,大版本升级到了Android 2.0/2.1 “Eclair”,它包含:主要特性提升硬件速度更多屏幕以及分辨率选择大幅度的用户界面改良支持Exchange活动墙纸大幅改进虚拟键盘蓝牙 2.1 Google 地图 3.1.2 Android 2.2 该版本名字叫“Froyo”,中文代号称“冻酸奶”,Nexus One的用户已经开始接受Android 2.2“FroYo”的无线更新,其他机型的用户应该会在短时间内获取到这一更新。这一版本包含大量让其他手机用户垂涎三尺的更新,包括了: - 全新的JIT编译器 - 额外的可用RAM:2.2将使用新的Linux内核(从2.6.29升级至 2.6.32),可存取更大的RAM内存 - 增强支持OpenGL ES 2.0:增加新的API接口让开发者更容易使用OpenGL ES 2.0 - 支持Flash 10.1:Android版Flash将会在今年上半年正式发布,新版本Android系统将会直接内置,或者通过固件升级获得 - 修复多点触摸传感器的问题

Android开机启动流程样本

Android的开机流程 1. 系统引导bootloader 1) 源码: bootable/bootloader/* 2) 说明: 加电后, CPU将先执行bootloader程序, 此处有三种选择 a) 开机按Camera+Power启动到fastboot, 即命令或SD卡烧写模式, 不加载内核及文件系统, 此处能够进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式, 加载recovery.img, recovery.img包含内核, 基本的文件系统, 用于工程模式的烧写 c) 开机按Power, 正常启动系统, 加载boot.img, boot.img包含内核, 基本文件系统, 用于正常启动手机( 以下只分析正常启动的情况) 2. 内核kernel 1) 源码: kernel/* 2) 说明: kernel由bootloader加载 3. 文件系统及应用init 1) 源码: system/core/init/* 2) 配置文件: system/rootdir/init.rc, 3) 说明: init是一个由内核启动的用户级进程, 它按照init.rc中的设置执行: 启动服务( 这里的服务指linux底层服务, 如adbd提供adb支持, vold提供SD卡挂载等) , 执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1) 源码: frameworks/base/cmds/app_main.cpp等 2) 说明: zygote是一个在init.rc中被指定启动的服务, 该服务对应的命令是/system/bin/app_process

Android系统启动过程详解

Android系统启动过程详解 Android系统启动过程 首先Android框架架构图:(来自网上,我觉得这张图看起来很清晰) Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用。 启动的过程如下图所示:(图片来自网上,后面有地址)

下面将从Android4.0源码中,和网络达人对此的总结中,对此过程加以学习了解和总结, 以下学习过程中代码片段中均有省略不完整,请参照源码。

一Init进程的启动 init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行, 并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。 启动过程就是代码init.c中main函数执行过程:system\core\init\init. c 在函数中执行了:文件夹建立,挂载,rc文件解析,属性设置,启动服务,执行动作,socket监听…… 下面看两个重要的过程:rc文件解析和服务启动。 1 rc文件解析 .rc文件是Android使用的初始化脚本文件(System/Core/Init/readm e.txt中有描述: four broad classes of statements which are Actions, Commands, Services, and Options.) 其中Command 就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是linux 命令, 还有一些是android 添加的,如:class_start :启动服务,class_stop :关闭服务,等等。 其中Options是针对Service 的选项的。 系统初始化要触发的动作和要启动的服务及其各自属性都在rc脚本文件中定义。具体看一下启动脚本:\system\core\rootdir\init.rc 在解析rc脚本文件时,将相应的类型放入各自的List中: \system\core\init\Init_parser.c :init_parse_config_file( )存入到 action_queue、action_list、service_list中,解析过程可以看一下parse_config函数,类似状态机形式挺有意思。 这其中包含了服务:adbd、servicemanager、vold、ril-daemon、deb uggerd、surfaceflinger、zygote、media…… 2 服务启动 文件解析完成之后将service放入到service_list中。 文件解析完成之后将service放入到service_list中。 \system\core\init\builtins.c

Android SystemBar启动流程分析

Android SystemBar启动流程分析 SystemBars的服务被start时,最终会调用该类的onNoService()方法。 @Override public void start() { if (DEBUG) Log.d(TAG, "start"); ServiceMonitor mServiceMonitor = new ServiceMonitor(TAG, DEBUG, mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this); mServiceMonitor.start(); // will call onNoService if no remote service is found } @Override public void onNoService() { if (DEBUG) Log.d(TAG, "onNoService"); createStatusBarFromConfig(); // fallback to using an in-process implementation } private void createStatusBarFromConfig() { … mStatusBar = (BaseStatusBar) cls.newInstance(); … mStatusBar.start(); } BaseStatusBar是一个抽象类,故调用其子类的PhoneStatusBar的start 函数。 @Override public void start() { … super.start(); … } 子类的start又调用了父类的start public void start() { … createAndAddWindows(); … }

AndroidL系统启动及加载流程分析

Android L系统启动及加载流程分析 1、概述 Android L的启动可以分为几个步骤:Linux内核启动、init进程启动、native系统服务及java系统服务启动、Home启动,主要过程如下图: 图1 整个启动流程跟4.4及之前的版本相差不多,只是有个别不同之处,本文我们主要分析Linux内核启动之后的过程。

2、启动过程分析 2.1 init进程启动 当系统内核加载完成之后,会启动init守护进程,它是内核启动的第一个用户级进程,是Android的一个进程,进程号为1,init进程启动后执行入口函数main(),主要操作为: 图2 AndroidL上将selinux的安全等级提高了,设为了enforcing模式,4.4上是permissive模式。 解析rc脚本文件,即init.rc脚本,该文件是Android初始化脚本,定义了一系列的动作和执行这些动作的时间阶段e aryl-init、init、early-boot、boot、post-fs等阶段。init进程main 函数中会根据这些阶段进行解析执行。AndroidL上为了流程更清晰,增加了charger(充电开机)、ffbm(工厂模式)、以及late-init阶段,实际上这些阶段是对其他阶段的组合执行,比如late-init:

2.2 ServiceManager的启动 servicemanager的启动就是init进程通过init.rc脚本启动的: 源码在frameworks/native/cmds/servicemanager/service_manager.c中,servicemanager是服务管理器,它本身也是一个服务(handle=0),通过binder调用,为native和Java系统服务提供注册和查询服务的,即某个服务启动后,需要将自己注册到servicemanager中,供其他服务或者应用查询使用。AndroidL上servicemanger中在处理注册和查询动作之前添加了selinux安全检测相关的处理。 2.3 SurfaceFinger、MediaServer进程启动 Android4.4以前,surfacefinger的启动根据属性system_init.startsurfaceflinger,决定是通过init.rc启动还是systemserver进程启动,之后的版本包括AndoridL都是通过init.rc启动的: 启动后会向servicemanager进程注册服务中,该服务启动时主要功能是初始化整个显

android应用技术简介

Android技术应用简介 摘要:近几年来,Android逐渐成为便携设备上的主要操作系统。2011年Android 在全球的市场份额首次超过塞班系统,跃居全球第一。本文主要通过阐述Android的主要思想、发展状况以及核心技术来使读者对Android有一个初步的认识。 关键词:Android、linux、NDK、google 这学期我们开设了《Android应用程序开发》这门课程。这么课程开始的时候同学们都很兴奋。因为Android在现在是最为流行的操作系统。同学们大部分用的手机都是Android操作系统。所以对它的名字非常熟悉,但是对它的真正意义和具体是如何实现Android应用程序却十分陌生。同学们都希望了解到自己的手机上的应用程序到底是如何实现其功能的。所以对这门课程产生了极大的兴趣。 这门课程主要给我们介绍了Android开发环境、应用程序、生命周期、用户界面、组件通信与广播信息、后台服务、数据存储与访问、位置服务与地图应用、Android NDK开发这9个方面的内容。让我们对Android有一个初步的认知。这本书上的内容仅仅是Android程序开发的一小部分,是引导我们正确看待Android。在今后的学习中还需要我们多看关于Android的书籍,关注Android 各方面的消息,多做关于Android的实验和课题。这样才能进一步了解这个当今全球最为流行的操作系统。 1、Android简介 Android是一种以linux为基础的开放源代码操作系统,主要使用于便携设备。目前尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。Android操作系统最初由Andy Rubin开发,最初主要支持手机。2005年由google 收购注资,并组建开放手机联盟开发改良,逐渐扩展到平板电脑及其他领域上。Android的主要竞争对手是苹果公司的iOS以及RIM的Blackberry OS。2011年第一季度,Android在全球的市场份额首次超过塞班系统,跃居全球第一。 2012年2月数据,Android占据全球智能手机操作系统市场52.5%的份额,中国市场占有率为68.4%。 Android的系统架构和其它操作系统一样,采用了分层的架构。android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。 Android是以Linux为核心的手机操作平台,作为一款开放式的操作系统,随着Android的快速发展,如今已允许开发者使用多种编程语言来开发Android 应用程序,而不再是以前只能使用Java开发Android应用程序的单一局面,因而受到众多开发者的欢迎,成为真正意义上的开放式操作系统。 在Android中,开发者可以使用Java作为编程语言来开发应用程序,也可以通过NDK使用C/C++作为编程语言来开发应用程序,也可使用SL4A来使用其他各种脚本语言进行编程(如:python、lua、tcl、php等等),还有其他诸如:QT(qt for android)、Mono(mono for android)等一些著名编程框架也开始

android开机启动流程简单分析

android开机启动流程简单分析 android启动 当引导程序启动Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统同时会加载用户级别的第一个进程init(system\core\init\init.cpp)代码如下: int main(int argc, char** argv) { ..... //创建文件夹,挂载 // Get the basic filesystem setup we need put together in the initramdisk // on / and then we'll let the rc file figure out the rest. if (is_first_stage) { mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); #define MAKE_STR(x) __STRING(x) mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)); mount("sysfs", "/sys", "sysfs", 0, NULL); } ..... //打印日志,设置log的级别 klog_init(); klog_set_level(KLOG_NOTICE_LEVEL); ..... Parser& parser = Parser::GetInstance(); parser.AddSectionParser("service",std::make_unique()); parser.AddSectionParser("on", std::make_unique()); parser.AddSectionParser("import", std::make_unique()); // 加载init.rc配置文件 parser.ParseConfig("/init.rc"); } 加载init.rc文件,会启动一个Zygote进程,此进程是Android系统的一个母进程,用来启动Android的其他服务进程,代码: 从Android L开始,在/system/core/rootdir 目录中有4 个zygote 相关的启动脚本如下图:

塞班和安卓最全全面的比较分析

塞班和安卓都是智能手机操作系统,软件都非常丰富,无论是通信交流、上网、聊天、拍照、听歌、视频、看书、杂志、看图、生活社交、炒股理财、微博、邮件、英语学习、实用工具还是游戏娱乐,塞班能做的事,安卓也都能做,反之亦然。但它们也有着各自显著的特点。 (1)塞班是能上网的手机,安卓是带电话功能的互联网终端。 塞班手机的电话相关功能,比如通讯录、分组、短信群发、通话记录、情景模式、铃声的设置等等方面是十分完善和人性化的;而安卓在这些基本功能方面还是不够的。 上网方面,塞班手机支持WAP和WWW网站,GO浏览器甚至可以在线观看优酷和土豆网等网络视频。而安卓由于它的出身,已经支持Flash和HTML5,上网体验不亚于PC;同时安卓非常依赖于手机互联网,是很耗费流量的。 此外,诺基亚手机的信号好,而很多安卓手机都有信号不太好的问题。 (2)塞班实用,安卓华丽。这是从界面上来说的,包括系统的主屏桌面和应用程序界面。不过,塞班可以安装很多漂亮的主题,整个桌面、背景和图标等所有元素都可以替换的跟iPhone一样;还可以安装桌面软件,使得主屏桌面可以很像安卓。 塞班好用不好玩。安卓好玩不好用。从软件实用功能方面来说,比如通话短信方面,塞班手机安装了相关软件就可以实现:通话背景音、魔音、通话录音、来电大头贴、来电自动答录、虚拟来电、虚假信息、定时发短信、短信备份、短信加密、语音识别发短信、聊天式短信、免费发短信、语音对讲、未接来电未读短信提醒等等实用功能。 回归本质上来说,手机作为电话它的实用性是很重要的,比如稳定可靠和待机时间长。有人说塞班是你玩手机,安卓是手机玩你;塞班用户的爱好是电话短信聊QQ,安卓用户的爱好是刷机重启抠电池。虽然有点夸张,但也说明了一些情况。因为安卓手机比较容易假死重启死机等;而且安卓手机是很费电的,玩游戏或WiFi上网可能2个多小时就没电了;如果不是出于便携性,它的上网体验能好过上网本和平板电脑吗? 说安卓好玩和安卓玩你并不矛盾,其中一方面都是说安卓需要折腾。 (3)塞班开发之初的目标是要保证在较低资源的设备上能长时间稳定可靠的运行,这导致了塞班的应用程序开发有着较为陡峭的学习曲线,开发成本较高。但是程序的运行效率很高。比如5800的128M的RAM,后台可以同时运行10几个程序而操作流畅(多任务功能是特别强大的,值得一提,不像某些水果手机),即使几天不关机它的剩余内存也是保持稳定。 由于塞班发展的很久,它的应用程序也是非常丰富的,再加上诺基亚手机在国内的占有率很高,所以国内开发的各种最新手机软件大部分都有塞班的版本。 而谷歌主导的安卓一开始就是一个移动互联网操作系统,第一追求的是功能,对CPU、RAM等资源要求高,至于长时间稳定可靠的运行似乎不是最重要,大不了重新启动一下手机。 安卓使用Java作为应用程序层面的开发语言,程序开发入门容易,开发者众多,应用程序丰富。但Java程序是解释执行的,程序运行效率比编译成机器码直接执行的塞班程序要低很多。而且程序占用内存很高,比如同样功能的手机QQ,塞班s60v5版占用RAM大约6M,而安卓版则需要30M。所以安卓手机才需要配置512M的RAM和高主频的CPU。 不过应用程序再丰富,无论塞班还是安卓,安装后值得保留的偶尔一用的程序也就 50~100个,最常用的不过10个。所以号称几万个应用程序又有多大意义呢?不过,从目前来看,安卓在游戏资源上是略有优势的,这也是安卓“好玩”的一个原因。 (4)塞班和安卓的区别不是绝对的,它们是相互影响、相互融合的。这点就不用说了。 从塞班S60v5到塞班3、塞班belle,诺基亚是一直在努力。此外,QT平台的应用,对于塞班应用程序的开发和移植将具有加速性的推动作用。 PS:诺基亚手机一般的拍照效果和音质都比安卓手机好,尤其是卡尔蔡司认证镜头的拍照手机,和音乐手机,就比安卓手机好得多了。 所以安卓手机适合上网和游戏,而诺基亚手机功能全面,均衡才是王道。

Android开发技术文档

Android 开发最佳实践 从Futurice公司Android开发者中学到的经验。遵循以下准则,避免重复发明轮子。若您对开发iOS或Windows Phone 有兴趣,请看iOS Good Practices和Windows client Good Practices这两篇文章。 摘要 ?使用 Gradle 和它推荐的工程结构 ?把密码和敏感数据放在gradle.properties ?不要自己写 HTTP 客户端,使用Volley或OkHttp库 ?使用Jackson库解析JSON数据 ?避免使用Guava同时使用一些类库来避免65k method limit(一个Android程序中最多能执行65536个方法) ?使用 Fragments来呈现UI视图 ?使用 Activities 只是为了管理 Fragments ?Layout 布局是 XMLs代码,组织好它们 ?在layoutout XMLs布局时,使用styles文件来避免使用重复的属性 ?使用多个style文件来避免单一的一个大style文件 ?保持你的colors.xml 简短DRY(不要重复自己),只是定义调色板 ?总是使用dimens.xml DRY(不要重复自己),定义通用常数 ?不要做一个深层次的ViewGroup ?在使用WebViews时避免在客户端做处理,当心内存泄露 ?使用Robolectric单元测试,Robotium 做UI测试 ?使用Genymotion 作为你的模拟器 ?总是使用ProGuard 和 DexGuard混淆来项目 Android SDK 将你的Android SDK放在你的home目录或其他应用程序无关的位置。当安装有些包含SDK的IDE的时候,可能会将SDK放在IDE同一目录下,当你需要升级(或重新安装)IDE或更换的IDE时,会非常麻烦。此外,若果你的IDE 是在普通用户,不是在root下运行,还要避免吧SDK放到一下需要sudo权限的系统级别目录下。 构建系统

相关主题
文本预览
相关文档 最新文档