|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
有一些像NSCopying的接口(经@李禹龙提醒应该叫协议)不是特别用到开始不用了解NSObject创建对象的时候用+(id)alloc方法创建后需要init方法初始化概述
每当发新版本时,美团团购Android客户端会被分发到各个使用市场,好比豌豆荚,360手机助手等。为了统计这些市场的效果(活泼数,下双数等),必要有一种办法来独一标识它们。
团购客户端今朝经由过程渠道号(channel)来辨别分歧的市场,代码中利用Config.channel变量纪录该渠道号。好比,豌豆荚市场中美团使用的渠道号是wandoujia,360手机助手中美团使用的渠道号为qihu360。客户端会见API时会在哀求参数中带上渠道号,以便背景接上去盘算分歧渠道的效果。
每次发版时,市场部会供应一个渠道列表,AndroidRD会依据这些渠道响应地天生等量的渠道包。跟着渠道愈来愈多(停止本文写作时已有900多个渠道),客户端打渠道包的体例也一向在演进,本文接上去就具体先容美团使用的打包之旅。
Maven
Maven是一个软件项目办理和主动构建工具,共同利用android-maven-plugin插件,和maven-resources-plugin插件能够很便利的天生渠道包,上面扼要先容下打包历程,更多Maven和插件的利用办法请参考相干文档。
起首,在AndroidManifest.xml的<application>节点中增加以下<meta-data>元素,用来界说渠道的- <!--利用Maven打包时会器具体的渠道号交换失落${channel}--><meta-dataandroid:name="channel"android:value="${channel}"/>
复制代码 界说好渠道来历后,接上去就能够在程序启动时读取渠道号了:- privateStringgetChannel(Contextcontext){try{PackageManagerpm=context.getPackageManager();ApplicationInfoappInfo=pm.getApplicationInfo(context.getPackageName(),PackageManager.GET_META_DATA);returnappInfo.metaData.getString("channel");}catch(PackageManager.NameNotFoundExceptionignored){}return"";}
复制代码 要交换AndroidManifest.xml文件界说的渠道号,还必要在pom.xml文件中设置Resources插件:- <resources><resource><directory>${project.basedir}</directory><filtering>true</filtering><targetPath>${project.build.directory}/filtered-manifest</targetPath><includes><include>AndroidManifest.xml</include></includes></resource></resources>
复制代码 筹办事情已完成,如今必要的就是实践的渠道号了。上面的剧本会遍历渠道列表,逐一交换并打包:- #!/bin/bashpackage(){whilereadlinedomvncleanmvn-Dchannel=$linepackagedone<$1}package$1
复制代码 在后期渠道很少时这类办法还能够承受,但只需渠道略微增加该办法就不再合用了,缘故原由是每打一个包都要实行一遍构建历程,效力太低。
apktool
apktool是一个逆向工程工具,能够用它解码(decode)并修正apk中的资本。接上去具体先容怎样利用apktool天生渠道包。
后期事情和用Maven打包一样,也必要在AndroidManifest.xml文件中界说<meta-data>元素,并在使用启动的时分读取清单文件中的渠道号。详细请参考下面的代码。
和Maven纷歧样的是,每次打包时不再必要从头构建项目。打包时,只需天生一个apk,然后在该apk的基本上天生其他渠道包便可。
起首,利用apktooldecode使用程序,在终端中输出以下命令:- apktooldyour_original_apkbuild
复制代码 下面的命令会在build目次中decode使用文件,decode完成后的目次以下:
<br>
接上去,交换AndroidManifest.xml文件中界说的渠道号,上面是一段python剧本:- importredefreplace_channel(channel,manifest):pattern=r(<meta-datas+android:name="channel"s+android:value=")(S+)("s+/>)replacement=r"g<1>{channel}g<3>".format(channel=channel)returnre.sub(pattern,replacement,manifest)
复制代码 然后,利用apktool构建未署名的apk:- apktoolbbuildyour_unsigned_apk
复制代码 最初,利用jarsigner从头署名apk:- jarsigner-sigalgMD5withRSA-digestalgSHA1-keystoreyour_keystore_path-storepassyour_storepass-signedjaryour_signed_apk,your_unsigned_apk,your_alias
复制代码 下面就是利用apktool打包的办法,经由过程利用剧本能够批量地天生渠道包。不像Maven,每打一个包都必要实行一次构建历程,该办法只需构建一次,年夜小节省了工夫。
可是好景不长,我们的渠道包愈来愈多,今朝已有近900个渠道,打完一切的渠道包必要近3个小时。有无更快的打包体例呢?且看下节。
META-INF
假如能间接修正apk的渠道号,而不必要再从头署名能节俭很多打包的工夫。侥幸的是我们找到了这类办法。间接解压apk,解压后的根目次会有一个META-INF目次,以下图所示:
<br>
假如在META-INF目次内增加空文件,能够不必从头署名使用。因而,经由过程为分歧渠道的使用增加分歧的空文件,能够独一标识一个渠道。
上面的python代码用来给apk增加空的渠道文件,渠道名的前缀为mtchannel_:- importzipfilezipped=zipfile.ZipFile(your_apk,a,zipfile.ZIP_DEFLATED)empty_channel_file="META-INF/mtchannel_{channel}".format(channel=your_channel)zipped.write(your_empty_file,empty_channel_file)
复制代码 增加完空渠道文件后的目次,META-INFO目次多了一个名为mtchannel_meituan的空文件:
<br>
接上去就能够在Java代码中读取空渠道文件名了:
所以你可以用很多方法存储数据比如最长用的sqlite当然如果另类也可以用plist文件或者其他NSManagedObjectContextNSManagedObjectContext |
|