±à¼ÍƼö: |
±¾ÎÄÖ÷Òª½éÉÜÁËAtlasÊÇʲô£¿×é¼þ»¯¼¼Êõϸ½Ú¡¢Atlas¶¯Ì¬»¯ÒÔ¼°AtlasÏîĿʵ¼ù¡£
±¾ÎÄÀ´×ÔÓÚcsdn£¬ÓÉ»ðÁú¹ûÈí¼þAlice±à¼¡¢ÍƼö¡£ |
|
Atlas¼ò½é
AtlasÊÇÒ»¸öAndroid¿Í»§¶ËÈÝÆ÷¿ò¼Ü£¬Ö÷ÒªÌṩÁË×é¼þ»¯¡¢¶¯Ì¬ÐÔ¡¢½âñµÄÖ§³Ö£¬Ö§³ÖÔÚ±àÂëÆÚ¡¢ApkÔËÐÐÆÚÒÔ¼°ºóÐøÔËάÐÞ¸´ÆÚµÄ¸÷ÖÖÎÊÌâ¡£AtlasĿǰ֧³ÖµÄÖ÷Òª¹¦ÄÜÓУº
ÔÚ¹¤³ÌÆÚ£¬ÊµÏÖ¹¤³Ì¶ÀÁ¢¿ª·¢£¬µ÷ÊÔ¹¦ÄÜ£¬¹¤³ÌÄ£¿éµÄ¶ÀÁ¢£»
ÔÚÔËÐÐÆÚ¼ä£¬ÊµÏÖÍêÕûµÄ×é¼þÉúÃüÖÜÆÚÓ³É䣬Àà¸ôÀëµÈ»úÖÆ£»
ÔÚÔËάÆÚ¼ä£¬Ìṩ¿ìËÙÔöÁ¿µÄ¸üÐÂÐÞ¸´¹¦ÄÜ£¬¿ìËÙÉý¼¶¡£
AtlasÊǹ¤³ÌÆÚºÍÔËÐÐÆÚ¹²Í¬Æð×÷ÓõĿò¼Ü£¬Ëü¾¡Á¿½«Ò»Ð©¹¤×÷·ÅÔÚ¹¤³ÌÆÚ£¬ÕâÑù±£Ö¤ÔËÐÐÆÚµÄ¼òµ¥¡¢Îȶ¨¡£ÏÂÃæÊÇAtlas×é¼þ»¯µÄÒ»¸ö¿ò¼ÜÔÀíͼ¡£

ÉÏͼÊÇÊÖ»úÌÔ±¦µÄapk£¬µÚÒ»²ãĿ¼ÉÏÓë±ê×¼µÄapkÊÇÍêȫһÑùµÄ¡£ÔÚApp»áÓкܶàµÄsoÎļþ£¬Ã¿¸ösoÎļþÈç¹û½â¿ªÀ´¿´ËüµÄ½á¹¹ÀàËÆÓÚÍêÕûµÄapk£¬µ«±¾Éí²»ÄܶÀÁ¢ÔËÐУ¬ËüÔËÐÐÔÚÕû¸öÈÝÆ÷Àÿһ¸ö×é¼þ¶¼ÊǶÀÁ¢µÄBundle¡£ÀýÈ磬ÊÖÌÔµÄÄ£¿é²ã´Î»®·ÖÈçÏÂͼ¡£

´ÓÄ£¿éÀ´»®·Ö£¬ÊÖÌÔAPK¿ÉÒÔ·ÖΪÁ½²ã£¬ÉϲãÊǾ¹ý²ð·ÖµÄÒµÎñBundle£¬É¨Âë¡¢ÆÀ¼Û¡¢ÏêÇ飬¸÷¸öÒµÎñÖ®¼ä¿ÉÒÔ½øÐй¦Äܵĵ÷Ó㬿ÉÒÔͨ¹ý·Óɵ÷¶Èµ½ÆäËûÒµÎñ·½¡£Ï²ãÊǹ²ÏíµÄµ×²ãÖмä¼þ£¬ÏòÒµÎñ·½¿ª·Å¸÷ÖÖÄÜÁ¦£¬ÈçÍøÂç¿â¡¢Í¼Æ¬¿âµÈ£¬»áÔÚÈÝÆ÷Àï½øÐÐͳһµØ°Ñ¿Ø£¬ÕâÑù×öµÄºÃ´¦Êǰü×öµ½¾¡¿ÉÄÜС£¬µÚ¶þÊÇÐÔÄܼѡ£

