移动APP开发技术.docx_第1页
移动APP开发技术.docx_第2页
移动APP开发技术.docx_第3页
移动APP开发技术.docx_第4页
移动APP开发技术.docx_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

移动APP开发技术1.1基本的架构设计模式提高生产力,是对程序员们对程序进行孜孜不倦架构设计的原因。通过不同的架构设计使程序模块化解耦以及程序内部的高聚合,使得开发人员可以在开发工程中只需关注一点或者某块的功能设计而不必关注全貌,甚至以点窥面,从某个模块的理解即可覆盖全局。同时测试设计也会因为一个更良好的架构设计而改观。在本章,笔者主要针对移动端常用的MVC、MVP、MVVM三种设计模式进行比较探讨,并结合实例,来说明三者之间的差异。1.1.1 MVC/MVP/MVVMMVC/MVP/MVVM是一种架构模式,它描述的是数据流向,这三者之间的差别可以由如下图,可以看到三者之前的相同点是,View均为UI层,是用户直接的交互操作入口,并负责UI交互和界面展现相关逻辑。Model层为数据对象,提供对应用程序数据的操作接口,并在数据发生变化时,发出变更通知。图1 架构模式那么,它们的不同点是什么呢,在MVC中,controller被动接收View的操作事件,根据事件的不同进行不同的操作,model并不直接与controller交互,而是View通过观察者的方式,来直接与Model交互,在Android中,往往很难区分View和Controller,所以经常会看到好几千行的Activity,非常难维护;MVP可以理解为MVC的升级版,在笔者眼中,它是第一次使客户端分层得以充分实现的一种架构模式,它的特点是,Prensenter将View和Model完全隔离,View传递事件给Presenter,而presenter直接负责View的刷新;MVVM早期应用是windows的MFC上,而近期在2015年google IO大会上,发布的新Android studio也支持了这一特性,它的基础是DATA BINDING,这一特性从理想态上来说,完美的解决了UI前端与业务逻辑层的解耦问题,哪怕是MVP也不能具有这么好的特性。1.1.2MVP设计模式实现 实现MVP并不复杂,但是重点是把握好,不要过度设计,MVP很容易导致本来很简单的代码需要大量的开发工作,写在前面,可以理解,架构的设计模式与产品体量有关,说一个极端的场景,当你的团队只有1个人,APP整体也只是一个前台展示 + 简易逻辑处理 + 数据存储 + 网络请求时,其实此时并不需要特别复杂的架构设计,而是,要用最简易便捷的方式将APP设计起来,这也遵循了产品设计之初快速产出,快速试错的目的。而当团队逐步增大、产品规模逐步提升,譬如,代码量超10W时,这时候为了团队协作、模块管理、便于测试等诉求,就不得不进行一定的架构设计或重构了。如何讲解一个MVP的例子,还是找一个比较简单的例子切入,可能并不能说明一切端设计的场景,但是可以作为读者了解MVP的切入点,假设有一个用户数据录入的APP,具备简单功能,即用户数据录入&简单用户数据查询功能,它的界面看起来是如下这样的:图2 简易APP用户界面最后的工程结构是这样的,如下图图3 MVP基本结构第一步,实现数据载体Beanpublic class UserBean private String mFirstName; private String mLastName; public UserBean(String firstName, String lastName) this. mFirstName = firstName; this. mLastName = lastName; public String getFirstName() return mFirstName; public String getLastName() return mLastName; 第二步,实现Model层,model其实是对数据的CURD操作的封装,如果有网络请求或其他需要异步处理的需求,这一层通过listener与上层的presenter进行通讯public interface IUserModel Boolean insert(int id, String firstName, String lastName); Boolean update(int id, String firstName, String lastName); void delete(int id); UserBean query(int id); void reset(); List queryAll();第三步,实现presenterpublic class UserPresenter private IUserView mUserView; private IUserModel mUserModel; public UserPresenter(IUserView view) mUserView = view; mUserModel = new UserModel(); public void saveUser( int userId, String firstName, String lastName) mUserModel.insert(userId, firstName, lastName); public void loadUser( int userId) UserBean user = mUserModel.query(userId); mUserView.setFirstName(user.getFirstName(); mUserView.setLastName(user.getLastName(); 第四步,实现View层public interface IUserView String getFristName(); String getLastName(); void setFirstName(String firstName); void setLastName(String lastName);其中,没有标准Activity和model的实现,相信读者可以参考IUserView和IUserModel的接口就可以实现对应的view层和model层实体了。这样就算是基于MVP设计模式,设计了一个简单的APP。但是这个APP的实现是不全的,但是对于说明MVP设计来说已经足够了。1.1.3 MVVM设计模式实现MVVM模式,并不是移动时代来临以后特有的,它起初的应用是微软的WPF(windows vista用户界面框架),所以它并不新鲜,但是,引入到了移动端,它的重要性举足轻重。简单一句话是,相对于MVP和MVC,它彻底解耦了View层和下面的业务逻辑及数据层。MVVM的核心是”data binding”技术(数据绑定),在笔者看来,MVVM与其说是一种设计模式,笔者认为,不如说是一种前端解耦的解决方案更为妥当。关于MVVM,在Android里是需要一个特殊的lib库支持,才能实现MVVM的架构设计模式,这个lib在2015年5月google IO发布,并已集成到了Android studio中,建议是读者可以直接参考google Android Deloper官网的Data binding部分。本篇以android端的实现为例子介绍如何一步一步实现MVVM,权当做读者的快速上手文档。仍然以上面我们已经实现了的简易APP为例,不清楚的看第一章哟 构建前提是你的Android Studio升级到了1.3版本及以上(相信eclipse肯定也支持MVVM的构建,但是毕竟eclipse的开发方式逐步被Android studio替代,并且你的工程可以很容易从eclipse迁移到Android studio,鉴于此,使用studio说明MVVM的构建是OK的)第一步,设置Android Studio,打开 Preferences - Appearances & Behavior - Updates - 设置Automatically Check updates for 改为 Canary Channel。这个原因是MVVM毕竟在Android还算新的东西,并不完美,开启这个可以最快获取google发布的最新预览版,但可能会遇到BUG。图4 Android Studio设置第二步,配置data binding环境,data binding是一个依赖库,他支持Android2.1 及以上版本,但需要一定的配置。具体配置为,在gradle构建文件中配置如下:dependencies classpath com.android.tools.build:gradle:1.2.3 classpath com.android.databinding:dataBinder:1.0-rc0在每一个想使用data binding的module中添加如下:apply plugin: com.android.applicationapply plugin: com.android.databinding触发sync,等待Android studio,自动配置相关环境。这个时间有点长,建议是翻下墙。如上配置后,就可以开始正式的开发工作了,本文所有改动仍然是实现,上一章在MVP结构下构建的APP,在上一章中,虽然初步实现了View与业务逻辑解耦,但是每种不足的是Activity仍然遗留了大量代码,譬如view内容变化、事件监听等,data binding其实就是为了解耦这部分工作而存在的,实现了data binding的APP,这些操作可以直接在xml中配置实现,并且这种模式下,是支持条件判断的。相对上一章没有列出的layout,在MVVM中,上一章中的layout XML会长成如下样子: 可以见到,如上图中的xml的元素中,多了data节点,这个节点中定义的变量就与实际的view model交互,进而影响UI展现。1.1.4后记 如上,本章完成,主要讲解了MVC/MVP/MVVM的特点及他们之间的区别,通过简单的例子说明了如何设计一个简单的MVP/MVVM架构,关于这一章,建议是不要为了架构而架构,而是选择与自己产品形态和发展时期符合的开发架构和方式。尤其是在产品早期,不是非常建议非要做成那种架构。就像百度内部的手百APP,早期也只是简单的三层结构,并没有清晰的设计模式的概念,简单实用。无论是什么设计,都离不开低耦合、高聚合这个基本原则。1.2平台化解耦方案在国内的大环境下,一个APP往往会过度发展,具体表现是,体量极大,业务种类繁杂(譬如,社交APP玩O2O,支付APP玩社交一样),当然少不了2.3系统上65535的这个经典案例。往往,一个APP发展到这个阶段,在团队协作、研发方式上都会遇到不小的挑战,这时候,很多大公司会将,是时候尝试一些动态解决方案了。因此,hybrid、插件系统应用而生,用来解决上述问题。1.2.1 如何抉择如何抉择hybrid解决方案还是组件化(OSGI/AOP)的解决方案,可以参考笔者的经验在百度,这两种技术方案基本是并存的状态,但是却又解决了不同的问题,举个简单例子,百度内部有大量的解耦模块在百度内部大量APP上集成,主流的有基础类模块,语音、图像、定位、分享、用户反馈、安全网址等;垂类模块,贴吧、小说、新闻、地图、乐播、音乐等;O2O模块,电影、团购、酒店、外卖、出行等;这些模块的最大特点是,他们来自不同的事业部,是不同的兄弟团队开发的作品,持续的为百度容器类产品扩充能力(自黑一下,貌似如果把厂子看成一个搜索公司,那么在这个容器里上任何插件都可以理解为为满足用户需求的目的出发,也就没有什么百度全家桶之说了,哈哈),有次闲来无事,粗略估算了一下,这些模块放在一起,至少得有小100W行代码,如果这些模块都在同一个分之开发同一个分支发布的话,我想厂子一年能发布一款高质量产品就已经难能可贵了,所以这里哥们必须存在,当然,也必须是基于给用户最好体验的基础上那么回到正题,如何选择,其实这个就像是先有鸡还是先有蛋一样,永远不会有答案,依然还是上面的例子,就直接讲百度内部是如何使用这两个框架的吧百度内部hybrid和插件方案运行在一套叫做”苏伊士运河”的机制上,这两者并存,但解决的是不同的问题hybrid更倾向于解决O2O产品这种时效性要求高,版本发布频次高的场景,它的特点是可以直接发布独立的H5页面,而不需要动态加载机制支持,稳定性好,只要接口映射层设计OK,一般不会出现崩溃问题(也有badcase,IOS上有过页面死循环导致OOM的问题)插件方案更倾向于解决注重NA体验的组件,最直接的是语音组件,它有比较强的交互性,需要用户连续点击、长按等操作,并需要本地SO库支持,但却不一定经常发版,只是偶尔需要时发个版就可以了(需要动态方案支持)所以这个时候,插件化更适合这个场景,因为它比hybrid性能体验更好,是完全NA化的。我们内部对比,内部的hybrid调起速度慢于NA插件方案几倍,但加载完成流畅度是没有问题的。笔者注:有一种方案可以让插件方案直接取代hybrid,就是基于AOP编程的插件方案,但是这种在笔者看来,因为需要做系统API级别欺骗和大量反射工作,风险系数相对OSGI方案要高很多,并不推荐。这个方案目前已知的是360的DroidPlugin和百度的GPT方案图4.1 百度苏伊士运河技术方案从现在的经验看,百度内部的苏伊士运河,其实很好的融合了这两个方案,上架构图,读者一看便应该了解这套架构的好处是,hybrid框架是已有NA插件系统的一个插件,这样它可以继承原来NA插件系统已经开发好的本地端能力,同时仍然保佑自己的H5加载能力,同时,因为基于插件动态加载系统,一旦H5能力需求增长时,无需发版,直接基于动态插件系统下发就好了。可以说,这套系统完美的融合了hybrid和NA插件系统两者之间的优势,同时,只要做好技术选型,组件可以选择最适合框架进行开发。1.2.2 hybrid图4 hybrid架构图Hybrid是混合应用开发的简称,目前比较流行hybrid框架,国外有PhoneGap、Titanium,国内有比如AppCan、Rexsee等,在百度尝试最多的是PhoneGap,目前应用比较广泛的是百糯hybrid技术方案,但是并没有开源出来。1.2.3插件化系统实践插件化解决方案可以理解为模块动态化安装,在插件化方案下,一个独立APK可以当做某APP的一个组件,直接绕过系统OS的安装系统直接动态加载起来。这种方案,多见于Android平台,IOS平台因其系统封闭性,目前只有lua或JSpatch这种热修复方案,不能称为插件化解决方案。常见的插件化解决方案氛围OSGI和AOP两种,百度内部有两种技术方案,分别使用了OSGI技术方案和AOP技术方案,这两种方案的区别在于,OSGI方案,是基于组件代理的解决方案,它需要动态模块进行一定修改,目前开源的OSGI框架,有dynamic-load-apk;AOP方案,它的原理也不复杂,但是操作起来较为复杂,需要对系统的应用层有深刻理解,这套方案的特点是,任何APK无需修改,可以绕过系统直接动态安装,并且APK自身会认为自己是一个独立APK,这套框架业内比较知名的是360的DroidPlugin和百度内部的GPT框架。在百度,一些大的团队,从14年初开始,就走上了模块解耦动态下发的”不归路”,踩坑不少,但最终,这套系统终于稳定了下来,到现在,基本NA化的插件(与业界其他平台化产品相比,百度的插件无需关注体量,都可以放心安全的下发)也可以做到实时高质量下发。如何做到?一个完善的插件系统,除了端能力之外,还需包括如下几个部分:1、持续灰度系统,如果把APP看做一个容器的话,插件往往算是容器内的一个功能点,往往,插件的用户是APP这个容器用户的子集,所以,插件的上线需要走独立的灰度系统。这套系统核心在于,将目标用户从海量日志中统计出来,然后线上要有一套配套的下发小流量系统,当用户请求到达云端时,对用户配置进行识别,并定向下发。问题监控上,采取独立监控的手段,区别于端全量监控,端上有独立的SDK,当灰度下发到达时启用,并将灰度日志传到单独的server上去。2、线下兼容性扫描系统,每种插件技术,都存在不同样的机制问题,无论是AOP方案还是OSGI方案,这些问题机制坑一旦被踩到,问题表象往往就是一个崩溃(EXCEPTION)问题。一个配套的机制白盒扫描系统,可以解决类似问题,构建起来也非常简单,不需要类似findbugs这种关系型的扫描工具,只需要类似dexdump这种工具,能看到每一个插件内部变量和类的使用情况,这样基于平时积累的兼容性或不可解决的问题样本,即可构建自己的扫描规则,在百度,插件是不允许注册崩溃handler、使用app级context、无限制使用本地空间、操作登录状态、修改app传入的内存变量等。3、线上有一整套止损机制,随时应对各种突发情况,动态下发系统的使用,在业内已非常普遍,但是这套系统的运行往往需要承担一定风险,因为,无论是哪种插件化系统,都使用了大量的反射,来达到动态加载的目的。这一特性导致插件系统可能会因为rom、厂商、甚至是竞品APP的技术变化导致各种各样的兼容性问题。同时插件的运行,也会有如上的问题。所以云端要做好两种开关:1、保证插件系统即使被下掉,端APP也能正常使用&运行;2、对动态插件而言,需要有至少4个维度的止损能力,禁用、回滚、强制更新、最小OS|app 版本支持。云端则需要对插件进行分版本、OS、厂商进行控制这三套系统配合下,百度内的插件系统,在线上才会稳定运行,而当线上出现问题时,云端可以在最快1小时内做出反应,将损伤讲到最低1.2.4小结本章主要介绍了移动端平台化的解耦方案hybrid和插件化系统的特性和区别,以及他们在百度内部的实践。插件化系统在业界算是应用非常广泛了,但是笔者建议是,不到非做不可的时候,插件化系统是最不建议的解耦方案,原因是这种解决方案至今并不被android系统承认,使用的同时也带有比较大的不确定性。1.3基础库前言百度针对Android/IOS设备,提供了一系列应用程序接口,包括统计、定位、语音等等。开发者可以利用这些接口,使用统计组件分析应用程序,使用定位组件为应用程序增加位置信息,使用语音组件为应用程序增加语义识别功能。1.3.1 百度统计基础库百度移动统计()是业界领先的免费移动应用统计分析工具,支持iOS和Android平台,开发者通过嵌入统计SDK,实现对移动应用的全面监测,实时掌握产品表现,准确洞察用户行为。强大的报表分析功能,助您做到心中有“数”。使用方法百度移动统计提供了基本统计、错误统计、自定义事件统计等的功能。(1) 基础设置l Android端一、嵌入API的方式,开发者需要在每个Activity的onResume()和onPause()中调用SDK提供的StatService.onResume(Context context)和StatService.onPause (Context context);二、 直接继承SDK提供的StartService类。StatActivity封装了StatService.onResume(context)和StatService.onPause(context)方法,方便开发者统计页面信息。l IOS端需要设置两个方法(void) pageviewStartWithName:(NSString*) name、(void) pageviewEndWithName:(NSString*) name ,在IOS中某个视图开始被展示时调用 ,为该次视图访问命名为name。与pageviewEndWithName接口配对使用,在该视图消失时,调用pageviewEndWithName接口,填入同样的name值(2) 错误统计设置l Android端 在启动Activity的OnCreate()回调方法内插入void setOn(Context context, int flag),该API为开关类型的API,功能是否被启用,通过参数flag控制。目前,提供了错误分析的功能,后续版本的SDK会支持更多的功能。(3) 自定义事件统计设置l Android端自定义事件需要在百度移动统计的设置中的自定义事件管理中添加对应的事件ID。 void onEvent(Context context, String event_id, String label)void onEvent(Context context, String event_id, String label, int acc)可嵌入代码的任何位置l IOS端(void) logEvent:(NSString*) eventId eventLabel:(NSString*)eventLabel1.3.2 定位基础库百度地图Android定位SDK是为Android移动端应用提供的一套简单易用的LBS定位服务接口,专注于为广大开发者提供最好的综合定位服务,通过使用百度定位SDK,开发者可以轻松为应用程序实现智能、精准、高效的定位功能。使用方法初始化设置(1) 设置AndroidManifest.xml(2) 声明使用权限声明网络定位、GPS定位、访问WIFI、SDK读、运营商信息、手机状态、 访问网络、SD卡等的权限。 (3) 设置AcessKey /key:开发者申请的key (4) SDK相关类概要com.baidu.location.BDLocation;com.baidu.location.BDLocationListener;com.baidu.location.LocationClient;com.baidu.location.LocationClientOption;com.baidu.location.BDNotifyListener;/假如用到位置提醒功能,需要import该类com.baidu.location.Poi;定位接口(1) 初始化LocationClient类主线程中声明LocationClient类public LocationClient mLocationClient = null;public BDLocationListener myListener = new MyLocationListener(); public void onCreate() mLocationClient = new LocationClient(getApplicationContext(); /声明LocationClient类 mLocationClient.registerLocationListener( myListener ); /注册监听函数(2) 配置定位SDK参数使用LocationClientOption类,设置定位参数包括:定位模式(高精度定位模式,低功耗定位模式和仅用设备定位模式),返回坐标类型,是否打开GPS,是否返回地址信息、位置语义化信息、POI信息等等(3) 实现BDLocationListener接口BDLocationListener接口有1个方法需要实现: 1.接收异步返回的定位结果,参数是BDLocation类型参数。public class MyLocationListener implements BDLocationListenerOverridepublic void onReceiveLocation(BDLocation location) (4) 开启定位mLocationClient.start();1.3.3 语音基础库百度语音识别是一种面向移动设备的语音识别解决方案。通过该方案,开发者可以轻松构建出功能丰富、交互性强的语音识别应用程序。 使用方法语音SDK的识别主要有语音识别控件和API方式两种识别方法语音识别控件(1) 创建识别对象l Android端/ 创建百度语音识别对话框BaiduASRDigitalDialog mDialog = new BaiduASRDigitalDialog(this, params);/ 设置对话框回调监听器mDialog.setDialogRecognitionListener(new DialogRecognitionListener() / 识别结果处理函数 public void onResults(Bundle arg0) ArrayList rs = results != null ? results .getStringArrayList(RESULTS_RECOGNITION) : null; if (rs != null & rs.size() 0) recognition_result = rs.get(0); );(2) 启动识别l Android端mDialog.show();l IOS端recognizerViewController startWithParams:paramsObject;API方式识别(1) 创建实例l Android端private android.speech.SpeechRecognizer mSpeechRecognizer; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); / . mSpeechRecognizer=SpeechRecognizer.createSpeechRecognizer(this,new ComponentName(this, VoiceRecognitionService.class); l IOS端BDVoiceRecognitionClient *sharedInstance = BDVoiceRecognitionClient sharedInstance;(2) 设置监听l Android端RecognitionListener listener = new RecognitionListener() / ., 略过具体实现 ;mSpeechRecognizer.setRecognitionListener(listener);监听器包括onReadyForSpeech、onBeginningOfSpeech、onRmsChanged、onBufferReceived、onEndOfSpeech、onResults等方法的回调l IOS端接收结果需要实现MVoiceRecognitionClientDelegate协议。此协议主要是通知识别过程中的各种状态和结果(3) 开始识别l Android端Intent recognizerIntent = new Intent();/ recognizerIntent.putExtra .mSpeechRecognizer.startListening(recognizerIntent);l IOS端int startStatus = BDVoiceRecognitionClient sharedInstance startVoiceRecognition:self; switch(startStatus) case EVoiceRecognitionStartWorking :. / 启动成功 . (4) 停止录音l Android端mSpeechRecognizer.stopListening();1.4移动客户端编译打包方式移动客户端的编译打包,是客户端CI的开始点。通过jenkins等持续集成平台,结合代码管理工具,搭建自动编译任务,按照约定的条件自动打包,能够节省人力,管理迭代提测版本,节省人力。移动端编译打包,按照系统不同,可以分成android编译和ios编译两类,各自的编译工具和方式也各不相同,下面分章节概述其主要的编译工具和方法1.4.1 android端编译随着android系统的不断升级,android端的主流编译方式,经历了ant、maven、gradle等几种方式,目前google官方推荐的方式是gradle方式。本节将首先概述android apk编译的具体流程,然后针对几种主流编译方式进行说明。 android端编译过程android端的整个编译过程,会调用很多编译工具,生成大量的中间文件,并最终生成一个apk文件。编译过程为:1. 打包资源文件,生成R.java文件:使用aapt工具($ANDROID_SDK_HOME/platform-tools/aapt)打包好资源文件,生成R.java文件。2. 处理AIDL文件,生成对应的.java文件:使用aidl工具,通过源码、aidl、framework.aidl等文件,生成对应的java文件,如果工程中无aidl文件,则该步骤将跳过。3. 编译.java文件,生成.class文件:使用javac工具,将所有.java文件编译成.class文件4. 将.class文件转换成.dex文件,供Davik虚拟机加载使用使用dex工具,将.class文件打包成dex文件(混淆操作在该步骤之前)5. 打包未签名的.apk文件使用apkbuilder工具,将1-4步骤中的产物(以及libs下的库文件),打包成apk文件6. 给未签名的apk文件打签名使用jarsigner工具,将签名文件(.keystore文件),打入apk文件中7. apk文件对齐处理使用zipalign工具,将步骤6中的产物进行优化和对齐。可以参考如下的流程:/sdk/installing/studio-build.html图2-1 android编译流程图 Ant方式编译android appAnt工具,是Apache软件基金会JAKARTA目录下的一个自项目,工具使用纯java语言编写,因此可以跨平台执行。使用Ant工具进行编译打包,需要一个build.xml文件来进行配置。对于比简单的android项目,我们可以使用“android update project path 工程路径”命令来自动生成build.xml文件。但显然,对于比较复杂的客户端,可以自己编写一个build.xml文件来实现复杂的编译需求。build.xml简介2.1.1节中,我们简单介绍了android端编译的整个流程,结合这个流程,一个简单的自定义build.xml如下:解释一下上面build.xml片段中的内容:1. 标签:是build.xml文件的根标签,每个标签对应一个项目。它可以由多个内在的属性,其主要属性如下:default表示默认的运行目标,这个属性是必须的。basedir表示项目的基准目录。name表示项目名称。description表示项目的描述。2. 标签build.xml的重要组成部分,整个build的过程都是由一个个target构成的。target之间通过depends属性建立依赖关系,target的depends需要先于该target执行。target的主要属性如下:.name表示target名称,这个属性是必须的。.depends表示依赖的对象,这个属性不适必须的,一个target可以由多个depends。if表示仅当当前属性设置时才执行。unless属性和if属性相反,表示当前属性没有设置的时候才执行。description属性表示当前target的描述。3. 标签用来创建一个目录。,则会新建一个路径名对应的目录。4. 标签用来生成一个jar文件,主要属性如下:destfile表示jar文件名称。basedir表示被归档的文件名。includes表示被归档的文件类型。exclude表示不被归档的文件类型。5. 标签用于编译java文件,其属性如下:.srcdir 表示源程序的src目录。.destdir表示.class文件的输出目录。.include表示被编译的文件类型。excludes表示被排除的文件类型。.classpath表示所使用的类路径。.debug表示包含的调试信息。.optimize表示是否使用优化。.verbose表示提供详细的输出信息。.failonerror表示遇到错误的时候自动停止。6. 标签用于执行本地环境中的可执行命令,命令参数使用方式来添加,其主要属性如下:executable表示可执行文件的名称。fialonerror表示遇到错误的时候停止。几个重要的配置在android项目中,我们可能需要配置混淆,添加libs以外的编译依赖,或者是添加对lib工程的编译依赖,此外,如果项目比较大的话,可能还会遇到oom等问题。下面分别描述各个问题的配置方式。混淆的配置:代码混淆主要是使用proguard.jar文件,对编译后的.class文件进行混淆。其具体的配置项如下: obf

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论