① 应用公园制作app可以拿走源码吗
应用公园制作app可以拿走源码吗:首先其次最后手机APP制作流程:无需技术,教你制作一个自己的手机APP
一款手机APP的制作,说复杂非常复杂,涉及到多个领域的研发,稍复杂一点的个人研发基本上搞不定,但是,也有非常简单的手机APP一站式制作运营方法。
随着移动互联网基层开开发技术的发展,无需编程技术,也可以在应用公园制作手机。这里就以应用公园为例,教您熟悉手机APP制作流程,手把手教你制作一款自己心仪的手机APP。
第一步:了解自己想要制作一款怎么的手机APP。是软硬件结合? 游戏 类?商城类?新闻资讯类?互动类?聊天类?还是团购类、同城服务类?送餐类?企业展示类?
每一个类别的APP开发差异非常大,主要就是不同类型所需要的功能支持。对自己想要做的APP有个大致的了解,但是这一步很多人都没搞清楚,大部分人都存在一个大概模糊的创意、想法阶段。
第二步:了解自己想要做的APP的基础功能,划分板块。
对基础功能的了解、板块的分类,上手最快的方法就是:查看市场上类似的APP进行借鉴。
第三步:界面及交互的设计
界面及交互的设计,可以直接使用“墨刀”。可以先设计一个大概,后期不断丰富。
第四步:APP功能的开发制作
APP功能的开发直接使用应用公园就可以了。应用公园把市场上常见的APP功能进行拆分组合,你不需要懂任何编程技术,只需哟安把需要的功能挑选出,组合搭配一个,就能迅速组建出一个手机APP。
手机APP制作具体流程:
1、打开应用公园的官网,点击“开始制作”,注册登录;
2、应用公园为在线APP制作平台,所以不需要下载任何东西,直接进入制作页面就可以;
3、应用公园目前有两种模式:
(1)主题模式:应用公园平台上,已经很多已经制作完善的手机APP软件,可以直接当做模板使用,仅需要把里面的文字图片进行替换,就可以快速制作一款APP。
(2)自由模式:就像拼图一样,把需要的功能自由组合搭配一下,就可以创造一款独一无二的手机APP。
每一个功能控件的具体功能,都通过后台自动配置。
4、手机APP打包
制作完善后,在应用公园平台直接点击制作完成,就会自动打包成手机安装程序。
5、应用发布上架
在应用公园平台直接申请应用发布,通过联网后,就可以联网使用了。
6、下载管理、运营
应用公园提供运营管理后台、下载站点、下载二维码、手机管理助手等APP相关产品,一站式服务,自动配置,免去多次开发成本,而且后期的功能、内容的更新迭代自己既可以搞定,也不需要具体的编程技术。
自己制作app需要 编程知识 。但依靠第三方工具,三分钟就可以做成专属自己的APP。下面以简易网为例演示:
简网APP工厂三大特点
1、最低的成本:节省所有开发成本,以及仅几分钟的时间成本。
2、实用的功能:贴近传统网站的内容编辑与发布方式。
3、灵活的运营:生成APP后,一个人也可以完美运营。
先来了解一下APP工厂:三分钟制作APP
使用简网APP工厂之前,我曾经通过其他类似的APP公司制作过两三个不同版本的免费APP,简网的操作流程是制作门槛最低的一家。
不支持用户名注册,需要使用微博账号
新浪与腾讯微博用户数几乎覆盖全网网民数,我们默认用户已经拥有微博账号,以便于进行APP快速创建。
填写APP信息:几分钟搞定
制作APP之前我们需要做一些准备工作,比如我们要明确我们要做一个怎样的APP,我们要为这个APP准备一张1024x1024的ICON以及一张114x114的小图标,另外还需要一张640x1136的开机图。
从简网APP工厂的首页,经过3次跳转,省略了网站注册过程,通过模板挑选完成APP美工定案,所需的是APP的图标与应用简介。全过程几分钟足矣。
快捷实用的后台采编系统
我们制作了一个新闻资讯类的APP软件,同时我们拥有了一个功能齐全的后台更新系统。利用后台可以完全解决APP内容更新问题,可以快速进行新闻发布,包括文字、图片、视频、微博等形式,并且引入了完善的评论系统与社区系统。
笔者至今使用过三家大型网站的后台系统,由于种种 历史 原因,这些后台系统都存在或多或少的不合理设计,也许是因为承载的功能过多,数据架构过于复杂,在新入职人员上手操作时,需要经过长时间的熟悉过程。
简网为我们制作的APP提供了统一的后台模板,这个后台的功能亮点在于不仅提供原始录入,还提供也许是目前设计最为合理的网络来源抓取功能。包括网页、微博在内的网络内容,都可以在大约1分钟时间内导入后台中,并且实时呈现在用户手机上的APP客户端。
APP的生成时间约为三分钟,APP容量只有3M,一般的宽带都可以在1分钟之内下载好装进手机
我们得到了一个可安装的APP软件
同时获得了一个功能完善的编辑后台
快速的内容抓取,让后台采编人员的数量可以降到最低,维持一个日更新量在100篇文章左右的APP客户端,一个工作人员足矣。
内容采编神器:发布到应用
“发布到应用”这个功能可以说是管理后台提供的最强大的一个功能,经过简单的设置后,我们可以在几秒钟之内把网络内容发布到我们的APP客户端。
这样一个媒体类APP就做好了。
很高兴回答这个问题。
我是从事安卓App开发的,开发过很多App,那么App是如何制作的。
页面设计
我们看到的app都一个个页面,每个页面功能不同。首先是产品经理通过调研整理需求,然后将需求整理成页面(可以使用墨刀等网页制作),然后在交给UI人员进行专业设计和美化,最后将设计图打包给开发人员。
开发设计
拿安卓举例,开发使用语言也分几种,具体得根据实际情况来选择。
1.原生开发
安卓一般使用java语言开发,当然现在也有kotlin语言进行开发。如何开发就涉及到具体编程了,这里就不详说了。简单描述就是使用安卓提供的一系列控件来实现页面,复杂点的页面可以通过自定义控件来实现。
2.使用H5语言开发
使用H5开发的好处有很多,可以多端复用,比如浏览器端,ios端,当然H5开发的体验是没有原生好的。结合我做过的项目来说,一般是这个页面需要分享出去的话,就用H5开发。
3.使用flutter开发
flutter是近年来谷歌推出的一款UI框架,
使用dart语言进行开发,支持跨平台,weight渲染直接操作硬件层,体验可媲美原生。但是flutter技术比较新,生态还不完善,开发起来效率相对偏低
页面数据填充
页面开发出来只是空壳子,没有数据填充,这时候就需要通过接口获取数据,然后解析数据,显示在页面上。
到此,一个大概的App制作流程就结束了。
首先你要清楚自己想要什么样的APP,是做哪一方便的?简单的?还是复杂的
一下我就分为两类进行回答
一,简单APP
必要岗位
ui设计师(至少一个)
主要负责APP页面的搭建和交互的梳理
客户端开发人员(至少一个)
目前市面上的APP开发方式多为混合开发,如果做一个简单的APP可以选择webapp,这样不但可以减少开发周期还可以控制开发成本
服务端开发(至少一个)
目前服务器语言很多php,java,
node.js
非必要岗位
首先 ,我说的非必要岗位不是说这些岗位不重要,而是说在为了减少成本的情况下,这样岗位可以被别的岗位所替代
产品经理
如果开发的App功能简单,UI设计师就可以担任这样职责
测试工程师
当然,在时间允许的情况下,开发人员也可以是测试人员
二,复杂APP
复杂app可以考虑纯原生开发,那么客户端至少两个人进行开发(安卓,IOS),或者考虑混合开发,及web前端+原生开发人员
必要岗位
ui设计师,安卓开发工程师,ios开发工程师,后端开发工程师,产品经理,测试工程师,人员的多少可以根据项目的大小来定
三,必要成本
服务器 :这是开发app必须要的,也就是我们放代码的地方
上架审核所需费用 :比如IOS上架审核的花好几百,安卓要申请软着等
今年六月的时候,萌生了开发一个记账 App 的想法,想去用自己的 App 记账,管理收支。那时正好在英国是考试周,放假后,我回到了国内,准备去实现我的计划。没想到这暑假很快就结束了,在这个暑假中经历的太多的事,准备了要去美国读研的考试,遇到了生命中的另一半,同时,也将 Costuary for iPhone 带到了这个世界。
Logo
说道为什么要开发这样一个 App ,因为笔者在 UK 读书,市面上很少有记账 App 能够实现实时汇率的换算,带有这个功能的 App 也是操作繁杂。所以要自己开发一个,功能并没有那么复杂的,并且能够满足自己在国外和国内生活需求的 App,所以自己编写了 iPhone 的客户端,为了获取汇率和 Excel 导出,又用 Java 设计和编写了 Costuary 的后端服务器。
比起今年年初开发的 Flat Weather,这个项目的代码量大约是他的十倍,需要实现众多的功能和模块。
这篇文章将会介绍一下 Costuary 的功能与我开发过程中的一些心得。
效果图设计
说到设计,两年前,我还是一个 android 开发者,Google 的 Material Design 是我的最爱,所以,Costuary 采用了 Android 5.0 之后采用的 Material Design 设计。其中掺杂了一些我自己的设计,因为 Material Design 的控件有时候操作繁琐。
早在 5 月份的时候已经零零总总的用 Sketch 画出了这个产品的 UI 和图标,之后开始了漫长开发的过程。
Sketch交互
与去年开发的 Android 版不同,iPhone 版的 Costuary 采用了底部导航栏的设计,相比于 Android 通常使用的 Navigation Drawer 的抽屉布局,底部导航栏的设计即使在右手操作 iPhone 的时候都不会太费力。
UX功能 Features
Costuary 支持世界上主要货币的实时汇率转换,所有外汇在统计时会转换成主货币的数目,方便查看花销。
日历视图能够很直观的反映出哪一天有消费和收入。
说到记账软件,量化消费的图表无疑是重要的一环,Costuary 提供了饼状图来视觉化一段时间的花销。
可以建立多个账户来表示自己的银行卡,支付宝,现金等等。
可以看出本月的预算还有多少。
如果想要进行更加详细的分析,可以使用导出功能将账本导出到 Excel。
允许备份账本内容到 iCloud。
开发
去把一纸设计变成真正的产品,这是一个独立开发者应该具有的能力。只会写代码不只是我唯一掌握的,能够去设计出来自己想要的应用并且将他实现才是我在做的事情。
这款应用的开发并没有想象中的简单,需要自己去实现大量 Android UI 控件,很多圆角,阴影,字体,要慢慢的去调整,让控件适合 iPhone 的屏幕。整个应用的背后有 3 个关系型数据库来储存账户,账本与各种汇率。与以前开发的 Flat Weather 不同,Costuary 会产生大量的用户数据,所以整个软件架构的稳定性变得异常重要,需要设计一些机制来防止数据丢失与损坏。
Development
为了实现 App 获取每日的汇率,并且在 iPhone 上能够实现账本导出到 Excel ,我设计了一个服务器后端来处理这些繁杂的实物。每次 App 启动后会与我的服务器来更新最新的汇率。当用户选择导出时,账本会被发送到服务器上并处理为 Excel 发送到用户的邮箱里。
Mail
说到服务器,就不得不提到用户隐私了,因为导出到 Excel 功能需要将账本传到我的服务器上做进一步处理,很多人会觉得我侵犯了他的个人隐私。对此,为了保护我的权益与用户的权益,我撰写了 Costuary 软件许可及服务协议与 Costuary 隐私政策,这是我作为独立开发者这么多年后第一次去写许可协议。
Agreement资费
与我的其他产品一样,这款 App 依旧是免费供大家使用的,作为独立开发者,我们都知道,绝大多数用户不会去珍惜一个免费的产品。就像 Flat Weather 一样,虽然获得了很多人的支持,但是也收到了很多人的吐槽。在 Costuary 中依然设计了一个的捐助按钮,如果大家使用之后喜欢这个应用,请支持我将他维护下去。
Please donate me尾巴
Costuary for iPhone 是我开发出来过最大的软件体系。我相信,能够独立开发出来产品的人懂得不只是编程。一个人要去经历项目的全部生命周期:规划,设计,开发,运营,维护,营销,这些是我开发这么多产品所学会的。
现在的 Costuary 只是第一个版本,还有很多 iPhone 的特性没有来得及开发,以后会跟上的,比如 iPhone X 的适配,3D Touch、Today Widget、Touch ID 等等。
以前在少数派撰稿的时候,很多读者会来问我如何学习开发,我也特地去写过如何去学习编程,但我相信,真正想去学习的,想去为这个生态贡献出自己的一份力的人,自己都会找到学习的方法。我的专业是电子电器而不是软件工程,但是我不后悔当年去学习编程。
最后,还是感谢在背后默默支持我的人,我会不断地改进与提升,如果 Costuary 真的在记账方面给予了你便利,这是我莫大的荣幸。
如果想要了解我的更多作品可以访问我的个人博客 MikeTech,或者在少数派中阅读我以前写过的文章。今年年初也在 iPhone 上写过一个天气 App,天气应用 Flat Weather 的设计历程
对了,关于记账有什么用,如何记账,如何养成记账的习惯。为什么每个月末都捉襟见肘,除了没钱,很可能是对财务管理的能力不强。想了解这一方面的知识,不妨看一看我派的付费阅读栏目:从零开始做好个人记账
你好,非常感谢你的邀请。
开发一个app的话首先
第一步、需要调研,分析开发需求。
第二步、根据你的开发需求整理一个开发方案,选择合理的架构。
第三步、开始研发。
第四步、测试。
第五步、上线试运行。
第六步、查缺补漏后投入使用。
开发一个app的话。有多种选择。可以找一个第三方公司来进行开发。也可以自己招聘开发团队。也可以交给比较信任的程序员朋友来进行开发。第三种方式的话,属于接私活儿,成本较低。 当然前提你得有认识的人。
我也是程序员出身。参与过web网站开发。传统办公开发。H5开发。微信小程序开发。以及安卓开发。有着较丰富的开发经验。自己完全可以胜任一个App,如果你有这方面的事需求的话,也可以私信我。我是山东的。如果方便的话也可以面谈。
App软件开发,从之前的沟通需求、规划设计、程序开发、测试修改、它的发布等。这是一个非常复杂和漫长的过程,一旦进入通信,就需要定期维护和功能变更。它需要大量的专业人员参与,成本自然很高。 所以,随着更新市场的发展和人们福利的提高,现在已经不像传统开发那么困难了。只需要动动鼠标,不需要触碰代码就可以完成制作app部分。
App开发已成为企业发展的重要推动力量
十年巨变!移动互联网已颠覆我们的时代,商业、社交、视频、新闻、工具等领域,移动应用的渗透率已高达95%,在团购 旅游 和零售行业,移动端收入规模已超过PC端,手机APP已成为企业不可或缺的线上阵地。
不用编程就能制作app的在线平台,摆脱了很多复杂的流程,还能减少用户的麻烦,不会制作,而且可以在平台上查看详细的课程,非常贴心的设置!在这里,我想说的是,如果你想制作app的话,可以在平台上查看详细的课程。总的来说,这种方法会大大降低软件开发app的成本,节省时间,让很多人解决了资金短缺和想快速制作app的问题。
app是如何制作的,APP如何开发?
随着智能手机APP软件的吸引力越来越大,越来越多的企业开始开发自己的APP应用。企业要想开发属于自己企业的APP应用,首先要分析自身的情况和市场对产品的需求。
在APP,开发这件事上,企业一定要注意以下几点。
1. 开发APP应用一定要明确以自己为中心,开发APP是否能带来巨大的利润。
2. 要了解目标用户的需求,配置APP吸引用户,提高用户购买应用的意愿。
3. 通过合作再次寻找潜在客户,我相信开发APP的收益远远大于成本。
开发APP苹果系统,必须使用Xcode苹果开发工具,一般采用Objective-C或Swift语言。Objective-C是继承了C语言的C字,可以直接用Objective-C语言进行编程。如果你不懂数据,差别很小。还有一些新的苹果后缀语言,非常有用。
Andro系统的app都是用Java语言开发的,Java语言已经流行了20多年,这个趋势还在持续和延续。如果想要安卓系统的app首先要掌握Java语言,对于说C语言的人来说,学习Java还是很容易的。如果你对自学感兴趣,Java网站上有很多培训课程,还有很多免费培训。视频,不想付费。如果这个绝对是零基础(没学过其他编程语言,比如c语言),如果真的很感兴趣,可以自学,但是速度比较慢。
总结:app开发拥有多种方法,选择最适合自己的方式方法很重要
答案写到这里,我想您应该知道了app的开发途径或者方法是什么。如果您是小企业或者是个体工商户,您可以找人帮忙开发小程序或者自己在一些网站上进行傻瓜式软件开发。正如上文所说,现在有很多的网站支持在线生成APP,常用的功能和接口都已经设置好了,操作起来不是很难。如果您是大企业,业务多访问量比较大,我的建议是您应该聘请专业的软件工程师开发专门的app,避免后期出现的问题没办法及时解决给您的企业带来损失。
不懂的话,找专业的人帮忙,我就是专业的
app即application program。应用程序。目前手机平台是ios和安卓两大平台的天下。本人不才从事安卓开发。简单介绍一下吧你问的这个问题范围太广。ios和安卓开发语言不同。ios使用的是object_c和swift。安卓是基于java。二者都属于面向对象的语言。开发平台安卓基于android studio早期使用的是eclipse+adt。不过已经被淘汰了。那么怎样开发app?首先你需要一个后台程序员写服务器以及搭建数据库。其次你的会ios或是android其中之一那么这就是最简单的配置.现在流行混合开发如果你再会点前端的h5和js就更好了。一般一个软件公司的基本配置是一个前端一个ios一个安卓一个后台。基本就满足你搭建网站和手机应用的需求了。不过你作为老板养这样一个团队很费钱。还不如找外包
软件的生成需要经历以下几个阶段:
1、满足用户需求——建立软件目标,设想产品功能,进行场景化细分说明;进行可行性分析,用户需求收集,用户需求场景描述;场景问题梳理;获取用户行为、想法;场景应用痛点,机会点
2、需求开发与管理——建立用户画像,从软件目标出发,进行问题梳理,场景行为分析,愿景分析,建立体验地图
3、利用Axure绘制软件原型,在用户场景中切入,并组织软件原型实施,在实施过程中进行问卷调查,收集问题,记录用户行为,不断改善软件需求,进行需求评审,进入评审优化
4、技术可行性分析——技术分析,场景分析,功能实现验证,
5、开发计划制定,实施,测试,验证,发布
② 如何高效阅读源代码
下面是之前写的一篇文章:《如何快速阅读源码》
本文探讨在需要了解一个开源项目时,如何快速的理清开源项目的代码逻辑!
以下是个人认为行之有效的方法:
本文以Mybatis为例来进行演示!
先“跑起来”程序界有个老传统,学习新技术时都是从“Hello World”开始的!无论是学习新语言时,打印“Hello World”;还是学习新框架时编写个demo!那为什么这里的“跑起来”要打个引号呢?
实际上,当你想要阅读一个开源项目的源码时,绝大部分情况下,你已经能够使用这个开源项目了!所以这里的“跑起来”就不是写个“Hello World”,也不是能跑起来的程序了!而是能__在你的脑子里“跑起来”__!什么意思?
Mybatis你会用了吧?那么请问Mybatis是如何执行的呢?仔细想想,你能否用完整的语句把它描述出来?
这里是Mybatis的官方入门文章!你是如何看这篇文章的?读一遍就行了吗?还是跟着文章跑一遍就够了吗?从这篇文章里你能获得多少信息?
我们来理一下:
回答出了上面这些问题!你也就基本能在脑子里把Mybatis“跑起来”了!之后,你才能正真的开始阅读源码!
当你能把一个开源项目“跑起来”后,实际上你就有了对开源项目最初步的了解了!就像“ 书的索引 ”一样!基于这个索引,我们一步步的进行拆解,来细化出下一层的结构和流程,期间可能需要深入技术细节,考量实现,考虑是否有更好的实现方案!也就是说后面的三步并不是线性的,而是__不断交替执行__的一个过程!最终就形成一个完整的源码执行流程!
自顶向下拆解继续通过Mybatis来演示(限于篇幅,我只演示一个大概流程)!我们现在已经有了一个大概的流程了:
虽说每个点都可以往下细化,但是也分个轻重缓急!
很明显,SqlSession去执行 sql才是Mybatis的核心!我们先从这个点入手!
首先,你当然得先下载Mybatis的源码了(请自行下载)!
我们直接去看SqlSession!它是个接口,里面有一堆执行sql的方法!
这里只列出了一部分方法:
SqlSession就是通过这些方法来执行sql的!我们直接看我们常用的,也是Mybatis推荐的用法,就是基于Mapper的执行!也就是说“SqlSession通过Mapper来执行具体的sql”!上面的流程也就细化成了:
那SqlSession是如何获取Mapper的呢?Mapper又是如何执行sql的呢?
深入细节我们来看SqlSession的实现!SqlSession有两个实现类SqlSessionManager和DefaultSqlSession!通过IDE的引用功能可以查看两个类的使用情况。你会发现SqlSessionManager实际并没有使用!而DefaultSqlSession是通过DefaultSqlSessionFactory构建的!所以我们来看DefaultSqlSession是如何构建Mapper的!
它直接委托给了Configuration的getMapper方法!
Configuration又委托给了MapperRegistry类的getMapper方法!
在MapperRegistry类的getMapper中:
在这里knowMappers是什么?MapperProxyFactory又是什么?mapperProxyFactory.newInstance(sqlSession)具体做了什么?
其实很简单,knowMappers是个Map,里面包含了class与对应的MapperProxyFactory的对应关系!MapperProxyFactory通过newInstance来构建对应的Mapper(实际上是Mapper的代理)!
快接近真相了,看mapperProxyFactory.newInstance(sqlSession)里的代码:
这里干了什么?
最终实际还是委托给了sqlSession去执行具体的sql!后面具体怎么实现的就自行查看吧!
延伸改进现在我们的流程大概是这样的一个过程:
现在我们大概知道了:
那么,
这个问题列表可以很长,可以按个人需要去思考并尝试回答!可能最终这些问题已经和开源项目本身没有什么关系了!但是你思考后的收获要比看源码本身要多得多!
再循环一轮结束后,可以再次进行:
不断的拆解->深入->改进,最终你能__通过一个开源项目,学习到远比开源项目本身多得多的知识__!
最重要的是,你的流程是完整的。无论是最初的大致流程:
还是到最终深入的细枝末节,都是个完整的流程!
这样的好处是,你的时间能自由控制:
而不像debug那样的方式,需要一下子花费很长的时间去一步步的理流程,费时费力、收效很小,而且如果中断了就很难继续了!
总结本文通过梳理Mybatis源码的一个简单流程,来讲述一个个人认为比较好的阅读源码的方式,并阐述此方法与传统debug方式相比的优势。
阅读源码是每个优秀开发工程师的必经之路,那么这篇文章就来讲解下为什么要阅读源码以及如何阅读源码。
首先来说下为什么要读源码,有学习源码的必要吗?
为什么要阅读源码?
关于为什么阅读和学习源码,我个人认为可能有以下几点:
(一)吊打面试官,应对面试
为了找到更好的工作,应对面试,因为在面试中肯定会问到源码级别的问题,比如:为什么 HashMap 是线程不安全的?
如果你没有阅读过源码,面试官可能会对回答的结果不满意,进而导致面试结果不太理想,但如果你对源码有所研究,并能够很好地问答面试官的问题,这可能就是你的加分点,可以形成自己独特的竞争力,吊打面试官,升职加薪不是梦。
(二)解决问题(bug)
在开发过程中,我们或多或少会遇到 bug,比如:在 foreach 循环里进行元素的 remove/add 操作,为啥有可能会报 异常?
我们可以先在 Google、Stack Overflow 以及对应项目的 Issues 里看有没有类似问题以及解决办法,如果没有的话,我们只能通过阅读源码的方式去解决了。如果我们对相关源码有所涉猎,就可以快速定位到问题所在。
(三)提升编程能力
和阅读一本好书一样,阅读源码就是和编程大牛面对面交流的机会,在许多优秀的开源项目中,它们的编码规范和架构设计都是很棒的,另外在设计上也使用了大量的设计模式,通过阅读和学习源码,能够快速提升我们的编码水平,以及对设计模式有更深的理解。
同时,在我们阅读完一个源码后,可以触类旁通,能够快速地对其他框架的源码进行阅读和学习,减少时间成本。
除了上述提到的原因之外,可能还有许多,在这里就不一一赘述了,那么在确定了要阅读源码之后,就让我们看下如何阅读源码吧!
如何阅读源码?
如何阅读源码取决于你为什么要读源码,比如:
下面大概说下阅读源码的几点建议:
在阅读之前,可以先从开源项目的官网上看它的架构设计和功能文档,了解这个项目的 整体架构、模块组成以及各个模块之间的联系 。
如果没有对应的项目文档,可以根据代码的模块进行梳理,以形成对项目的初步了解,或者 查看已有的源码解析文章或者书籍 ,在阅读源码之前,了解项目的架构和思路会使阅读源码事半功倍。
在了解一个类的时候,可以使用 ctrl+F12 来查看类中的成员变量和方法。
可以通过 IDEA 的 Diagrams 功能去了解一个类的继承关系。
多打 断点调试 ,断点追踪源码是很好的阅读源码的方式,可以先通过 debug 了解下调用逻辑,都和哪些类有关联,有大致了解后再通过 debug 了解整体代码的功能实现,各个类都起到了什么作用,有没有涉及到设计模式等。
另外,优秀的开源项目中肯定会有许多地方应用到了 设计模式 ,建议在阅读源码之前,需要对常用的设计模式有大致的了解,不然阅读源码的效率会大大降低。
如果遇到读不懂某部分源码的时候,可以先跳过,之后再回来看,如果属于搞不懂这部分就茶不思饭不想的人,可以在网上找是否有该部分源码的解析或者文档,也可以自己通过 源码注释和测试用例 去阅读学习。
一般优秀的开源项目都会有 单元测试 ,可以通过对应类的单元测试去了解方法的含义和用法,加深对源码逻辑的理解。
在阅读源码的时候,可以在代码上加上 注释和总结 ,同时还可以画出 时序图和类图 ,这样对阅读源码有很大的帮助,可以很清楚地知道类之间的调用关系和依赖关系,也方便以后回顾,重新阅读。
在这里推荐大家一个 IDEA 插件 SequenceDiagram,可以根据源码生成调用时序图,便于阅读源码。
刚开始阅读源码,不建议直接看框架源码,可以先从 jdk 源码看起:
jdk 源码也是非常庞大的,可以分模块来阅读,下面是建议的阅读顺序:
其他包下的代码也可以做下了解,JDK源码阅读笔记:https://github.com/wupeixuan/JDKSourceCode1.8
再有了一定的源码阅读经验后,可以再去学习 Spring、Spring Boot、Dubbo、Spring Cloud 等框架的源码。
总结主要介绍了为什么读源码以及如何读源码,供大家参考,每个人都有适合自己的阅读源码的方式,希望可以在学习中去摸索出一套属于自己的方式。
阅读源码不是一蹴而就的,这是持久战,只要你能够坚持下来,肯定受益匪浅。阅读源码的过程比较枯燥,可以在社群里一起讨论学习,这样可能效率更高些。
没看过源代码,都不好意思出来说了,最近刚好在看一些,来说一个。
先看使用 https://element.eleme.cn/#/zh-CN/component/installation
先看一下这个库是做什么用的,然后提供了哪些功能。
看GitHub https://github.com/elemefe
一般会看下项目最新的情况,然后没有关闭的issue,看下wiki,大家在讨论什么。
再看代码
clone 一份到本地,然后先看下目录结构,然后根据文档看几个简单的组件的时候,一边看掘金上的分析,一边自己看下实现。
e le
饿了么这个框架代码结构还是很清楚的,基本上每个组件都是分开的,所以你只要看其他的一个文件夹就行。然后一些工具的都在src文件夹。
要学会看issue,一般开源的项目都有人会来提建议,有些是bug,有些是功能,你可以看看自己是否有能力去解决,如果可以的话,你可以去fork代码,然后自己修改,再提pr。
我最近恰好找摸索出一个梳理遗留系统架构的技巧:自底向上 找到一个典型的切面 沿着调用和回调的路径 在代码中添加结构化注释(比如eclipse中加//TAG 流程A1.1 甲->>乙),这样便得到了一个code地图,并且在tasks视图中看起来很直观(看起来跟书的目录一样)可快速跳转。将目录到有道云笔记的markdown序列图中 就自动生成了一个序列图。
我觉得这基本上就是可缩放的可视化架构地图了,对维护一个比较乱和庞大的遗留系统非常有帮助,定位代码 修改维护都方便多了。
1、需要过硬的基础知识,这个前提。不然基本语法、常用的模式都不晓得怎么读。
2、多参考 历史 版本和更新变化,好的源码都是反复迭代出来的精华,开始就读精华是很不明智的,所以看看版本更新说明,版本的 历史 演变。就想人一样是怎样进化过来的。
3、参考别人阅读注释,想必在你读源码之前也有人读过了源码,并且总结,注释。和分享原理,可供你参考,毕竟每个人读一篇文章,理解的东西是有差异化的。
4、直接买书,有些作品直接出书就是源码精解
5、找个大神给你慢慢分析,这个最快。娓娓道来,直接面授比啥都强。缺点是,你容易跟着他的思维走下去。
我觉得阅读代码就不应该高效,而应该像看小说一样,看的过程就像是在和作者交流,有趣才是看代码的动力。
画图,看数据走向,逻辑走向
先弄清楚这些代码实现了哪些功能,然后从主线开始往下看,好的代码光看变量和接口名称就能明白是什么意思?扒出源码实现的整体框架逻辑,然后再对自己感兴趣的模块进行剖析,还是从整体把握,细节深入,慢慢地整个框架就被丰满了。
接下来是思考为什么要如此设计,这样设计的好处是什么?如果是你来做应该怎么设计,把你觉得源码缺点的地方进行仔细研究,了解里面是否包含自己不清楚的细节,避免遗漏。
接下来就是根据代码改造或者是调试错误,对于源码中遇到的不理解的地方一定要弄明白,有的确实是画蛇添足,有的有独特的作用。
多多学习,对每一种主流框架铭记于心,对主流设计模式了如指掌,万变不离其宗,源码看多了,跟看一个电视机遥控器的操作说明一样。
1、一边阅读代码一边写注释。这是我用过的最好的方法,对代码理解得更深入,看一些重要代码或者特别难懂的代码时挺有用。更何况,注释也是一种文档嘛。
2、一边阅读代码一边绘制UML。这个方法适用于类之间的关系较复杂和调用层次较深的情况,我一般都是先绘制顺序图,然后为顺序图中的类绘制关系图。
3、通过Debug来跟踪程序的主要执行过程,这样就可以分清主次了,阅读的时候更有针对性。
4、类的快速阅读。先弄清楚它在继承链中的位置,看看它的内部状态,也就是成员变量,一般来说,类的对外接口都是对成员变量的访问、加工、代理等,然后看看它的对外接口,也就是公有成员函数,识别核心的一个或多个函数,这时候你应该可以大概了解这个类的职责或作用了。可能这个类是某个设计模式中的一个组成部分,所以,设计模式的掌握对代码的快速阅读也是很有帮助的。
5、带着问题去阅读。比如想了解android中的消息机制,那么看看Looper、Handler、MessegeQueue这几个类就可以了,其他的不要去看,要不然就跑题了。
下面列几个阅读源码时所处的情景,在特定场景下用哪些方法: 不太熟悉业务逻辑,还不是很清楚它是干啥的,可以用3、5。 代码量很大,有几十万行,甚至百万行,可以用2、3、5。 你无法看见程序的运行过程,比如没有用户界面,也有可能是无法运行的,可以用3、5。 设计复杂,用了大量的设计模式,调用链很深,可以用1、2、3、4、5。 时间有限,没有那么多时间让你看源码,可以用3、5。
画出逻辑流程图,先了解整体流程,再详解具体函数
③ android实战培训课程
⑴ 安卓培训主要学习哪儿些内容
每个人准备培训情况和基础都是不一样的,但是看了你的问题之后觉得咱俩的情况还是很相似的,我是去年毕业的,当时我学的是计算机专业,当时在学校的时候开的各门的课程都是以理论基础为主要的,我也不是说大学的教育不好,可是当时的课程一般都是教授级别的给我们讲一般的模式就是老师讲课在上面念PPT我们在下面拍照,等最后考试的时候老师直接给我们划题答案背过基本这一年就这样过去了,技术类的东西是真心没学到,后来华清远见到我们学校和我们学校合作,给我们弄得安卓方面的实训课程,觉得自己欠缺的很多的,也是怕和你这种情况一样找不到理想的工作,所以我就在华清远见进行的安卓培训,当时我们的学习内容主要有以下几点,其实各种的培训班的课程都是大同小异的老师属于一部分的因素最关键的还是要靠自己的。
第一阶段的课程一般都是Java编程开发,这一部分应该会和Java后台有相关联的地方,但是比Java后台简单,这一阶段一般要学习Java语法和Java面向对象思想、Java数据结构及算法、GUI界面编程、Java进程与线程、Java网络通信与流、设计模式、数据库和Javaweb,安卓在这一阶段的学习内容看似和后台关联性很大,但是这一部分我们只学习后台一些基础的东西和日后会用到的东西,我们要把基础奠定好。
第二阶段要学习的内容是安卓基础开发,主要的课程内容为Android界面编程(界面编程是Android入门的核心技术,内容纵多,涉及四大组件之一Activity、Wedget、自定义View、事件处理、动画处理、列表、图片处理、国际化、资源文件、菜单、通知、对话框、Tools/ActionBar/Fragment、样式/主题、Intent。)、进程与线程、服务与广播、数据存储、网络通信、多媒体以及硬件相关,这一阶段更注重安卓入门基础的培训,一定要好好的把握。
接下来学习的内容是一个进阶阶段,主要学习的是安卓的高级开发,一般的课程内容为HOME开发、NDK开发等、地图开发项目发布等等,以上就算是安卓培训的所有学习内容,但是你掌握了学习内容之后还是远远不够的,一般的培训班都会给我们安排项目实战的,这是一种思想的锻炼,我们做什么就要有什么的思维做后台的有做后台的思维,做前端的有做前段的思维,我们学安卓的进行手机端APP开发的就要有安卓的思维,这一阶段也是很重要的,就好比我们在华清远见学完整体的内容之后也参与了一些项目的实战。
我把每一阶段要学习的课程都给你整理了,你可以现在有准备的去看一些基础的视频或者相关的书籍了。
⑵ 我想学习安卓开发,哪个培训机构靠谱呢
没什么好与不好,建议对比师资选择,管理团队拥有平均10年以上IT培训行业从业经验,核心讲师团队由Mars、老罗、饼干等移动互联网传奇名师领衔,以良知教学为本、责任心强,平均8年的执教经验,在业内首屈一指,教学方面可以不用担心。
⑶ 现在的安卓教育培训是真的吗
当然是真的,首先国内移动互联时代是移动应用App的爆发式增长,人们的消费与使回用倾向正逐渐向移动答端转移,这种趋势就如同当初的互联网一样势不可挡。从各项统计来看,现在App的大行其道,正慢慢的吞噬着软件业。都说互联网改变了我们的生活,不过短短的数年时间,带来的却是一整个属于移动端的时代。
其次移动开发行业的人才供不应求,缺口逐渐加大,所以除了专业的开发者,也吸引了一大群尝试择业的在职者和优秀毕业生。与此同时,移动端的教育培训缺口也被打开,一些经典的如Android开发培训课程受到了学员们热烈的追捧。
数据表明,当前Android已经占到移动系统的80%以上。因而越来越多的应届毕业生与在职者从原来的专业或职业中走出来,拥抱IT,拥抱移动互联网这个朝气蓬勃的产业。首选就是学Android开发,因而选择好的线上或线下Android培训机构就显得极为重要。
最后好的Android开发培训课程,必然来自好的Android开发培训机构。尚硅谷教育通过全日制小班授课与项目实战相结合的形式,全方位的服务学员,专注于移动互联网领域高端课程的研发。
⑷ Android培训课程有什么内容
今后,业界将有两种移动开发课程体系:一种是其他机构Android课程,一种是尚硅谷Android+HTML5混合开发课程。
尚硅谷Android课程全面升级为《Android+HTML5混合开发》,让学员如虎添翼!在原Android课程基础上加入HTML、CSS、JavaScript、React核心,React Native跨平台混合开发、豆瓣搜索项目实战等H5前端技术。
当前,同时掌握“Android原生开发”+“H5跨平台开发”两大核心技术的复合型移动开发人才严重供不应求,薪资节节攀升,就业及未来职业发展都极具竞争力。
⑸ 安卓系统 培训 有什么课题可以选
只要写GUI开发就可以了,这本身就很深奥了。可以从以下着眼: 1.GUI框架 2.各个控键的重复使用 3.高扩展性 4.性能优化 可以参考一下《Java Swing ...
⑹ 安卓培训多少钱,安卓培训课程有哪些
Android培训周期一般都是4个月,至于培训费用大部分培训机构的收费标准都不相上下,部分Android高端培训费用会偏高一点,费用2W+。选择Android培训除了看培训机构外也要看自身条件,适合参加什么样的培训,例如普通还是高端,普通的Android培训零基础也可以,但高端Android培训就需要计算机语言基础了。
好程序员Android高端班课程,是一套涵盖 Java 语言强化、Java Web 开发、Android 应用开发、Android 游戏开发的专业课程。本套课程真正围绕Android知识体系制订,绝非由Java EE课程、Java ME课程或者Symbian课程改造而成。每一阶段课程涵盖多个实战项目,每个知识点均对应项目中实际功能,学习新知识的同时不断向项目中添加新功能,独特的教学方法帮助学员强化学习目标,迅速提升学习能力。致力于培养Android 高端开发人才,旨在培养真正的 Android 应用和游戏开发能力的高素质人才,学员毕业即具备行业前沿开发技术。
第一阶段 Java面向对象高级编程——java编程语法进阶
该阶段课程重点讲解了面向对象设计原则与设计模式;智能家居之远程监控。
Java面向对象编程
1、面向对象设计原则
2、面向对象设计模式概要
3、面向对象设计模式a.创建型设计模式b.结构型设计模式c.行为模式4、数据结构与常用算法
第二阶段 高级JDK API开发技术 —— Java Web编程
该阶段课程重点讲解了JDK当中的高级API的使用方法,包括新的并发线程库和反射机制。手机安全卫士
Java Web编程
1、并发线程库介绍
2、线程本地变量的使用方法
3、信号量与可重入锁
4、读写锁的使用方法
5、阻塞队列与同步 *** 库使用方法
6、Java反射机制介绍
7、Class、Field和Method的使用方法
8、动态代理模式的使用方法
9、Java框架开发原理
第三阶段 Android基础阶段大纲
一、UI基础
1.Android环境搭建及工程目录介绍:1.1 Android开发(版本:SDK21及以上版本)环境搭建1.2 Android发展史、移动设备操作系统、四层系统架构等理论知识1.3 HelloWorld程序1.4 adb shell简介(install uninstall)
2.常用UI布局及主要控件2.1 LinearLayout2.2 RelativeLayout2.3 FrameLayout2.4 GridLayout2.5 TextView基本用法
3.表单UI控件及相应控件的事件处理3.1 EditText、Button、ImageView3.2 RadioButton及RadioGroup的用法3.3 CheckBox的多选效果及监听3.4 Toast的基本用法
4.Spinner、AutoCompleteTextView、ScrollView及适配器、数组资源4.1 Spinner4.2 适配器4.3 数组资源4.4 AutoCompleteTextView4.5 ScrollView4.6 ProgressBar、SeekBar、RatingBar
5.UI美化及Android资源5.1 Style的简单用法5.2 Android资源汇总
二、应用核心组件初识
1.Activity生命周期及页面跳转传值1.1 Activity的声明和使用1.2 Activity生命周期1.3 Activity现场保护1.4 Activity基本页面跳转及传值1.5 Activity具有返回值的页面跳转
2.Activity启动模式及Intent七大属性2.1 Task和Back Stack的基本概念2.2 Activity的启动模式2.3 Intent属性的特点及用法
3.AsyncTask异步任务3.1 使用异步任务的必要性3.2 异步任务的用法
4.ListView基本用法及适配器介绍4.1 ListView基本用法4.2 SimpleAdapter4.3 BaseAdapter
5.ListView优化及分页加载数据、GridView加载网络图片、ExpandableListView5.1 ListView优化5.2 ListView滚动监听实现分页加载数据5.3 GridView加载图片
三、数据存储
1.菜单及对话框1.1 OptionsMenu1.2 ContextMenu1.3 PopupMenu1.4 PopupWindow1.5 AlertDialog1.6 ProgressDialog1.7 列表对话框1.8 自定义Dialog
2.数据存储2.1 SharedPreferences2.2 内部存储2.3 外部存储2.4 存储Bitmap图片到外部存储
3.SQLite数据库与CursorAdapter适配器3.1 回顾SQLite3.2 SQLiteOpenHelper的用法3.3 CursorAdapter
4.ContentProvider4.1 ContentResolver实现系统数据库的操作4.2 自定义ContentProvider
5.Loader5.1 CursorLoader的用法5.2 AsyncTaskLoader加载本地数据
四、移动开发主流界面实现
1.动画资源1.1 帧动画1.2 补间动画1.3 属性动画
2.Fragment2.1 Fragment基本用法2.2 Fragment传值2.3 Fragment性能优化
3.ViewPager3.1 ViewPager与适配器3.2 ViewPager加载网络图片3.3 PagerAdapter的优化
4.书签导航4.1 书签导航多种实现方式(无需代码实现)4.2 RadioGroup + ViewPager + Fragment实现导航4.3 HorizontalScrollView + ViewPager + Fragment实现导航
5.Handler、Looper消息传递机制5.1 Handler、Looper消息传递机制的原理5.2 Handler、Looper源码
五、应用核心组件进阶(Android Studio开发环境教学)
1.ActionBar (Action View、SearchView)+ ToolBar1.1 ActionBar1.2 ToolBar
2.BroadcastReceiver及Notification2.1 Notification (普通通知、大视图通知、进度条通知、自定义通知)2.2 广播接收器2.3 自定义发送广播
3.Service基础3.1 Service介绍3.2 Start Service3.3 IntentService3.4 Bind Service3.5 两种服务混合使用实现MediaPlayer音乐播放
4.跨进程的Service4.1 AIDL4.2 Messenger
5.LruCache与Bitmap二次采样、WebView与HTML5混合开发5.1 LruCache5.2 二次采样5.3 WebView5.4 HTML5混合开发
六、View深入探究
1.网络地图1.1 网络地图基本用法1.2 网络地图搜索
2. 事件分发消费机制2.1 事件分发消费机制原理2.2 事件分发消费机制的应用场景
3.自定义View(一)3.1 自定义View介绍3.2 自绘制的自定义View
4.自定义View(二)4.1 具有接口回调的自定义View4.2 继承于ViewGroup的自定义View
5.机型适配及SVN搭建5.1 机型适配介绍5.2 屏幕相关重要概念回顾5.3 机型适配的解决方案5.4 SVN搭建
第四阶段 Android项目实战阶段大纲
一、项目实战第一阶段
1.TabLayout及SlidingPaneLayout1.1 TabLayout(5.0Material Design新技术)与ViewPager配合自定义Tab1.2 SlidingPaneLayout左侧或右侧滑动1.3 NavigationView(5.0Material Design新技术)HeaderLayoutMenu xml配置Navigation监听事件
2.okHttp网络访问框架及Picasso2.1 okHttp框架的介绍2.2 okHttp框架的用法Http请求方法:get,post同步请求,异步请求(回调在非UI线程中)2.3 Picasso加载网络图片的用法简单图片请求Picasso通用配置:内存缓存大小,磁盘缓存大小及位置图片加载配置:下载尺寸,填充模式,加载中图片,错误图片2.4 第三方侧滑菜单:SlidingMenu菜单设置
3.Fresco(壁画异步加载图片框架)3.1 Fresco框架的介绍3.2 Fresco框架的用法(中文文档)简单图片请求Fresco通用配置:内存缓存大小,磁盘缓存大小及位置图片加载配置:下载尺寸,填充模式,加载中图片,错误图片,顶层,底层,图片变形
4.PullToRefresh、SwipeRefreshLayout及Ultra PullToRefresh4.1 PullToRefresh框架配置事件回调多种控件PullToRefreshBase重写4.2 SwipeRefreshLayout配置事件回调4.3 Ultra PullToRefresh(中文文档)配置事件回调多种下拉效果
5.打包(按渠道打包)、混淆及数字签名5.1 按渠道打包基本打包多渠道:资源,清单文件,代码,调试5.2 混淆开启混淆混淆配置:保留类,保留方法,忽略错误5.3 数字签名生成keystore配置签名
二、项目实战第二阶段——Android新技术
1.RecyclerView1.1 5.0新技术介绍(Material Design)设计理念、新增控件1.2 RecyclerView的用法、CardView的用法1.3 RecyclerView与ListView比较
2.5.0Material Design新技术2.1 CoordinatorLayoutToolbar与Layout2.2 TextInputLayout错误监听2.3 Snackbar监听Action2.4 FloatingActionButton属性介绍onClick
3.媒体播放器3.1 视频播放器VideoView3.2 SurfaceView及MediaPlayerSurfaceView介绍与View区别SurfaceHolder与CallBackMediaPlayer.setDisplayMediaPlayer加载网络视频3.3 获取视频缩略图使用Fresco3.4 ListView的item实现视频播放Item显示视频单Item播放Item滚出时停止播放3.5 播放器全屏显示与恢复3.6 Vitamio(维他密播放器)
4.摄像头、传感器、ZXing二维码4.1 利用Intent实现摄像头两种模式,存文件和缩略图4.2 加速度传感器实现《摇一摇》传感器获取传感器监听注册加速度传感 摇一摇4.3 ZXing实现生成二维码(容错等级、二维码正中心Logo)生成BitMatrix转Bitmap容错等级中心Logo4.4 ZXing实现二维码扫描导包
5.JPush推送、ShareSDK一键分享及第三方登录5.1 JPush极光推送的原理及用法通知推送消息推送推送原理5.2 ShareSDK一键分享及第三方登录注册集成分享第三方登录APIOAuth介绍
三、项目实战第三阶段
1.加密解密1.1 对称加密(AES 、DES、3DES)1.2 非对称加密(RSA)1.3 消息摘要(MD5、 SHA-1 )1.4 编码解码(Base64、URLEncode、URLDecode)
2.网络支付2.1 Alipay支付2.2 微信支付
3.ButterKnife(反转注入框架)、EventBus、ActiveAndroid(数据库ORM框架)及Retrofit(网络访问框架)3.1 ButterKnife(反转注入框架)3.2 EventBus的用法3.3 ActiveAndroid(数据库ORM框架)3.4 Retrofit(网络访问框架)
4.项目实战需知4.1Git、UML4.2XMPP4.3常见面试题4.4移动端与服务器端的交互流程4.5移动开发工程师与web工程师工作配合的流程4.6面试常用技巧(面试禁忌)4.7开发规范(代码规范)
第五阶段 就业指导及职业规划
⑺ 求比较好的android培训的课程
可以看看android培训学习课程大纲了解下,课程分阶段进行,不同阶段学习的详细内容可以看下。
第一阶段:Android编程基础--JavaSE阶段()
Java语言入门
1、介绍计算机的基本使用和DOS常用命令 2、Java概述和开发环境 3、关键字、标识符、常量与变量 4、数据类型和运算符
5、流程控制与数组 6、方法的定义及格式、正确的调用方法
OOP编程
1、面向对象编程(OOP)、类和对象 2、成员变量和局部变量、方法(方法重载)、匿名对象 3、构造方法、封装、this关键字
4、方法参数的传递(传值、传址)、static关键字 5、继承、super关键字、方法的重写、访问修饰符权限 6、抽象类与抽象方法、接口
7、多态(对象的多态,对象的转型) 内部类和常用的设计模式
Java核心API
1、异常、异常处理,自定义异常
2、java基础类库:Object类、Scanner类、String类、StringBuffer类、
StringBuilder类、Arrays类、基本包装类(拆箱、装箱)、正则表达式、Math类、Random类、System类、Date类、DateFormate类、Calendar类,及其常用方法
3、 *** 框架:Collcetion接口、List接口、Set接口、Iterator接口、Map接口
4、List接口:ArrayList类、LinkedList类、Vector类、Stack类 Set接口:HashSet类、TreeSet类、Map接口: HashMap类、HashTable类、LinkedHashMap类、TreeMap类
5、泛型的使用
6、File类、File类的常用方法
7、I/O操作:IO流的种类,IO流的使用(字节输入/输出流、字符输入/输出流、 字节(字符)缓存流、转换流、打印流、内存流、对象流、随机读取流) 多线程的使用(Thread类的常用方法、线程的生命周期,线程的实现、线程的安全问题)
网络与Web应用
1、Socket编程
2、HTML(结构,form表单)、Servlet简介
3、SQLite数据库的使用
4、HTTP网络访问(URL类、HttpURLConnection类、HttpClient类)
5、JSON解析(JSON的格式、JSON的常用解析:JSON、Gson、fastJson)
6、XML解析(XML简介、两种常用的解析方式: PULL解析、SAX解析) 反射机制
第二阶段:Android开发初级阶段
UI基础
1、Android发展史及四层系统架构
2、Android环境搭建及SDK介绍
3、创建第一个Android程序
4、Eclipse开发APP的目录结构
5、Android Studio开发APP的目录结构
6、adb shell简介
7、View常用属性
8、Android长度相关单位的概念、区别及转换运算(sp、dp、dip、px、dpi)
9、LinearLayout及RelativeLayout特有属性
10、FrameLayout及GridLayout特有属性
11、TextView、EditText、Button、ImageView基本用法
12、RadioButton及RadioGroup的用法
13、CheckBox的多选效果及监听
14、Spinner常用属性及适配器
15、AutoCompleteTextView、ScrollView、ProgressBar、SeekBar、RatingBar的基本用法
16、Style的作用及基本用法
17、Android常用资源(id、字符串资源、颜色资源、尺寸资源、布局资源、数组资源、样式和主题资源 、菜单资源、图像资源、动画资源、原生xml资源、raw资源、特殊Drawable资源、自定义属性资源)
应用核心组件初识
1、Activity生命周期及页面跳转传值
2、ctivity启动模式及Intent七大属性
3、AsyncTask异步任务 ListView常用属性、方法及监听器ListView与ArrayAdapter的使用
4、ListView与SimpleAdapter的使用
5、SimpleAdapter与ViewBinder结合使用
6、ListView与BaseAdapter
7、ListView优化(内存空间优化、运行时间优化、ListView中item多布局的复用)
8、ListView滚动监听实现分页加载数据
9、GridView加载图片
10、ExpandableListView的用法
数据存储及相关组件
1、菜单及对话框 (OptionsMenu、ContextMenu、PopupMenu、PopupWindow、AlertDialog、ProgressDialog、列表对话框、自定义Dialog)
2、SharedPreferences
3、内部存储的概念及用法
4、外部存储的概念、存储目录及用法
5、存储Bitmap图片到外部存储
6、SQLite数据库与CursorAdapter适配器
7、ContentProvider与ContentResolver的概念及关系
8、ContentResolver实现系统数据的操作(联系人、媒体库文件、通话记录、短信记录)
9、自定义ContentProvider
10、CursorLoader的使用场景及用法
11、AsyncTaskLoader的用法以及与CursorLoader的对比
移动开发主流界面实现
1、动画资源(帧动画、补间动画、属性动画)
2、Fragment基本用法
3、Fragment传值
4、Fragment性能优化
5、EventBus的作用以及在Fragment中的应用
6、ViewPager基本使用(ViewPager实现欢迎引导页)
7、ViewPager的适配器PagerAdapter、FragmentPagerAdapter、FragmentStatePagerAdapter
8、ViewPager加载网络图片
9、PagerAdapter优化
10、TAB书签导航的多种实现方式
11、RadioGroup + ViewPager + Fragment实现TAB导航HorizontalScrollView + ViewPager + Fragment实现TAB导航
应用核心组件进阶
1、ActionBar基本用法(ActionBar显示和隐藏、ActionBar添加动作项、ActionBar启动图标导航、分离式ActionBar、
ActionBar导航模式、ActionBar现场保护 Action View的介绍、ActionProvider)
2、ActionBar上SearchView的用法
3、ToolBar的基本用法
4、ToolBar的Standalone用法
5、Notification (普通通知、大视图通知、进度条通知、自定义通知)
6、广播接收器的概念、作用、分类及注册
7、广播接收器实现系统监听(开机监听、短信监听、电话监听、耳机插拔监听、网络状态改变监听、电量改变监听)
8、自定义发送广播(发送无序广播、有序广播、发送本地广播、注册本地广播接收器 )
9、Service的概念、分类、生命周期、注册及使用场景
10、Start Service实现音乐播放器
11、IntentService实现网络视频文件下载
12、DownloadManager实现网络视频文件下载
13、Bind Service实现音乐播放器
14、两种服务混合使用实现MediaPlayer音乐播放
15、AIDL跨进程Service的概念及用法
16、Messenger的概念及用法
17、Handler、Looper消息传递机制的原理
18、Handler、Looper源码分析
19、LruCache与Bitmap二次采样
20、WebView基本用法以及与5交互
View深入探究
1、事件分发消费机制的原理分析及应用场景
2、自定义View的常规做法
3、自绘制的自定义View(画布Canvas、画笔Paint、重写onDraw()方法、重写onMeasure()方法、自定义属性)
4、组合式自定义View
5、具有手势监听的自定义View
6、继承于ViewGroup的自定义布局
7、Android中机型适配出现的原因(系统碎片和屏幕碎片)
8、机型适配的解决方案(屏幕适配:相对布局、尺寸限定符、最小宽度限定符、屏幕方向限定符、自动拉伸位图,版本适配,语言自适应)
第三阶段:Android开发高级阶段
常用第三方框架
1、网络地图(网络地图API及配置、网络地图定位及覆盖物、网络POI检索、出行线路规划、公交路线查询)
2、第三方侧滑菜单SlidingMenu及与原生DrawerLayout、SlidingPaneLayout的对比
3、UIL(universal-image-loader)图片加载框架
4、okHttp网络访问框架
5、Picasso加载网络图片框架
6、Fresco加载图片框架
7、xUtils3、0框架
8、PullToRefresh下拉刷新框架
9、Ultra PullToRefresh下拉刷新框架
10、ButterKnife(反转注入框架)
11、ActiveAndroid(数据库ORM框架)
12、Retrofit(网络访问框架)
Android5.0新技术
1、RecyclerView及CardView
2、ExpandableRecyclerView CoordinatorLayout协调AppBarLayout、CollapsingToolbarLayout、NestedScrollView、 Toolbar、RecyclerView等控件实现特殊滚动效果
3、TextInputLayout与TextWatcher
4、FloatingActionButton
5、Snackbar
6、TabLayout介绍以及与ViewPager、Fragment配合实现TAB导航效果
7、NavigationView介绍以及结合DrawerLayout使用SwipeRefreshLayout下拉刷新控件
其他高级技术
1、媒体播放器(MediaPlayer、VideoView、SurfaceView及MediaPlayer)
2、Vitamio第三方播放器
3、摄像头
4、传感器
5、ZXing二维码
6、JPush极光推送
7、ShareSDK一键分享及
8、第三方登录
9、Alipay支付及微信支付
10、加密解密(编码解码、对称加密、非对称加密、消息摘要)/p>
第四阶段:Android项目实战阶段
APP开发
1、商业应用项目模拟(项目结构分析及设计、UML、Git、SVN、打包混淆及数字签名)
2、移动开发工程师与web工程师工作配合的流程
3、常见面试题
4、面试常用技巧(面试禁忌)
5、开发规范(代码规范)
⑻ google android官方培训课程中文版这个学完够吗
不够啊,你在多拿几个项目练练手
④ Spring Tx源码解析(二)
上一篇 我们介绍了 spring-tx 中的底层抽象,本篇我们一起来看看围绕这些抽象概念 spring-tx 是如何打造出声明式事务的吧。笼统的说, spring-tx-5.2.6.RELEASE 的实现主要分为两个部分:
这两部分彼此独立又相互成就,并且每个部分都有着大量的源码支撑,本篇我们先来分析 spring-tx 中的AOP部分吧。
EnableTransactionManagement 注解想必大家都很熟悉了,它是启用 Spring 中注释驱动的事务管理功能的关键。
EnableTransactionManagement 注解的主要作用是向容器中导入 ,至于注解中定义的几个属性在 Spring AOP源码解析 中有过详细分析,这里就不再赘述了。
由于我们并没有使用 AspectJ ,因此导入容器的自然是 这个配置类。
这个配置类的核心是向容器中导入一个类型为 的Bean。这是一个 PointcutAdvisor ,它的 Pointcut 是 , Advice 是 TransactionInterceptor 。
利用 TransactionAttributeSource 解析 @Transactional 注解的能力来选取标注了 @Transactional 注解的方法,而 TransactionInterceptor 则根据应用提出的需求(来自对 @Transactional 注解的解析)将方法增强为事务方法,因此 可以识别出那些标注了 @Transactional 注解的方法,为它们应用上事务相关功能。
TransactionInterceptor 能对方法进行增强,但是它却不知道该如何增强,比如是为方法新开一个独立事务还是沿用已有的事务?什么情况下需要回滚,什么情况下不需要?必须有一个‘人’告诉它该如何增强,这个‘人’便是 TransactionAttributeSource 。
@Transactional 注解定义了事务的基础信息,它表达了应用程序期望的事务形态。 TransactionAttributeSource 的主要作用就是解析 @Transactional 注解,提取其属性,包装成 TransactionAttribute ,这样 TransactionInterceptor 的增强便有了依据。
前面我们已经见过, spring-tx 使用 来做具体的解析工作,其父类 定义了解析 TransactionAttribute 的优先级,核心方法是 computeTransactionAttribute(...) 。
默认只解析 public 修饰的方法,这也是导致 @Transactional 注解失效的一个原因,除此之外它还实现了父类中定义的两个模板方法:
同时为了支持 EJB 中定义的 javax.ejb.TransactionAttribute 和 JTA 中定义的 javax.transaction.Transactional 注解, 选择将实际的提取工作代理给 TransactionAnnotationParser 。Spring 提供的 @Transactional 注解由 进行解析。
的源码还是很简单的,它使用 AnnotatedElementUtils 工具类定义的 find 语义来获取 @Transactional 注解信息。 RuleBasedTransactionAttribute 中 rollbackOn(...) 的实现还是挺有意思的,其它的都平平无奇。
RollbackRuleAttribute 是用来确定在发生特定类型的异常(或其子类)时是否应该回滚,而 NoRollbackRuleAttribute 继承自 RollbackRuleAttribute ,但表达的是相反的含义。 RollbackRuleAttribute 持有某个异常的名称,通过 getDepth(Throwable ex) 算法来计算指定的 Throwable 和持有的异常在继承链上的距离。
程序猿只有在拿到需求以后才能开工, TransactionInterceptor 也一样,有了 TransactionAttributeSource 之后就可以有依据的增强了。观察类图, TransactionInterceptor 实现了 MethodInterceptor 接口,那么自然要实现接口中的方法:
可以看到, TransactionInterceptor 本身是没有实现任何逻辑的,它更像一个适配器。这样分层以后, TransactionAspectSupport 理论上就可以支持任意类型的 Advice 而不只是 MethodInterceptor 。实现上 TransactionAspectSupport 确实也考虑了这一点,我们马上就会看到。
invokeWithinTransaction(...) 的流程还是非常清晰的:
第一步前文已经分析过了,我们来看第二步。
TransactionInfo 是一个非常简单的类,我们就不费什么笔墨去分析它了。接着看第三步,这一步涉及到两个不同的操作——提交或回滚。
至此, TransactionInterceptor 于我们而言已经没有任何秘密了。
本篇我们一起分析了 spring-tx 是如何通过 spring-aop 的拦截器将普通方法增强为事务方法的,下篇就该说道说道 PlatformTransactionManager 抽象下的事务管理细节啦,我们下篇再见~~
⑤ Android socket源码解析(三)socket的connect源码解析
上一篇文章着重的聊了socket服务端的bind,listen,accpet的逻辑。本文来着重聊聊connect都做了什么?
如果遇到什么问题,可以来本文 https://www.jianshu.com/p/da6089fdcfe1 下讨论
当服务端一切都准备好了。客户端就会尝试的通过 connect 系统调用,尝试的和服务端建立远程连接。
首先校验当前socket中是否有正确的目标地址。然后获取IP地址和端口调用 connectToAddress 。
在这个方法中,能看到有一个 NetHooks 跟踪socket的调用,也能看到 BlockGuard 跟踪了socket的connect调用。因此可以hook这两个地方跟踪socket,不过很少用就是了。
核心方法是 socketConnect 方法,这个方法就是调用 IoBridge.connect 方法。同理也会调用到jni中。
能看到也是调用了 connect 系统调用。
文件:/ net / ipv4 / af_inet.c
在这个方法中做的事情如下:
注意 sk_prot 所指向的方法是, tcp_prot 中 connect 所指向的方法,也就是指 tcp_v4_connect .
文件:/ net / ipv4 / tcp_ipv4.c
本质上核心任务有三件:
想要能够理解下文内容,先要明白什么是路由表。
路由表分为两大类:
每个路由器都有一个路由表(RIB)和转发表 (fib表),路由表用于决策路由,转发表决策转发分组。下文会接触到这两种表。
这两个表有什么区别呢?
网上虽然给了如下的定义:
但实际上在Linux 3.8.1中并没有明确的区分。整个路由相关的逻辑都是使用了fib转发表承担的。
先来看看几个和FIB转发表相关的核心结构体:
熟悉Linux命令朋友一定就能认出这里面大部分的字段都可以通过route命令查找到。
命令执行结果如下:
在这route命令结果的字段实际上都对应上了结构体中的字段含义:
知道路由表的的内容后。再来FIB转发表的内容。实际上从下面的源码其实可以得知,路由表的获取,实际上是先从fib转发表的路由字典树获取到后在同感加工获得路由表对象。
转发表的内容就更加简单
还记得在之前总结的ip地址的结构吗?
需要进行一次tcp的通信,意味着需要把ip报文准备好。因此需要决定源ip地址和目标IP地址。目标ip地址在之前通过netd查询到了,此时需要得到本地发送的源ip地址。
然而在实际情况下,往往是面对如下这么情况:公网一个对外的ip地址,而内网会被映射成多个不同内网的ip地址。而这个过程就是通过DDNS动态的在内存中进行更新。
因此 ip_route_connect 实际上就是选择一个缓存好的,通过DDNS设置好的内网ip地址并找到作为结果返回,将会在之后发送包的时候填入这些存在结果信息。而查询内网ip地址的过程,可以成为RTNetLink。
在Linux中有一个常用的命令 ifconfig 也可以实现类似增加一个内网ip地址的功能:
比如说为网卡eth0增加一个IPV6的地址。而这个过程实际上就是调用了devinet内核模块设定好的添加新ip地址方式,并在回调中把该ip地址刷新到内存中。
注意 devinet 和 RTNetLink 严格来说不是一个存在同一个模块。虽然都是使用 rtnl_register 注册方法到rtnl模块中:
文件:/ net / ipv4 / devinet.c
文件:/ net / ipv4 / route.c
实际上整个route模块,是跟着ipv4 内核模块一起初始化好的。能看到其中就根据不同的rtnl操作符号注册了对应不同的方法。
整个DDNS的工作流程大体如下:
当然,在tcp三次握手执行之前,需要得到当前的源地址,那么就需要通过rtnl进行查询内存中分配的ip。
文件:/ include / net / route.h
这个方法核心就是 __ip_route_output_key .当目的地址或者源地址有其一为空,则会调用 __ip_route_output_key 填充ip地址。目的地址为空说明可能是在回环链路中通信,如果源地址为空,那个说明可能往目的地址通信需要填充本地被DDNS分配好的内网地址。
在这个方法中核心还是调用了 flowi4_init_output 进行flowi4结构体的初始化。
文件:/ include / net / flow.h
能看到这个过程把数据中的源地址,目的地址,源地址端口和目的地址端口,协议类型等数据给记录下来,之后内网ip地址的查询与更新就会频繁的和这个结构体进行交互。
能看到实际上 flowi4 是一个用于承载数据的临时结构体,包含了本次路由操作需要的数据。
执行的事务如下:
想要弄清楚ip路由表的核心逻辑,必须明白路由表的几个核心的数据结构。当然网上搜索到的和本文很可能大为不同。本文是基于LInux 内核3.1.8.之后的设计几乎都沿用这一套。
而内核将路由表进行大规模的重新设计,很大一部分的原因是网络环境日益庞大且复杂。需要全新的方式进行优化管理系统中的路由表。
下面是fib_table 路由表所涉及的数据结构:
依次从最外层的结构体介绍:
能看到路由表的存储实际上通过字典树的数据结构压缩实现的。但是和常见的字典树有点区别,这种特殊的字典树称为LC-trie 快速路由查找算法。
这一篇文章对于快速路由查找算法的理解写的很不错: https://blog.csdn.net/dog250/article/details/6596046
首先理解字典树:字典树简单的来说,就是把一串数据化为二进制格式,根据左0,右1的方式构成的。
如图下所示:
这个过程用图来展示,就是沿着字典树路径不断向下读,比如依次读取abd节点就能得到00这个数字。依次读取abeh就能得到010这个数字。
说到底这种方式只是存储数据的一种方式。而使用数的好处就能很轻易的找到公共前缀,在字典树中找到公共最大子树,也就找到了公共前缀。
而LC-trie 则是在这之上做了压缩优化处理,想要理解这个算法,必须要明白在 tnode 中存在两个十分核心的数据:
这负责什么事情呢?下面就简单说说整个lc-trie的算法就能明白了。
当然先来看看方法 __ip_dev_find 是如何查找
文件:/ net / ipv4 / fib_trie.c
整个方法就是通过 tkey_extract_bits 生成tnode中对应的叶子节点所在index,从而通过 tnode_get_child_rcu 拿到tnode节点中index所对应的数组中获取叶下一级别的tnode或者叶子结点。
其中查找index最为核心方法如上,这个过程,先通过key左移动pos个位,再向右边移动(32 - bits)算法找到对应index。
在这里能对路由压缩算法有一定的理解即可,本文重点不在这里。当从路由树中找到了结果就返回 fib_result 结构体。
查询的结果最为核心的就是 fib_table 路由表,存储了真正的路由转发信息
文件:/ net / ipv4 / route.c
这个方法做的事情很简单,本质上就是想要找到这个路由的下一跳是哪里?
在这里面有一个核心的结构体名为 fib_nh_exception 。这个是指fib表中去往目的地址情况下最理想的下一跳的地址。
而这个结构体在上一个方法通过 find_exception 获得.遍历从 fib_result 获取到 fib_nh 结构体中的 nh_exceptions 链表。从这链表中找到一模一样的目的地址并返回得到的。
文件:/ net / ipv4 / tcp_output.c
⑥ Feign源码解析二
本文会基于Feign源码,看看Feign到底是怎么实现远程调用
上文中,我们的 user-service 服务需要调用远程的 order-service 服务完成一定的业务逻辑,而基本实现是order-service提供一个spi的jar包给user-service依赖,并且在user-service的启动类上添加了一个注解
这个注解就是@EnableFeignClients,接下来我们就从这个注解入手,一步一步解开Feign的神秘面纱
该注解类上的注释大概的意思就是:
扫描那些被声明为 Feign Clients (只要有 org.springframework.cloud.openfeign.FeignClient 注解修饰的接口都是Feign Clients接口)的接口
下面我们继续追踪源码,看看到底什么地方用到了这个注解
利用IDEA的查找调用链快捷键,可以发现在.class类型的文件中只有一个文件用到了这个注解
OK,下面主要就是看这个类做了什么
通过UML图我们发现该类分别实现了 ImportBeanDefinitionRegistrar , ResourceLoaderAware 以及 EnvironmentAware 接口
这三个接口均是spring-framework框架的spring-context模块下的接口,都是和spring上下文相关,具体作用下文会分析
总结下来就是利用这两个重要属性,一个获取应用配置属性,一个可以加载classpath下的文件,那么FeignClientsRegistrar持有这两个东西之后要做什么呢?
上面将bean配置类包装成 FeignClientSpecification ,注入到容器。该对象非常重要,包含FeignClient需要的 重试策略 , 超时策略 , 日志 等配置,如果某个FeignClient服务没有设置独立的配置类,则读取默认的配置,可以将这里注册的bean理解为整个应用中所有feign的默认配置
由于 FeignClientsRegistrar 实现了 ImportBeanDefinitionRegistrar 接口,这里简单提下这个接口的作用
我们知道在spring框架中,我们如果想注册一个bean的话主要由两种方式:自动注册/手动注册
知道了 ImportBeanDefinitionRegistrar 接口的作用,下面就来看下 FeignClientsRegistrar 类是何时被加载实例化的
通过IDEA工具搜索引用链,发现该类是在注解@EnableFeignClients上被import进来的,文章开始的图片中有
这里提下@Import注解的作用
该注解仅有一个属性value,使用该注解表明导入一个或者多个@Configuration类,其作用和.xml文件中的<import>等效,其允许导入@Configuration类,ImportSelector接口/ImportBeanDefinitionRegistrar接口的实现,也同样可以导入一个普通的组件类
注意,如果是XML或非@Configuration的bean定义资源需要被导入的话,需要使用@ImportResource注解代替
这里我们导入的FeignClientsRegistrar类正是一个ImportBeanDefinitionRegistrar接口的实现
FeignClientsRegistrar重写了该接口的 registerBeanDefinitions 方法,该方法有两个参数注解元数据 metadata 和bean定义注册表 registry
该方法会由spring负责调用,继而注册所有标注为@FeignClient注解的bean定义
下面看registerBeanDefinitions方法中的第二个方法,在该方法中完成了所有@FeignClient注解接口的扫描工作,以及注册到spring中,注意这里注册bean的类型为 FeignClientFactoryBean ,下面细说
总结一下该方法,就是扫描@EnableFeignClients注解上指定的basePackage或clients值,获取所有@FeignClient注解标识的接口,然后将这些接口一一调用以下 两个重要方法 完成 注册configuration配置bean 和注册 FeignClient bean
断点位置相当重要
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
这里是利用了spring的代理工厂来生成代理类,即这里将所有的 feignClient的描述信息 BeanDefinition 设定为 FeignClientFactoryBean 类型,该类继承自FactoryBean,因此这是一个代理类,FactoryBean是一个工厂bean,用作创建代理bean,所以得出结论,feign将所有的 feignClient bean定义的类型包装成 FeignClientFactoryBean
最终其实就是存入了BeanFactory的beanDefinitionMap中
那么代理类什么时候会触发生成呢? 在spring 刷新容器时 ,会根据beanDefinition去实例化bean,如果beanDefinition的beanClass类型为代理bean,则会调用其 T getObject() throws Exception; 方法生成代理bean,而我们实际利用注入进来的FeignClient接口就是这些一个个代理类
这里有一个需要注意的点,也是开发中会遇到的一个 启动报错点
如果我们同时定义了两个不同名称的接口 (同一个包下/或依赖方指定全部扫描我们提供的 @FeignClient ),且这两个 @FeignClient 接口注解的 value/name/serviceId 值一样的话,依赖方拿到我们的提供的spi依赖,启动类上 @EnableFeignClients 注解扫描能同时扫描到这两个接口,就会 启动报错
原因就是Feign会为每个@FeignClient注解标识的接口都注册一个以serviceId/name/value为key,FeignClientSpecification类型的bean定义为value去spring注册bean定义,又默认不允许覆盖bean定义,所以报错
官方提示给出的解决方法要么改个@FeignClient注解的serviceId,name,value属性值,要么就开启spring允许bean定义覆写
至此我们知道利用在springboot的启动类上添加的@EnableFeignClients注解,该注解中import进来了一个手动注册bean的 FeignClientsRegistrar注册器 ,该注册器会由spring加载其 registerBeanDefinitions方法 ,由此来扫描所有@EnableFeignClients注解定义的basePackages包路径下的所有标注为@FeignClient注解的接口,并将其注册到spring的bean定义Map中,并实例化bean
下一篇博文中,我会分析为什么我们在调用(@Resource)这些由@FeignClient注解的bean的方法时会发起 远程调用
⑦ OkHttp源码解析 (三)——代理和路由
初看OkHttp源码,由于对Address、Route、Proxy、ProxySelector、RouteSelector等理解不够,读源码非常吃力,看了几遍依然对于寻找复用连接、创建连接、连接服务器、连接代理服务器、创建隧道连接等逻辑似懂非懂,本篇决定梳理一遍相关的概念及基本原理。
● HTTP/1.1(HTTPS)
● HTTP/2
● SPDY
一个http请求的流程(直连):
1、输入url及参数;
2、如果是url是域名则解析ip地址,可能对应多个ip,如果没有指定端口,则用默认端口,http请求用80;
3、创建socket,根据ip和端口连接服务器(socket内部会完成3次TCP握手);
4、socket成功连接后,发送http报文数据。
一个https请求的流程(直连):
1、输入url及参数;
2、如果是url是域名则解析ip地址,可能对应多个ip,如果没有指定端口,则用默认端口,https请求用443;
3、创建socket,根据ip和端口连接服务器(socket内部会完成3次TCP握手);
4、socket成功连接后进行TLS握手,可通过java标准款提供的SSLSocket完成;
5、握手成功后,发送https报文数据。
1、分类
● HTTP代理:普通代理、隧道代理
● SOCKS代理:SOCKS4、SOCKS5
2、HTTP代理分类及说明
普通代理
HTTP/1.1 协议的第一部分。其代理过程为:
● client 请求 proxy
● proxy 解析请求获取 origin server 地址
● proxy 向 origin server 转发请求
● proxy 接收 origin server 的响应
● proxy 向 client 转发响应
其中proxy获取目的服务器地址的标准方法是解析 request line 里的 request-URL。因为proxy需要解析报文,因此普通代理无法适用于https,因为报文都是加密的。
隧道代理
通过 Web 代理服务器用隧道方式传输基于 TCP 的协议。
请求包括两个阶段,一是连接(隧道)建立阶段,二是数据通信(请求响应)阶段,数据通信是基于 TCP packet ,代理服务器不会对请求及响应的报文作任何的处理,都是原封不动的转发,因此可以代理 HTTPS请求和响应。
代理过程为:
● client 向 proxy 发送 CONNET 请求(包含了 origin server 的地址)
● proxy 与 origin server 建立 TCP 连接
● proxy 向 client 发送响应
● client 向 proxy 发送请求,proxy 原封不动向 origin server 转发请求,请求数据不做任何封装,为原生 TCP packet.
3、SOCKS代理分类及说明
● SOCKS4:只支持TCP协议(即传输控制协议)
● SOCKS5: 既支持TCP协议又支持UDP协议(即用户数据包协议),还支持各种身份验证机制、服务器端域名解析等。
SOCK4能做到的SOCKS5都可得到,但反过来却不行,比如我们常用的聊天工具QQ在使用代理时就要求用SOCKS5代理,因为它需要使用UDP协议来传输数据。
有了上面的基础知识,下面分析结合源码分析OkHttp路由相关的逻辑。OkHttp用Address来描述与目标服务器建立连接的配置信息,但请求输入的可能是域名,一个域名可能对于多个ip,真正建立连接是其中一个ip,另外,如果设置了代理,客户端是与代理服务器建立直接连接,而不是目标服务器,代理又可能是域名,可能对应多个ip。因此,这里用Route来描述最终选择的路由,即客户端与哪个ip建立连接,是代理还是直连。下面对比下Address及Route的属性,及路由选择器RouteSelector。
描述与目标服务器建立连接所需要的配置信息,包括目标主机名、端口、dns,SocketFactory,如果是https请求,包括TLS相关的SSLSocketFactory 、HostnameVerifier 、CertificatePinner,代理服务器信息Proxy 、ProxySelector 。
Route提供了真正连接服务器所需要的动态信息,明确需要连接的服务器IP地址及代理服务器,一个Address可能会有很多个路由Route供选择(一个DNS对应对个IP)。
Address和Route都是数据对象,没有提供操作方法,OkHttp另外定义了RouteSelector来完成选择的路由的操作。
1、读取代理配置信息:resetNextProxy()
读取代理配置:
● 如果有指定代理(不读取系统配置,在OkHttpClient实例中指定),则只用1个该指定代理;
● 如果没有指定,则读取系统配置的,可能有多个。
2、获取需要尝试的socket地址(目标服务器或者代理服务器):resetNextInetSocketAddress()
结合Address的host和代理,解析要尝试的套接字地址(ip+端口)列表:
● 直连或者SOCK代理, 则用目标服务器的主机名和端口,如果是HTTP代理,则用代理服务器的主机名和端口;
● 如果是SOCK代理,根据目标服务器主机名和端口号创建未解析的套接字地址,列表只有1个地址;
● 如果是直连或HTTP代理,先DNS解析,得到InetAddress列表(没有端口),再创建InetSocketAddress列表(带上端口),InetSocketAddress与InetAddress的区别是前者带端口信息。
3、获取路由列表:next()
选择路由的流程解析:
● 遍历每个代理对象,可能多个,直连的代理对象为Proxy.DIRECT(实际是没有中间代理的);
● 对每个代理获取套接字地址列表;
● 遍历地址列表,创建Route,判断Route如果在路由黑名单中,则添加到失败路由列表,不在黑名单中则添加到待返回的Route列表;
● 如果最后待返回的Route列表为空,即可能所有路由都在黑名单中,实在没有新路由了,则将失败的路由集合返回;
● 传入Route列表创建Selection对象,对象比较简单,就是一个目标路由集合,及读取方法。
为了避免不必要的尝试,OkHttp会把连接失败的路由加入到黑名单中,由RouteDatabase管理,该类比较简单,就是一个失败路由集合。
1、创建Address
Address的创建在RetryAndFollowUpInteceptor里,每次请求会声明一个新的Address及StreamAllocation对象,而StreamAllocation使用Address创建RouteSelector对象,在连接时RouteSelector确定请求的路由。
每个Requst都会构造一个Address对象,构造好了Address对象只是有了与服务器连接的配置信息,但没有确定最终服务器的ip,也没有确定连接的路由。
2、创建RouteSelector
在StreamAllocation声明的同时会声明路由选择器RouteSelector,为一次请求寻找路由。
3、选择可用的路由Route
下面在测试过程跟踪实例对象来理解,分别测试直连和HTTP代理HTTP2请求路由的选择过程:
● 直连请求流程
● HTTP代理HTTPS流程
请求url: https://www.jianshu.com/p/63ba15d8877a
1、构造address对象
2、读取代理配置:resetNextProxy
3、解析目标服务器套接字地址:resetNextInetSocketAddress
4、选择Route创建RealConnection
5、确定协议
测试方法:
● 在PC端打开Charles,设置端口,如何设置代理,网上有教程,比较简单;
● 手机打开WIFI,选择连接的WIFI修改网络,在高级选项中设置中指定了代理服务器,ip为PC的ip,端口是Charles刚设置的端口;
● OkHttpClient不指定代理,发起请求。
1、构造address对象
2、读取代理配置:resetNextProxy
3、解析目标服务器套接字地址:resetNextInetSocketAddress
4、选择Route创建RealConnection
5、创建隧道
由于是代理https请求,需要用到隧道代理。
从图可以看出,建立隧道其实是发送CONNECT请求,header包括字段Proxy-Connection,目标主机名,请求内容类似:
6、确定协议,SSL握手
1、代理可分为HTTP代理和SOCK代理;
2、HTTP代理又分为普通代理和隧道代理;普通代理适合明文传输,即http请求;隧道代理仅转发TCP包,适合加密传输,即https/http2;
3、SOCK代理又分为SOCK4和SOCK5,区别是后者支持UDP传输,适合代理聊天工具如QQ;
4、没有设置代理(OkHttpClient没有指定同时系统也没有设置),客户端直接与目标服务器建立TCP连接;
5、设置了代理,代理http请求时,客户端与代理服务器建立TCP连接,如果代理服务器是域名,则解释代理服务器域名,而目标服务器的域名由代理服务器解析;
6、设置了代理,代理https/http2请求时,客户端与代理服务器建立TCP连接,发送CONNECT请求与代理服务器建立隧道,并进行SSL握手,代理服务器不解析数据,仅转发TCP数据包。
如何正确使用 HTTP proxy
OkHttp3中的代理与路由
HTTP 代理原理及实现(一)