AtlasµÄÕûÌå·ÖΪ5²ã£º
µÚÒ»²ã³ÆÖ®ÎªHack²ã£¬°üÀ¨OS Hack toolkit & verifier£¬ÕâÀï¶ÔϵͳÄÜÁ¦×öһЩÀ©Õ¹£¬È»ºó×öһЩ°²È«Ð£Ñé¡£
µÚ¶þ²ãÊÇBundle Framework£¬¾ÍÊǵÄÈÝÆ÷»ù´¡¿ò¼Ü£¬ÌṩBundle¹ÜÀí¡¢¼ÓÔØ¡¢ÉúÃüÖÜÆÚ¡¢°²È«µÈһЩ×î»ù±¾µÄÄÜÁ¦¡£
µÚÈý²ãÊÇÔËÐÐÆÚ¹ÜÀí²ã£¬°üÀ¨Çåµ¥£¬»á°ÑËùÓеÄBundleºÍËüÃǵÄÄÜÁ¦ÁÐÔÚÒ»¸öÇåµ¥ÉÏ£¬ÔÚµ÷ÓÃʱ·½±ã²éÕÒ£»ÁíÍâÊǰ汾¹ÜÀí£¬»á¶ÔËùÓÐBundleµÄ°æ±¾½øÐйÜÀí£»ÔÙ¾ÍÊÇ´úÀí£¬ÕâÀï¾ÍÊǺÍÒµ½çһЩ²å¼þ»¯¿ò¼Ü»úÖÆÀàËÆµÄµØ·½£¬»á´úÀíϵͳµÄÔËÐл·¾³£¬ÈÃBundleÔËÐÐÔÚµÄÈÝÆ÷¿ò¼ÜÉÏ£»È»ºó»¹Óе÷ÊÔºÍ¼à¿Ø¹¤¾ß£¬ÊÇΪÁË·½±ã¹¤³ÌÆÚ¿ª·¢µ÷ÊÔ¡£
µÚËIJãÊÇÒµÎñ²ãÁË£¬ÕâÀïÏòÒµÎñ·½±©Â¶ÁËһЩ½Ó¿Ú£¬Èç¿ò¼ÜÉúÃüÖÜÆÚ¡¢ÅäÖÃÎļþ¡¢¹¤¾ß¿âµÈµÈ¡£
×é¼þ»¯¼¼Êõϸ½Ú
¹ØÓÚBundleµÄÉúÃüÖÜÆÚ»áÌṩϸÁ£¶ÈµÄ½Úµã£¬±ÈÈçÏÂÃæÊÇÒ»¸öBundle´Ó¼ÓÔØµ½ÔËÐеÄÖÜÆÚ£º
startInstall£º¿ªÊ¼¼ÓÔØ¡£Õâ¸öʱºò¿ò¼Ü»á×öһЩ¿½±´Îļþ¡¢ÊÍ·Ålib¡¢¼ÓÔØBundleµÄÊÂÇ飻
Installed£º¼ÓÔØÍê±Ï¡£Õâʱ¿ò¼Ü»á×¢Èë×ÊԴ·¾¶£¬´´½¨class loader£»
resolved£º½âÎöÍê±Ï£¬¿ò¼Ü»á¼ì²é×é¼þÅäÖÃÊÇ·ñºÏ·¨£¬ÊÇ·ñÄܱ»½âÎö£»
active£ºÔËÐÐ×é¼þ£¬¼´¿ªÊ¼ÔËÐÐ×é¼þBundle£»
started£ºÔËÐгɹ¦¡£
×é¼þ»¯Éæ¼°µ½µÄµÚÒ»¸öÎÊÌâÊÇManifest´¦Àí£¬Ò»¸öÊÇÒòΪÀ´Ô´ºÜ¶à£¬ÓÐËÞÖ÷Manifest¡¢Aar
ManifestÒÔ¼°×é¼þManifest£¬ÁíÍⲻͬ×é¼þµÄManifest¾³£·¢Éú±ä»¯£¬ÒªÇóÁé»îµØÈ¥´¦Àí¡£ÕâÀïµÄ×ö·¨ÊÇÔÚ¹¤³ÌÆÚ½«ËùÓеÄManifest½øÐÐMerge²Ù×÷£¬ÕâÀïÐèҪעÒâµÄÊÇBundleµÄÒÀÀµµ¥¶ÀMerge£¬ÒòΪÕâÀïÉæ¼°µ½ÒÀÀµÖٲõÄÎÊÌâ¡£×îºó½âÎö¸÷¸öBundleµÄMerge
Manifest£¬µÃµ½Õû°üµÄBundleInfoList£¬¾ÍÊÇÉÏÃæÌáµ½µÄBundleÐÅÏ¢Çåµ¥¡£

µÚ¶þ¸öÊÇÀà¼ÓÔØ£¬ÕâÀïÀûÓÃDelegate ClassLoaderÀ´¶¯Ì¬¼ÓÔØ×é¼þµÄÀà¡£Delegate
ClassLoaderÏȲéÕÒËÞÖ÷BundleµÄPathClassLoader£¬È»ºó¸ù¾ÝÇ°ÃæµÄBundleListÕÒµ½¶ÔÓ¦µÄBundleClassLoader¡£

