一.认识android的架构
十多年的南湖网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整南湖建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“南湖网站设计”,“南湖网站推广”以来,每个客户项目都认真落实执行。
Android其本质就是在标准的Linux系统上增加了Java虚拟机Dalvik,并在Dalvik虚拟机上搭建了一个JAVA的application framework,所有的应用程序都是基于JAVA的application framework之上。
android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。
二.搭建环境
搭建开发环境
对国内的开发者来说最痛苦的是无法去访问android开发网站。为了更好的认识世界,对程序员来说,会翻墙也是的一门技术,带你去领略墙外的世界,好了,不废话了, 国内开发者访问(androiddevtools) 上面已经有了所有你要的资源,同时可以下载到我们的主角framework
但是这样的搭建只能去阅读源代码,我们无法去更进一步去实现自己的rom,我们看到锤子的系统在早期的开放rom是自己从新实现了framework的代码,现在看起来他成功了,所以我们还要去搭建android系统的源码编译环境。
搭建源码编译环境
三.开始主题
在一开始写c程序的时候都有一个运行的入口,比如
#include iostream
#include cmath
#include algorithm
using namespace std;
//这里的main就是应用的入口
int main(int argc, const char * argv[]){
return 0;
}
在计算机网络原理中我们用socket实现一个服务器端,不断的接听客户端的访问,而且他的代码是这样实现的:
#include winsock2.h
#pragma comment(lib, "WS2_32.lib")
#include stdio.h
void main()
{
WORD wVersionRequested;//版本号
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
//加载套接字库,如果失败返回
err = WSAStartup(wVersionRequested, wsaData);
if (err != 0)
{
return;
}
//判断高低字节是不是2,如果不是2.2的版本则退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//创建流式套接字,基于TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址结构体的创建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//转换Unsigned long型为网络字节序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定端口号,除sin_family参数外,其它参数都是网络字节序,因此需要转换
//将套接字绑定到一个端口号和本地地址上
bind(socSrv, (SOCKADDR*)addrSrv, sizeof(SOCKADDR));//必须用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字义用来接收客户端Socket的结构体
int len = sizeof(SOCKADDR);//初始化参数,这个参数必须进行初始化,sizeof
//循环等待接受客户端发送请求
while (1)
{
//等待客户请求到来;当请求到来后,接受连接请求,
//返回一个新的对应于此次连接的套接字(accept)。
//此时程序在此发生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)addrClient, len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化输出
//用返回的套接字和客户端进行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多发送一个字节
//接收数据
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他采用了一个while死循环去监听客户端的请求。
先上源代码
public final class ActivityThread {
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("pre-initialized");
Looper.prepareMainLooper();
//从中可以看到为app开辟了一个线程进入了looper之中
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
看到源码失望了,没有一个while循环啊,其实用了他方法实现
//用一个looper的机制循环监听响应
Looper.prepareMainLooper();
Looper.loop();
进一步深入代码
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 在这里看到了一个循环监听消息
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(" Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println(" Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}
驱动都是使用C写的,所以你想搞底层驱动开发,你要有一定的C基础。对于开发驱动来说,Windows系统是非常不适合的,特别是Android本身就是Linux内核,所以你也要掌握Linux操作系统,比如脚本的编写,C代码的编译等等。
随着智能手机的飞跃发展,特别是Android智能机的爆炸性发展,Android驱动工程师是越来越受欢迎的一个职位,而且是一个非常值得人期待的职位,因为可能你参与研发的一款手机就能改变了很多人的生活,所以,进阶吧,Android驱动程序猿,那怎样成为一名优秀的Android驱动程序猿,我来发表一下我的意见吧,希望各位网友不要轻易拍砖。
Android驱动的基础知识
首先作为Android驱动程序猿,你必须清楚的了解你要做的是什么,平时需要用到的基础知识,对Android的基本框架的了解还是非常的有必要,对linux下的编程基础也需要了解,因为严格来说,Android驱动是基于Linux驱动,个人强烈推荐阅读Linux Device Driver 3rd版,这本书讲了Linux下设备驱动的基础知识,作为Android驱动程序猿,你需要能最好读懂这本书,而且是反复的阅读这本书,因为我发现每次重新读这本书,都有新的收获,这本书很值得一读,强烈五星级推荐;而且还要会基本的C编程,能很好的读懂和编写一些C程序,而且懂一些基础的Java那就更好了,因为Framework层的代码与驱动层的代码联系也比较紧密,稍微懂一些Java代码,你会发现你对整个驱动框架的了解会更加的熟悉,相关的Linux编译脚本和Linux编译体系,因为商业开发的一些原因,Android本身的文件架构体系可能会被一些编译脚本而改变,加入新设备驱动,你需要了解整个的驱动编译体系,那样书写驱动程序也会更加的清晰!
\
Android/Linux相关驱动框架知识
为详细了解一下Android驱动程序员需要会的技术,我特意百度了各家Android驱动程序员招聘需求对Android程序猿的要求,选择哪几家呢,国产手机的代表,中兴,华为,酷派,联想,小米,魅族,VIVO都是非常不错的国产手机厂商,而且研发的Android智能手机越来越好,我甚至还专门去看了一下新兴Android智能机公司,包括锤子手机官网的Android驱动工程师招聘需求,One Plus One的官网连个加入我们的链接都木有,创业型的公司不知道是人才暂时饱和,还是啥原因,居然没有招聘信息,汇总发现,这些公司要求差异不是特别大,出了需要基本的Android调试能力,你还需要对Android各模块驱动框架的了解,比如,某锤科技的Android驱动工程师招聘需求,大伙可以去试试,锤子手机号称是在做最好的手机,比目前的旗舰手机都要好一点点,加入它,还蛮有期待的! \ 某米公司的Android驱动工程师也需要Android/Linux相关的知识,中兴和联想的Android招聘需求就比较笼统了,估计是大公司的缘故吧, \ 中兴的官网居然开始找不到驱动工程师的招聘,我的个神,废了我好大劲,才找到相关的招聘信息! \
相关的硬件知识和通信知识
Android驱动平时工作就是调试各种外围设备,是直接跟硬件打交道的职位,需要你看的懂电路原理图,了解基本的显示原理和基本的摄像头成像原理等等,这是跟你平时工作非常相关的基础知识,做Android智能手机,你也需要了解基本的通信相关知识,射频原理和基本的Modem相关知识,只有懂相关的硬件知识和通讯设备相关的基础知识,你才可以写出更好的Android驱动程序,才能调试出更满意的效果!
热爱驱动开发和不断学习
其实这点是非常的重要,应该摆在第一位,首先是你必须喜欢这份工作,你才可以做的更好,兴趣是最好的老师,这句话是真心的大实话,而目前的社会状态是什么赚钱,就一窝蜂的冲去做那个,结果,最后可能做的很不开心,然后,钱也没捞到;如今,我的大学同学很有一部分都放弃了所学的专业对口工作,有去卖保险的,有去工厂做普工的,有去做销售的,有去吃铁饭碗的,当然职业肯定不分贵贱好坏,我说这一点,主要是建议大家去坚持最初的梦想!我的梦想就是做出一款可以改变人们生活的移动终端,让这个世界因为我而有一点点的不同,童鞋们,一起坚持梦想吧! 此外,做Android驱动工程师需要的是不断的学习,时刻保持着一股激情,不断的学习才能更好的完成日常的驱动开发任务,并能保持对开发的的敏锐感觉,我觉得乔布斯的:Stay hungry,Stay foolish说的很好,一直被当做是我的座右铭,来激励我坚持做一个更好的Android驱动工程师,写这篇博客的目的就是分享我的一些小看法,日后我还是会不断更新我的博客,分享一些驱动开发相关的文档和博客,和广大的驱动程序猿一起进步!