简介:面向安卓开发学习者的仿滴滴出行项目源码,可用于理解移动出行类App从界面搭建到后台通信的整体实现。资源共289个文件,压缩包5.04MB,以Java源码、class编译文件、XML布局与配置、PNG界面切图为主,同时附带可安装的APK文件和源码说明文档,方便对照运行效果与代码逐一学习。该项目覆盖用户界面设计、定位与地图服务接入、网络请求、后台数据处理等关键环节;集成百度地图时需自行申请API密钥,这也为新手提供了一次完整的第三方服务接入实践。目前已有147人学习下载。结合说明文档与界面截图,开发者可以快速理清项目结构,掌握如何将地图、定位、订单流程等模块组织到一个安卓工程中,适合正在转向移动应用开发的初学者作为练手项目。 说实话,这类“仿滴滴打车”的安卓源码在当年是个挺火的练手项目。现在我还能看到有人专门在找能直接用Eclipse导入调试的版本,说明很多人拿它当毕业设计、课程作业,或者简历里的网约车项目经历。这个方向选得不算新,但胜在实用:一套完整源码里,地图定位、订单流转、支付模拟、消息推送全都有,比我见过的绝大多数酒店、商城Demo含金量高不少。
不过这里有个很现实的问题:这类源码大多出自2016到2018年之间,那会儿Android开发主流工具还是Eclipse加上ADT插件。到了今天,很多新手一上来装的却是Android Studio,导入这种老工程经常卡在Gradle版本、SDK版本甚至JDK兼容性上。而你手里如果拿的是一份“最好用Eclipse导入调试”的源码,那反而意味着它保留了最原始的工程结构,用Eclipse打开大概率能省掉一堆折腾。这篇文章我就顺着“Eclipse导入调试”这条线,把从环境搭建到跑通真机的完整过程拆开讲清楚,顺带把我踩过的坑也一并交代了。
1. 项目到底长什么样,值不值得花时间去搞
1.1 这类源码包含哪些核心模块
先说清楚,“仿滴滴”不是一个单文件Demo,它是一个完整的三层结构:客户端、服务端、管理后台。通常你下载到的源码包里,至少包含这些内容:
- 一个Android客户端工程,主包名一般是com.didi.chauffeur、com.example.driver这类,集成了百度或高德地图SDK,用于定位、路径规划、司机与乘客位置展示。
- 一个服务端工程,常见选择是Bmob后端云、LeanCloud或者直接内置一个简单的Servlet/JSP后台,负责订单分发、用户注册登录、计费等功能。
- 一套后台管理页面,用来查看司机数据、订单记录,一般用Java Web写,跑在Tomcat上。
- 数据库脚本,里面建好了用户表、订单表、司机表等表结构,导入MySQL就能用。
买到的源码里也有用的纯客户端模式,即用Bmob这类BaaS云存储,把订单和用户信息直接存在云端,不需要自己部署Tomcat。这种工程结构更简单,对Eclipse来说也更好导入。如果你只是做毕设演示,我建议优先选这种,因为能少碰一堆配置问题。
1.2 为什么选Eclipse而不是Android Studio
这个问题几乎每次都会被问到。我的看法是:看源码的工程结构,别被工具绑架。
老一批安卓源码里,Eclipse工程的标志是存在.project和.classpath两个文件,同时依赖目录是libs或lib,没有Gradle的build.gradle模块体系。如果你把这种工程硬塞进新版Android Studio,Gradle转换工具通常会报一堆“Configuration file not found”之类的错,还得手动改包依赖,非常痛苦。
反过来用Eclipse就顺理成章。Eclipse导入时会读取.project文件,自动识别工程根目录和能力,配合ADT插件就能直接编译。当然,你也不用担心学了Eclipse白学,因为你后面要做项目时照样可以回到Android Studio,但调试老源码这件事,Eclipse就是比Android Studio省心。拿我的经验说,用Android Studio改这种老工程可能需要小半天,用Eclipse只要半小时。这也是我为什么一直在旧机器上留着一个Eclipse IDE的原因。
2. 环境准备:这一步没做对,后面全是坑
2.1 JDK、Eclipse、ADT、SDK版本怎么搭配
很多人一上来就问“用什么版本的Eclipse”,这其实是入门级问题。更关键的在于JDK、Eclipse、ADT插件、Android SDK四者之间的版本匹配关系。
根据这几年的实际经验,我推荐一套最稳的组合:
注意,这里说的版本组合是我反复测过比较省事的,严格按这套走可以避开98%的兼容问题。
- JDK 1.8(32位或64位都行,但Eclipse位数要和JDK位数一致,强烈建议统一64位)。
- Eclipse 4.5(Mars)或者4.6(Neon),这两个版本对ADT插件兼容性最好。
- ADT 23.0.6,这是Eclipse上最后的ADT版本,稳定不折腾。
- Android SDK Platform 23(Android 6.0)以及配套的Build-Tools 23.0.1。
这套组合的理论基础在于:ADT 23.0.6正是为当时的Eclipse 4.5/4.6开发的,Android 6.0 SDK也和这套工具链同步发布。再往上走,比如用ADT 24、25,Eclipse市场里根本找不到官方更新源,安装插件时就容易失败。
Eclipse下载别去官网闭眼下最新版,直接找带有“Mars”或“Neon”标识的Eclipse IDE for Java Developers压缩包,解压即用。JDK安装好后,在Eclipse的eclipse.ini里确认-vm路径,或者直接在系统的环境变量JAVA_HOME里配置好路径,保证Eclipse能读到Java环境。
2.2 安装ADT插件的两种方式
ADT插件安装有两种常用方式:在线安装和离线安装。
在线安装走Eclipse的Help菜单,找到Install New Software,添加地址:
https://dl-ssl.google.com/android/eclipse/等待加载出ADT组件,勾选Developer Tools,一路Next就行。然后设置SDK路径:Window > Preferences > Android > SDK Location,选择你的Android SDK目录。如果在导入工程时提示“SDK Platform未安装”,直接到SDK Manager里勾选对应版本进行安装,安装完后重启Eclipse。
离线安装则是先把ADT插件的zip包下载好,然后在Install New Software界面点击Add > Archive,选择本地zip。这种方式比在线稳,尤其网络不稳定的时候,强烈推荐。
2.3 Eclipse导入工程的标准步骤
环境准备妥当后,就可以开始导入了:
- 打开Eclipse,菜单栏选择 File > Import,在弹窗里展开General文件夹,选Existing Projects into Workspace,点击Next。
- 点击Browse,选中你下载回来的源码根目录。注意这里有个小玄机:很多源码压缩包解压后会有两层目录,比如“driver-master”里面还套着“driver-master”,目录套目录。这时要选中内层那个真正包含
.project文件的文件夹。 - 导入选项里,建议勾选Copy projects into workspace。这样源码会被复制到Eclipse的workspace目录下,避免因为原地引用导致误删原文件。如果你的源码里有svn或git的隐藏目录,记得取消勾选下面那些版本控制相关的选项。
- 点击Finish后,Eclipse会开始构建工程,左下角进度条走完就算完成。
提示:如果导入后项目名旁边显示红叉,先别慌。右键项目 > Properties > Android,确认Project Build Target选的是API 23,并且下面的Library对话框里没有任何红叉。通常红叉大部分是SDK版本没配对或库工程缺失导致。
3. 配置依赖项:第三方SDK是个大活
3.1 Library库工程的导入与关联
“仿滴滴”这类源码往往不是单个工程,而是由一个主工程和若干Library工程组成。比如项目里会出现pulltorefresh、slidingmenu、android-async-http、baidumapSDK等带android:isLibrary属性的工程。
导入主工程后,你需要在Package Explorer里检查是否同时导入了这些Library工程。如果漏了,右键主工程 > Properties > Android > Library区域,点击Add,把依赖的库工程添加进去。
这里有一个常见的操作误区:以为把Library的源码文件夹丢到主工程里就算完事。实际上Eclipse的Android Library关联原理是编译库工程生成classes.jar或.aar,再链接到主工程,它要求Library工程本身可以独立编译。所以正确做法是先在Eclipse里单独导入Library工程,再在主工程里Add引用。
如果工程报的是Unable to resolve target 'android-19'这类错,多半是SDK Manager里没装对应的Android版本。处理办法很简单:打开SDK Manager,把报错信息里对应的Platform版本勾上,下载安装后重启Eclipse,然后在Properties > Android里重新选择Target。
3.2 地图Key、推送、支付这些第三方配置
源码跑通后,最常遇到的表现是定位不刷新、地图空白、推送收不到消息。原因基本都是第三方密钥还是原来源码作者的,和你自己的调试签名不匹配。
以百度地图为例,申请新的Key需要你提供当前应用的SHA1签名和一个包名。Eclipse下默认的调试签名是debug.keystore,通常是这个路径:
C:\Users\你的用户名\.android\debug.keystore获取SHA1签名,在命令行窗口执行:
keytool -list -v -keystore debug.keystore -storepass android -alias androiddebugkey记下输出的SHA1值,去百度地图开放平台创建一个应用,把包名和SHA1填进去,拿到新的AK。然后在AndroidManifest.xml里找到meta-data标签,把百度地图的Key值替换成新AK。
高德地图的Key配置逻辑类似,但注意它在同一个meta-data里还有可能有高德定位和高德地图两个Key,需要分别替换。推送方面,极光推送、友盟推送通常要求你在官网注册应用,把AppKey和AppSecret换到代码里,有的还要在AndroidManifest里填写JPUSH_PKGNAME这类占位符。支付这块,如果源码里接了支付宝或微信支付,那就要你的商户号和签名了,如果只是为了演示,建议直接把支付按钮的跳转逻辑屏蔽或改为模拟支付成功。
3.3 编译报错与jar冲突的处理
Eclipse下编译这个项目,最烦的报错莫过于Conversion to Dalvik format failed with error 1。这个问题的根源通常是两个:
一是jar包冲突,比如主工程libs里同时存在android-support-v4.jar,而某个Library工程里也带了一份相同jar,导致重复打包。解决办法是把主工程和Library工程里的重复jar删掉一份,只保留较新的。
二是jar版本过老或过新,比如源码里自带的android-async-http-1.4.4.jar和org.apache.http.legacy发生冲突,这种情况建议直接在工程Properties > Java Build Path里禁用或删除旧jar,再检查代码里有没有使用到被删jar里的类。
如果报错是Unable to execute dex: Multiple dex files define...,其实也是jar冲突,做一遍去重就行。还有一个常见问题:libs里的.so文件没打进APK,运行时报UnsatisfiedLinkError,去工程Properties > Java Build Path > Order and Export,把libs文件夹的导出选项勾上。
4. 真机调试:把项目跑起来,才算真正开始
4.1 模拟器还是真机,怎么选
因为地图和定位功能强依赖真实传感器,我建议第一次跑就直接用真机。模拟器跑老项目经常出现地图白屏,那是渲染问题和传感器数据缺失导致的,不是源码问题。
真机调试前需要做三件事:
- 手机打开开发者选项和USB调试。不同手机上这个入口不同,常见的操作是连续点击“版本号”7次,就能在设置里看到开发者选项。
- 插上USB线,在Eclipse里选择Run As > Android Application,如果提示没有找到设备,先确认
adb devices命令能看到设备序列号。 - 部分国产手机插上后只充电不提示调试,需要在通知栏把USB连接模式改成“传输文件”,并勾选“始终允许使用这台计算机调试”。
如果adb一直检测不到设备,多半是USB驱动问题。用手机厂商提供的驱动,或者用驱动精灵这类工具安装通用驱动。实在不行,换一根数据线,很多数据线只支持充电不支持数据传输,这是最容易被忽略的坑。
4.2 用Logcat准确定位崩溃点
项目启动后如果闪退,不要盲猜。Eclipse的Logcat窗口就是最好的破案工具。
打开Window > Show View > Logcat,用真机复现一次崩溃,Logcat里会打出红色堆栈信息。通常报错信息会写java.lang.RuntimeException: Unable to start activity...或NullPointerException,后面跟着源码中崩溃的行号,点带行号的MainActivity.java:123,Eclipse会直接跳到代码对应位置。
日志里比较常见的崩溃原因有这几个:
- 地图初始化时没有调用
onCreate前执行SDKInitializer.initialize(context),会报so文件加载失败或key校验失败。 - 数据库没初始化但提前查询,就会报
SQLiteException。 - 订单列表刷新时拿到的是空对象,没做null判断,导致NPE。
经验之谈是,先把崩溃点前的几行日志一起看,很多问题不是出在崩溃那一行,而是出在之前某一步错误的数据传递。比如加载司机列表时崩了,崩溃在GridView的getView里,但根源可能是网络请求回调里的JSON解析把某一字段解析成了null,而不是UI层的问题。
4.3 为什么推荐使用Eclipse的DDMS视角
Eclipse的DDMS(Dalvik Debug Monitor Service)在调试过程中非常好用,现在很多人不知道它。它除了看日志,还能看线程状态、内存分配和模拟电话短信。
“仿滴滴”工程里有一个高频难点:地图选点的回调走不通。这时打开DDMS里的Emulator Control面板,可以直接发送模拟GPS坐标,验证定位回调代码是否符合预期。这在真机上反而不方便,总不能真开着车到处跑。调试时先在模拟器把定位逻辑跑通,再换真机验证精度,效率能高出一大截。
5. 常见问题速查表:你可能会踩的坑,汇总在这里
| 现象 | 根本原因 | 处理方法 |
|---|---|---|
| 导入后项目名有红叉,但没报错信息 | 项目编译Target版本与本地SDK不一致 | 右键Properties,把Project Build Target切成本地已安装的API版本 |
| 地图灰色网格或显示“鉴权失败” | 百度/高德SDK的Key错误,或包名与Key不匹配 | 重新申请Key,替换AndroidManifest里的meta-data值 |
| 点击登录按钮无任何反应 | 登录调用的Bmob/自定义后端不可用 | 检查网络权限、连接是否可达;用Logcat看请求返回结果 |
| Run As里没有Android Application选项 | 工程没有被识别为Android工程 | 右键项目 > Properties > Project Facets,勾选Android |
| 编译报错:Unable to resolve target 'android-19' | 缺少对应Android SDK Platform | 打开SDK Manager安装对应API版本 |
| 真机装上后打开就闪退 | 通常是so文件未打包,或64位兼容问题 | 把libs目录下的armeabi、armeabi-v7a目录完整保留,并在构建路径里勾选导出 |
| Logcat中文乱码 | 源码使用GBK编码,Eclipse默认UTF-8 | 右键项目 > Properties > Resource > Text file encoding,改为GBK |
| 地图定位一直转圈 | 没有网络权限,或经纬度初始化为0 | 检查AndroidManifest里的ACCESS_FINE_LOCATION权限,在代码里传入正确坐标 |
| 列表图片加载失败 | 图片加载框架用了Picasso/ImageLoader,但网络图片地址失效 | 要么换图片URL,要么断开ImageView加载逻辑,改用本地图片 |
| Tomcat控制台启动后马上退出 | 端口被占用或JDK版本不匹配 | 更换server.xml里的端口;确认JAVA_HOME指向JDK8 |
这张表虽然只有十条,但覆盖了我在不同源码上见到的绝大多数问题。遇到别的问题,也别慌,照着Logcat追,总能定位到。
6. 从“跑起来”到“改起来”,怎么让源码变成自己的
6.1 先把流程走通,再去改功能
我见过很多人拿到源码后第一件事就是改界面、换App名字,结果经常改到一半工程就废了。我的建议是:第一遍跑通,第二遍看懂主流程,第三遍再动手改。
跑通之后,先把整个App从启动页到下单页面完整操作一遍,记下每一步调用了哪个Activity,用到了哪张表。比如注册登录后跳到首页,首页的司机列表是从哪个接口拉取的,点击“呼叫”按钮后订单数据写入到了哪个表。把这条线走通,你就对这坨源码有了整体认知。
接着做减法,删掉暂时不需要的功能模块。比如你不需要支付,就直接把支付流程跳过的入口接上;不需要聊天,就把聊天的类从MainActivity的按钮逻辑里剔除。老工程页面多、依赖乱,越精简越不容易出问题。
6.2 把后端换成自己的,是二次开发的最高价值点
那些基于Bmob等BaaS平台的源码,最大的改造空间在于把云端数据层换掉。
Bmob的SDK封装了快速建表、增删改查、批量查询等功能,通过回调返回数据。你把Bmob换成自己的服务器,流程其实是一样的:写一个HTTP接口,返回JSON;客户端把原先调用Bmob的地方替换成OkHttp或Volley请求。
比如原来获取司机位置信息,代码里很可能长这样:
BmobQuery<Driver> query = new BmobQuery<>(); query.findObjects(new FindListener<Driver>() { @Override public void done(List<Driver> list, BmobException e) { // list就是附近的司机列表 } });改成自己的HTTP接口后,这段代码变成:
OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://你的服务器地址/api/driver/list") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { String body = response.body().string(); // 解析body里的JSON,然后回调主线程更新UI } });这个改造过程能让你接触到网络层、JSON解析、线程切换这些Android核心知识点,比单纯跑通一个Demo有价值得多。
6.3 几个保留功能扩展的小方向
如果你想让这个项目在答辩时更有亮点,可以往这几个方向扩展:
- 实时车队位置刷新:原来可能是每隔几秒轮询一次,可以改成WebSocket或者轮询策略优化,在界面上用平滑动画显示车辆移动,观感提升明显。
- 订单状态机优化:从呼叫、接单、到达、开始、结束五个状态,细化到添加“司机迟到”“乘客取消扣费”等规则,逻辑上更像真实产品。
- 乘客端与司机端联动:很多源码把乘客端和司机端分成两个独立工程,你可以利用同一个后台,把两端都编译出来,演示“乘客下单、司机接单”的完整闭环,答辩时很有说服力。
不过动手前还是要评估一下自己的时间,与其把五个模块都改一遍,不如把一个模块改到精致。
结尾的一点心里话
折腾老源码这件事,本质上并不是为了追求新旧工具,而是为了把一件别人做过的作品吃透。很多知识点,比如ADT插件的工作原理、Eclipse的构建链路、NDK的so包打包逻辑,放在今天的Android Studio里你大概率不会特意去学,但在调试老工程时,你不得不去碰它们,这反而成了一种查缺补漏的捷径。
我个人的体会是:最好留一台固定的机器配好Eclipse调试环境,不要每次用的时候重新装一遍。环境这东西非常敏感,装一次成功后再也不乱动,能省下大量时间。你再遇到类似的仿美团、仿猫眼、仿携程老源码,导入流程几乎可以复用。
最后分享一个小技巧,源码拿到手别急,先看README。很多作者会把自己开发时的JDK版本、SDK版本、注意事项写在里面。别一上来就双击打开,那不符合咱们程序员的工作习惯。
本文还有配套的精品资源,点击获取