µÚÈý¸öÊÇ×ÊÔ´£¬»áÓÃ×Ô¼ºµÄDelegeteResourcesÌæ»»µôϵͳµÄresource£¬BundleµÄ×ÊÔ´»áÖð¸öÔÚ°²×°µÄʱºòÌí¼Óµ½AssertPath£¬ÓÉÓÚÌí¼ÓBundleµÄ˳Ðò·Ç¹Ì¶¨£¬²»·ÖÇø»áµ¼ÖÂ×ÊÔ´²éÕÒ´íÂÒ¡£
ÁíÍ⣬DalvikºÍARTÉϵÄ×ÊÔ´²éÕÒ¹ý³Ì˳ÐòÊDz»Ò»ÑùµÄ£¬¼ÓÉÏСÃ×µÈϵͳ»áÖØÐ´×Ô¼ºµÄresources£¬ËùÒÔ»áÊÊÅ䲻ͬµÄ»úÐÍ£¬Íùºó×·¼ÓAssetsPath»òÕßÍùǰ׷¼Ó£¬ÏµÍ³AssetManagerÊǸöµ¥Àý£¬Ä¬ÈÏÍùºó×·¼Ó£¬Èç¹ûÍùǰ׷¼Ó£¬ÔòÐèÒªÖØÐ´´½¨AssetsManager¶ÔÏó£¬Í¬ÑùÖ÷dex¶¯Ì¬²¿ÊðµÄʱºòÒª´ïµ½Ìæ»»ÔÓÐresourceµÄÄ¿µÄ£¬±ØÐë±£Ö¤²åÈë˳ÐòÓë²éÕÒ˳ÐòÒ»Ö¡£
»¹ÓÐÐèҪעÒâµÄÊÇ£¬Ã¿´Î¸üÐÂresourceTableµÄʱºò£¬±ØÐë±£Ö¤apkresource£¬runtimeµÄϵͳresource£¬ÀýÈçwebview£¬bundle
resource¶¼ÒѾÌí¼Ó³É¹¦£¬¶øÇÒΨһ£¬Ë³ÐòÕýÈ·¡£
²»Í¬BundleµÄ×ÊÔ´¿ÉÄÜ·¢ÉúÃüÃû³åÍ»£¬ÊÇÓÃÁËÒ»ÖÖÏà¶ÔÀ´Ëµ¼òµ¥µÄ·½·¨£¬½«¸÷×ÔµÄBundle·ÖÅä³É²»Í¬µÄID£¬±£Ö¤ËùÓеÄÒµÎñ×ÊÔ´²»»á²úÉú³åÍ»£¬¾¡Á¿½«ÎÊÌâ·Åµ½¹¤³ÌÆÚ½â¾ö¡£Ôںܶà´úÂëÀͨ¹ý·´ÉäÀ´µ÷ÓÃÕû¸ö×ÊÔ´£¬ÔÚ5.0ÒÔÉϵÄϵͳÊÇûÓÐÎÊÌâµÄ£¬ËüÖ»ÕÒµÚÒ»¸ö£¬¶ÔÒµÎñ´úÂë¶øÑÔ£¬ÔÀ´ÊÇÔõôдµÄ£¬½ñÌ컹ÊÇÔõôȥд¡£
¹ØÓÚ×é¼þ»¯ÐÔÄÜÕâÒ»²¿·Ö£¬ÒýÈëÁ˰´Ðè¼ÓÔØ£¬ÒòΪÊÖÌÔAPKÓÐ70¶à¸öBundle£¬Ã¿¸öÓû§ÕæÕýÓõÄʱºòÖ»ÐèÒª5»ò10¸ö£¬ËùÒÔ²»ÐèÒª¼ÓÔØËùÓеÄBundle¡£BundleÖ®¼ä½øÐиôÀ룬ͨ¹ýAndroidËÄ´óÔÉú×é¼þ½øÐн»»¥£¬ÕâÑùBundleÖ®¼ä¿ÉÒԱȽϺõĽâñî¡£ËùÓе÷ÓõÄÈë¿Ú¶¼ÊÇ»ùÓÚBundleInfolistÈ¥×öµÄ£¬¸ù¾ÝÕâ¸öÇåµ¥ÐÅÏ¢£¬µÃµ½×é¼þËùÔÚBundle£¬Èç¹ûÐèÒª¼ÓÔØ£¬¾Í½øÐÐinstall¡¢dexoptµÈ²Ù×÷¡£
ÁíÍ⣬¶ÔÓÚ½â¾ö×é¼þÒÀÀµÎÊÌ⣬¶¨ÒåÁËÁ½ÖÖеÄ×é¼þ¸ñʽAwb£¨ÒµÎñBundle£©ºÍsolib£¨so¿â£©£¬Ç°ÕßÓëAARÒ»Ö£¬²»¹ý²»Ìí¼Ó±¾µØlib£¬ÔÚ¹¹½¨µÄʱºò×öÒÀÀµÖÙ²ÃÇø·Ö£¬ºóÕßÊÇNative
so¿âµÄÒÀÀµ¡£AwbÆäʵ¾ÍÊÇAAR£¬Ö»ÊǺó׺ÐÞ¸ÄÁË£¬Èç¹ûÄãµÄ°ü·ÅÔÚËÞÖ÷Bundle¾ÍÓÃAAR£¬Èç¹ûÊÇ×é¼þBundle¾ÍÓÃAwb¡£
¶ÔÓÚÒµÎñBundleµÄÒÀÀµ£¬ÔÚ¹¹½¨ÆÚ»á½«ËÞÖ÷BundleºÍÒµÎñBundle¼°ÆäÒÀÀµ·Ö±ð´ò°ü£¬È»ºó°´ÕÕ×î¶Ì·¾¶¡¢µÚÒ»ÉùÃ÷ÔÔò½øÐÐÊ÷×´Öٲ㬵õ½Ã¿¸öBundleÐèÒªµÄÒÀÀµ£¬ÔÚ´ò°üµÄʱºò»á½«ÒÀÀµ¿â·Åµ½¸÷×ÔµÄBundleÀïÈ¥¡£

×îºóÊÇAPK¹¹½¨£¬¶ÔËü×öÁ˱ȽϴóµÄµ÷Õû¡£ÉÏÃæµÄͼÖУ¬Æäʵ×ó±ßÕâÒ»²¿·ÖÊÇÒ»¸ö±ê×¼µÄAPKµÄ¹¹½¨¹ý³Ì£¬°üÀ¨´¦Àí£¬±àÒ룬µ½Ç©ÃûµÄ¹ý³Ì¡£Õâ¸ö²»Í¬µÄµØ·½ÊǶàÁËAwbÐèÒªÌØÊâ´¦Àí£¬ÆäÖÐAwbµÄ×ÊÔ´¸ù¾ÝËÞÖ÷µÄresource.ap_ºÍ°üÄÚ×ÊÔ´¹¹½¨£¬RÎļþÓÉBundle
R×ÊÔ´ºÍËÞÖ÷R×ÊÔ´ºÏ²¢¶øÀ´£¬È»ºó¶ÔAapt½øÐÐÁËÐ޸쬶Ôÿ¸öawb·ÖÅ䲻ͬµÄpackageId£¬È»ºó½øÐÐͳһ»ìÏý£¬Éú²ú¸÷¸öAWBµÄDex£¬´ò°üΪAPK£¬Ç©ÃûÖ®ºó¸´ÖƵ½libs£¬¸ÄÃûΪsoÎļþ£¬È»ºóºÏ²¢µ½taobao
APK. Õâ¾ÍÊÇ×é¼þ»¯µÄÕû¸ö¹ý³Ì¡£
Atlas¶¯Ì¬»¯
ÔÚÒ»¸öÈÝÆ÷¿ò¼ÜÄÚ£¬×é¼þ»¯ºÍ¶¯Ì¬»¯ÊÇÏศÏà³ÉµÄ£¬×é¼þÖ»Êǽâ¾öÁ˽âñîµÄÎÊÌ⣬µ«Èç¹ûÏëÒªËæÊ±·¢°ü£¬¾Í±ØÐëÈÃÈÝÆ÷¿ò¼Ü¾ß±¸¶¯Ì¬»¯ÄÜÁ¦¡£ÔÚÍê³ÉÁËAtlasµÄ×é¼þ»¯Ö®ºó£¬×öÁ˶¯Ì¬»¯µÄÖ§³Ö¡£¶¯Ì¬»¯µÄºÃ´¦Ò»¸öÊǰüµÄ´óСËõ¼õ£¬¿ÉÒÔ½«Ò»Ð©°üÔÚÔËÐкóÏÂÔØµ½Ó¦ÓÃÖУ¬ÁíÒ»¸öÊǾ߱¸¶¯Ì¬·¢°æºÍÐÞ¸´ÄÜÁ¦¡£
AtlasÌṩÁ˶¯Ì¬²¿ÊðµÄÄÜÁ¦£¬Ö÷ҪĿ±êÊǶ¯Ì¬ÒµÎñ·¢²¼£¬ÒÔ¼°ÎÊÌâÐÞ¸´¡£Ëü»ùÓÚÊÖÌÔ×ÔÑвîÁ¿Ëã·¨£¬Ö÷Bundle»ùÓÚClassLoader»úÖÆ£¬ÒµÎñBundle»ùÓÚ²îÁ¿merge£¬Ö§³ÖȫҵÎñÀàÐÍ¡£
ÁíÍ⣬AtlasÒ²Ö§³ÖAndfix×÷Ϊ²å¼þʹÓã¬Ä¿±êÊÇ¿ìËÙ¹ÊÕÏÐÞ¸´£¬ËüµÄÔÀí»ùÓÚNative hook£¬Ö÷Òª×ö·½·¨µÄÐ޸ģ¬ÔÚʵ¼ÊÖпÉÒÔÁ½¸öÒ»ÆðÓá£ÔÚ¹¤³Ì¹¹½¨ÆÚÊÊÅäÖ®ºó£¬¿ÉÒÔ×öµ½Ò»Ì×´úÂëÁ½Ì×·½°¸Í¨Ó᣸÷½°¸µÄÔÀíͼÈçÏ£º

×ÔÑж¯Ì¬²¿Êð¹¦ÄÜʵÏÖÔÀí£¬Ê×ÏÈ£¬¶ÔÓÚDex PatchµÄÉú³É£¬Í¨¹ýÐÞ¸ÄDexµÄ×Ö½ÚÂëʵÏÖ£¬½«DexÎļþתΪSmali£¬¶ÔÆäÖеÄClassDefºÍClassDataMethod½á¹¹Ìå½øÐзÖÎö£¬¿ÉÒÔʵÏÖɾ³ý¡¢ÐÂÔö¡¢ÐÞ¸ÄÀ࣬Ȼºóͨ¹ýDiff´¦ÀíµÃµ½²îÁ¿Îļþ£¬ÔÙͨ¹ýMerge´¦Àí¼´Éú³É²¹¶¡¡£
Æä´ÎÊÇÕû¸ö×ÊÔ´PatchµÄÉú³É£¬·ÖΪÁ½¿é£¬Ò»¸öÊÇÒµÎñBundle£¬±¾À´ÊÇÒ»¸ö²»¶Ï¼ÓÔØµÄ¹ý³Ì£¬ËüʵÏÖÆðÀ´»á±È½Ï¼òµ¥£¬Í¨¹ýMd5
diff/BSDiff¼´¿ÉµÃµ½¡£¶ÔÓÚÖ÷Bundle£¬ÒòΪ°²×¿±¾ÉíÓÐÒ»¸öÏÞÖÆ£¬ËùÓеÄ×ÊÔ´±ØÐëµÃÔÚbase°üÀÐÂÔöÒ»¸ö×ÊÔ´ÊDz»ÉúЧµÄ¡£ËùÒÔÒ»¸ö×ö·¨ÊÇÔÚ´ò°üµÄʱºòÔ¤ÁôºÜ¶à¿Õ×ÊÔ´¡£ÁíÍâ¸üÐÂÒÑÓеÄ×ÊÔ´Ôòͨ¹ý×ÊÔ´¸²¸ÇÀ´Íê³É¡£
×îºó£¬Èç¹ûмÓÒµÎñµÄ»°£¬»áмÓActivity£¬µÄ×ö·¨Ê×ÏÈÔÚManifestÔ¤ÂñÒ»¸öStubActivity£¬È»ºóÔÚInstrumentation.execStartActivity()½×¶Î½øÐÐÌæ»»£¬Í¬Ê±ÅäºÏIntent
setFlagÄ£ÄâActivity launch mode²¢¼ÌÐøstartActivity£¬½Ó×ÅSystem_server½ø³Ì½øÐд¦Àí£¬¸üÐÂActivityStack£¬´´½¨binder£¬²¢Í¨ÖªActivityThread½øÐÐʵÀý´´½¨£¬×îºóÔÚActivityThreadµÄhandlerÀïÃæ½øÐÐÀ¹½Ø£¬¸üÐÂActivityInfoµÈÐÅÏ¢£¬´´½¨Ä¿±êActivity¡£
ÁíÍâÔÚ¹¤³Ìʵ¼ùÉÏ£¬ÒòΪ²¹¶¡µÄÉú³É»áÉæ¼°µ½DexºÍ×ÊÔ´µÄ»ùÏߣ¬»áÔÚ²¿ÊðµÄʱºò£¬Ã¿´Î·¢²¼APK°üͬ²½·¢²¼AP£¨»ùÏß°ü£©µ½Maven£¬AP»ùÏß°üÀïÊÇËùÓÐÓ°Ïì»ùÏßµÄÎļþ£¬µÚÒ»Êǰ²×¿APK£¬µÚ¶þÊÇMapping.txt£¬×îºóÊÇDependency.txt£¬ÕâÑùµÄ»°Õû¸ö¹¹½¨µÄËÙ¶È»á·Ç³£µÄ¿ì¡£
ËùÒÔÕâÖÖ·½Ê½£¬°æ±¾µÄÉý¼¶ÊDz»Í¬µÄ·½Ê½¡£±ÈÈç½ñÌìÊÖÌÔµÄÏêÇéÒª¸üУ¬»á·¢²¼°æ±¾£¬Õâ¸ö°æ±¾¿ÉÄܲ»Êǵ½Ó¦ÓÃÊг¡µÄ°æ±¾£¬¶øÊÇÒ»¸öPatch°ü¡£ÒµÎñ°æ±¾µÄ¶¯Ì¬²¿Êð£¬ÊÇͬ²½µÄ£¬5.3.0µ½5.3.1µ½5.3.2£¬ÕâÑùÒ»¸öºÃ´¦ÊÇÖ»ÒªÈÝÆ÷°æ±¾Ã»ÓÐÉý¼¶£¬Ö»ÒªÓÐÐèÇó£¬patch¾Í¿ÉÒÔÒ»Ö±Éý¼¶£¬¶øÇÒÊÇÎÞ¸ÐÖªµÄ²îÁ¿Éý¼¶¡£
˵Ã÷£¬±¾²¿·ÖÀ´Ô´ÓÚÊÖÌÔ×é¼þ»¯µÄ·ÖÏí¡£¹Ù·½Á´½ÓµØÖ·
AtlasÏîĿʵ¼ù
Ç°ÃæÎÒÃǽéÉÜÁËAtlasµÄһЩÔÀíÐԵĶ«Î÷£¬×ܵÄÀ´Ëµ£¬Atlas¾ÍÊÇÀûÓÃÔ¶³ÌBundleµÄÏ·¢·½Ê½£¬ÎªÁ˼õÉÙapkµÄ°²×°Ìå»ý£¬AtlasÏîĿʹÓÃbundleµÄ¼ÓÔØ·½Ê½¡£µ±Óû§°²×°Ã»ÓÐBundleµÄapkÎļþʱ£¬¾Í´ÓÍøÉÏÏÂÔØÕâ¸öbundleµÄso£¬È»ºó¼ÓÔØ´ò¿ª£¬ÏÂÔØÂ߼ʹÓÃappÔÉú´úÂë±àд£¬¼ÓÔØÓð´Ðè¼ÓÔØµÄ²ßÂÔ¡£
Atlas½ÓÈë
Ê×ÏÈн¨Ò»¸öÏîÄ¿£¬È»ºóн¨¼¸¸ömodule£¬ÈçÏÂͼ¡£

ÐÞ¸ÄÅäÖÃ
1£¬°Ñgradle¸ÄΪ3.3
2£¬È»ºóÎÒÃÇÐèҪΪAtlasÌí¼ÓһЩÅäÖã¬ÒýÓÃAtlas²å¼þ¼°ÒÀÀµ²Ö¿â£¬Ð޸Ť³ÌgradleÎļþ¡£
buildscript {
repositories { jcenter()}
dependencies {
//²»ÐèÒªÔÙÒÀÀµclasspath "com.android.tools.build:gradle"
classpath " com.taobao.android: atlasplugin: 2.3.3.beta2"
}
} |
3£¬ÐÞ¸ÄappµÄbuild.gradle½Å±¾£¬ÐèҪעÒâ°üÃûµÄ¶ÔÓ¦¹ØÏµ¡£
// ÐèÒª·Å×îÉÏÃæ³õʼ»¯
group = "mmc.atlastest"
version = getEnvValue("versionName",
"1.0.0");
def apVersion = getEnvValue("apVersion",
"");
apply plugin: 'com.android.application'
apply plugin: 'com.taobao.atlas'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "mmc.atlastest"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName version
testInstrumentationRunner " android.support.test.runne
r.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile ('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso: espresso-core:2.2.2',
{
exclude group: 'com.android.support', module:
'support-annotations'
})
compile 'com.android.support: appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
//atlasµÄÒÀÀµ
compile('com.taobao.android:atlas_core:5.0.7@aar')
{
transitive = true
}
compile 'com.taobao.android:atlasupdate:1.1.4.7@aar'
compile 'com.alibaba:fastjson:1.1.45.android@jar'
//ÏîÄ¿ÒÀÀµ
compile project(':librarybundle')
compile project(':localbundle')
compile project(':remotebundle')
}
//¼ÓÈëÒÔÏÂÅäÖÃ
atlas {
atlasEnabled true
tBuildConfig {
// autoStartBundles = ['com.android.homebundle']
//×ÔÆô¶¯bundleÅäÖÃ
outOfApkBundles = ['remotebundle'] //Ô¶³Ìmodule£¬ÁбíÀ´µÄ£¬¿ÉÌî¶à¸ö
preLaunch = 'mmc.atlastest.AtlasLaunch' //AppApplicationÆô¶¯Ö®Ç°µ÷Óã¬Õâ¸öÀàÏÂÃæ·Å³ö´úÂë
}
patchConfigs {
debug {
createTPatch true
}
}
buildTypes {
debug {
if (apVersion) {
// ´ò²îÒì²¹¶¡ gradlew assembleDebug -DapVersion=1.1.0
-DversionName=1.1.1
// ¶ÔÓ¦×ű¾µØmaven²Ö¿âµØÖ· .m2/repository/mmc/atlastest/AP-debug/1.1.4/AP-debug-1.1.4.ap
baseApDependency "mmc.atlastest: AP-debug:${apVersion}@ap"
patchConfig patchConfigs.debug
}
}
}
}
String getEnvValue(key, defValue) {
def val = System.getProperty(key);
if (null != val) {
return val;
}
val = System.getenv(key);
if (null != val) {
return val;
}
return defValue;
}
apply plugin: 'maven'
apply plugin: 'maven-publish'
publishing {
// Ö¸¶¨²Ö¿âλÖÃ
repositories {
mavenLocal()
}
publications {
// ĬÈϱ¾µØ²Ö¿âµØÖ· Óû§Ä¿Â¼/.m2/repository/
maven(MavenPublication) {
//¶ÁÈ¡apĿ¼ÉÏ´«maven
artifact "${project.buildDir} /outputs/apk/ ${project.name}-debug.ap"
//Éú³É±¾µØmavenĿ¼
groupId group
artifactId "AP-debug"
}
}
} |
4£¬ÐÞ¸ÄÔ¶³ÌbundleºÍ±¾µØbundleµÄbuild.gradle½Å±¾
apply plugin:
'com.android.library'
apply plugin: 'com.taobao.atlas'
atlas {
bundleConfig{
awbBundle true
}
buildTypes {
debug {
baseApFile project.rootProject.file ('app/build/outputs/apk/app-debug.ap')
}
}
}
//Ö»Ìí¼ÓÉÏÃæµÄÅäÖþÍÐÐÁË£¬ÏÂÃæµÄÊÇĬÈÏÉú³ÉµÄ
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner
.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile ('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:
espresso-core:2.2.2', {
exclude group: 'com.android.support', module:
'support-annotations'
})
compile 'com.android.support: appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
//ÒÀÀµlibÖмäbundle
compile project(':librarybundle')
} |
5£¬ÔÚËÞÖ÷appµÄapplicationÖÐÌí¼ÓÈçÏ´úÂë¡£
public class
DemoApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Atlas.getInstance( ).setClassNotFoundInterceptorCallback
(new ClassNotFoundInterceptorCallback() {
@Override
public Intent returnIntent(Intent intent) {
final String className = intent.getComponent().getClassName();
final String bundleName = AtlasBundleInfoManager.instance( ).getBundleForComponet(className);
if (!TextUtils.isEmpty(bundleName) &&
!AtlasBundleInfoManager.instance( ).isInternalBundle(bundleName))
{
//Ô¶³Ìbundle
Activity activity = ActivityTaskMgr.getInstance( ).peekTopActivity();
File remoteBundleFile = new File(activity.getExternalCacheDir(), "lib"
+ bundleName.replace(".","_")
+ ".so");
String path = "";
if (remoteBundleFile.exists()){
path = remoteBundleFile.getAbsolutePath();
}else {
Toast.makeText(activity, " Ô¶³Ìbundle²»´æÔÚ£¬ÇëÈ·¶¨
: " + remoteBundleFile.getAbsolutePath()
, Toast.LENGTH_LONG).show();
return intent;
}
PackageInfo info = activity.getPackageManager(
).getPackageArchiveInfo(path, 0);
try {
Atlas.getInstance().installBundle (info.packageName,
new File(path));
} catch (BundleException e) {
Toast.makeText(activity, " Ô¶³Ìbundle °²×°Ê§°Ü£¬"
+ e.getMessage() , Toast.LENGTH_LONG).show();
e.printStackTrace();
}
activity.startActivities (new Intent[]{intent});
}
return intent;
}
});
}
} |
6¡¢ÔÚappн¨Ò»¸öÀàAtlasLaunch£¬¼Ì³ÐAtlasPreLauncher¡£
public class
AtlasLaunch implements AtlasPreLauncher {
@Override
public void initBeforeAtlas(Context context)
{
}
} |
ÏîÄ¿½á¹¹
È»ºóдappµÄ»ù±¾¹¦ÄÜ£¬Ê¾ÀýÈçÏÂͼ¡£

ÏÂÃæÊÇËÞÖ÷ÖоßÌåµÄÌø×ªÂ߼ʵÏÖ¡£
public class
MainActivity extends BaseActivity {
@Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate (savedInstanceState);
setContentView(R.layout.activity_main);
}
//´ò¿ªÔ¶³Ìbundle
public void remote (View view){
Intent intent = new Intent();
intent.setClassName(view.getContext(), "mmc.remotebundle.RemoteActivity");
startActivity(intent);
}
//´ò¿ª±¾µØbundle
public void local(View view){
Intent intent = new Intent();
intent.setClassName(view.getContext(), "mmc.localbundle.LocalActivity");
startActivity(intent);
}
//¸üв¹¶¡
public void update(View view){
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids)
{
update();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
Toast.makeText(MainActivity.this, "¸üÐÂÍê³É£¬ÇëÖØÆô",
Toast.LENGTH_LONG).show();
}
}.execute();
}
private void update(){
File updateInfo = new File (getExternalCacheDir(),
"update.json");
if (!updateInfo.exists()) {
showToast("¸üÐÂÐÅÏ¢²»´æÔÚ£¬ ÇëÏÈ Ö´ÐÐ buildTpatch.sh");
return;
}
String jsonStr = new String (FileUtils.readFile(updateInfo));
UpdateInfo info = JSON.parseObject (jsonStr,
UpdateInfo.class);
File patchFile = new File (getExternalCacheDir(),
"patch-" + info.updateVersion + "@"
+ info.baseVersion + ".tpatch");
try {
AtlasUpdater.update(info, patchFile);
} catch (Throwable e) {
e.printStackTrace();
showToast("¸üÐÂʧ°Ü, " + e.getMessage());
}
}
} |
°²×°ÔËÐÐÏîÄ¿£¬¾Í¿ÉÒÔ¿´µ½ÈçÏÂͼËùʾµÄЧ¹û¡£

´Ëʱ»¹ÓÐÒÔϹ¤¾ßÐèÒªÍê³É£º
1£¬Õâ¸öʱºòµã»÷Ô¶³Ìbundle»áµ¯³ö˵ûÓÐsoÎļþ£¬ÒòΪ»¹Ã»´òso°üÄØ
2¡¢µã»÷±¾µØbundle£¬ÊÇ¿ÉÒÔÌø×ªµ½ÄǸö±¾µØbundleÒ³Ãæ
3¡¢µã»÷¸üв¹¶¡£¬»áÌáʾ¸üÐÂÐÅÏ¢²»´æÔÚ
´òÔ¶³ÌbundleµÄsoÎļþ
ÏÂÃæÒª´ò°ü³öÔ¶³ÌbundleµÄsoÎļþ£¬²¹¶¡µÄ²îÒì°üºÍ¸üÐÂ˵Ã÷¡£
1£¬´òsoÎļþ£¬Ã¿¸öÔ¶³Ì¶¼»áÉú³ÉÒ»¸ösoÎļþµÄ¡£´ò¿ªASµÄTerminal£¬ÊäÈ룺gradlew
clean assembleDebug publish
£¬È»ºó»Ø³µ£¬ÈçÏÂͼ£º

Õý³£µÄ»°£¬»áÌáʾÏÂÃæµÄÕýÈ·ÐÅÏ¢¡£

³É¹¦µÄ»°£¬appµÄbuildÎļþ¼ÐÀ»áÉú³ÉÕâ¸ösoÎļþ£¬Õâ¸ö¾ÍÊÇÔ¶³ÌbundleµÄsoÎļþ£¬°ÑÕâ¸öÎļþ·Åµ½ÊÖ»úÄڴ濨Android/data/mmc.atlastest/cache
Îļþ¼ÐÀïÃæ£¬È»ºóÔÙ´ò¿ªapp£¬µã»÷¡°Ô¶³ÌBundle¡±£¬Õâ¸öʱºò¾ÍÄÜÌø×ª¹ýÈ¥ÁË¡£

¸üв¹¶¡£¬´ò²îÒì°üºÍ¸üÐÂ˵Ã÷
½Ó×ŵÚÒ»²½£¬È»ºóÐ޸İ汾ºÅ£¬¶Ô±¾µØBundle½øÐÐÎÄ×ÖÐ޸쬶ÔappÖ÷ÏîĿҲ¿ÉÒÔÐ޸ġ£

Ð޸ĺó£¬ÔÚTerminalÀïÃæÊäÈ룺gradlew clean assembleDebug -DapVersion=1.0.0
-DversionName=1.0.1
»Ø³µ£¬³É¹¦ºó»áÉú³É²¹¶¡²îÒì°üºÍ¸üÐÂ˵Ã÷£¬ÈçÏÂͼ£º

°ÑºìɫȦÖеÄÁ½¸öÎļþ£¬·Åµ½ÊÖ»úÄڴ濨Android/data/ mmc.atlastest/cache
Îļþ¼ÐÀïÃæ£¬È»ºóµã»÷¡°¸üв¹¶¡¡±£¬¹ýÒ»»á£¬Ìáʾ¸üгɹ¦ºó£¬¾ÍÍ˳öɱËÀapp£¬ÔÙ´ò¿ª¾ÍÊǺóÃæÐ޸ĵÄÄÚÈÝÁË¡£
AtlasʹÓò½Öè×ܽá
1¡¢ÅäÖú㬰²×°1.0.0µÄapp
2¡¢ÓÃÃüÁî¡°gradlew clean assembleDebug publish¡±´òAP£¬µÃµ½Ô¶³ÌBundleµÄsoÎļþ
3¡¢Ð޸İ汾ºÅ£¬Ð޸İ汾ÄÚÈÝ
4¡¢ÓÃÃüÁî¡°gradlew clean assembleDebug -DapVersion=1.0.0
-DversionName=1.0.1¡±´ò²îÒì°ü²¹¶¡ºÍ¸üÐÂ˵Ã÷
5¡¢°ÑÉÏÃæµÃµ½µÄÈý¸öÎļþ·Åµ½appµÄcacheĿ¼ÀïÃæ
6¡¢ÔËÐиüз½·¨£¬É±ËÀapp£¬ÖØÆô
|