Android Hotfix 新方案——Amigo 源码解读
g e n e r o u s 推 荐 算 法
Github Android流行框架Top100GitHub Android Libraries Top 100 简介感谢 @GitHubDaily 与 @Android 开发日常的大力支持, 以及@stormzhang 的指点若有任何疑问可通过邮件或微博联系我项目名称项目简介react-native这个是 Facebook 在 React.js Conf 2015 大会上推出的基于JavaScript 的开源框架 React Native, 该框架结合了 Web 应用和Native 应用的优势, 可以使用JavaScript 来开发iOS 和Android 原生应用2.Android-Universal-Image-LoaderImageLoader 是最早开源的 Android 图片缓存库, 强大的缓存机制, 早期被广泛 Android 应用使用, 至今仍然有很多 Android 开发者在使用RxJava 是一个在 Java VM 上使用可观测的序列来组成异步的, 基于事件的程序的库, 简单来说它就是一个实现异步操作的库, RxJava 的优点在于一个词“简洁”, 使用它就算你程序逻辑有多么复杂, 它依然能够保持简洁易懂retrofitRetrofit 是Square 公司出品的HTTP 请求库, 同时是Square 是最早开源项目之一, Retrofit 是目前 Android 最流行的Http Client 库之一, 目前版本是 Retrofit2.0 Beta4, 越来越多Android 开发者开始使用这个请求库了OkHttp 是 Square 公司出品的 HTTP 另一个请求库, Google 不推荐人们使用 HttpClient, 可是 HttpURLConnection 实在是太难用了, 因此很多人使用了OkHttp 来解决这问题, 据说Android4.4 的源码中可以看到 HttpURLConnection 已经替换成OkHttp 实现呢SlidingMenu(不建议使用)一个侧滑菜单开源库, 在 Google 自己原生态的侧滑菜单NavigationDrawer 没有出现之前, 这个库就已经被广泛使用, 可是到现在这个库已经被放弃了Picasso 是 Square 公司出品的一款图片缓存库, 主导者是JakeWharton 大神android-best-practicesAndroid 开发最佳实践, 里面所介绍的经验都是来自于Futurice 公司 Android 开发者, 介绍内容有 Android 开发规范, 架构, 布局技巧, 以及使用一些有助于快速开发相关工具等等, 非常适合新手去学习EventBusEventBus 是Android 事件管理总线, 使用它可以替带Android BroadCast, BroadCastReceiver, Handler 在 Activity, Fragment, Service, 线程之间传递消息, 大大简化了事件传递逻辑 Fresco 是 FaceBook 公司出品的一款图片缓存库, Fresco 是一个强大的图片加载组件, 支持加载 Gif 图和 WebP 格式, 支持Android2.3(API level 9) 及其以上系统, Fresco 中设计了 Image pipeline 和 Drawees 两个模块各施其职, 使得图片完美加载出来, 想知道更多 image pipeline 和 Drawees 有关于它的特性, 可以到它官方平台看介绍ZXing 是二维码领域中名气最大的开源项目, 它提供了多个平台的二维码-条形码扫描解决方案, 拥有扫描快, 识别率高, 使用简单等特点leakcanaryLeakCanary 是 Square 公司出的一款检测内存泄露工具, 该工具能帮助你在开发阶段方便的检测出内存泄露的问题, 使用起来非常简单方便butterknife由 JakeWharton 大神开发出来的, ButterKnife 是 View 注入框架, 使用它为了简写很多 findViewById 代码, 同时还支持 View 的一些事件处理函数MPAndroidChartMPAndroidChart 是一款强大的 Android 图表库, 支持各种各样图表显示, 能想到的图表样式这里几乎都有, 图表还支持选择,拖放和缩放动画效果ActionBarSherlock (不建议使用)androidannotationsAndroidAnnotations 是一个能够让你快速进行 Android 开发的开源框架, 它能让你专注于真正重要的地方, 使代码更加精简, 使项目更加容易维护, 它的目标就是“Fast Android Development.Easy maintainanc e”ViewPagerIndicator由 JakeWharton 大神开发出来的一个 ViewPager 指示器, 使用起来简单方便, 可高度定制, 开发出各种各样动画效果 Glide 是 Google 员工的开源项目, 广泛应用于 Google 一些App 上, 在2014年 Google I-O 大会上被推荐使用, Glide 和Picasso 被人拿来比较研究过, Glide 与 Picasso 有 90% 的相似度, 但在一些细节上还是有点区别的, 各有各优缺点看君选择HomeMirror开发者是由一名程序媛 Hannah Mittelstaedt , HomeMirror 是一款 Android 镜子应用, 目前它能实现日期, 时间, 天气, 生日信息, 事件提醒器, 骑车天气的推荐, 股票信息, XKCD 漫画网站的新帖等等Android-PullToRefresh(不建议使用)一个强大的拉动刷新开源项目, 支持各种控件下拉刷新, ListView, ViewPager, WebView, ExpandableListView, GridView,ScrollView, Horizontal ScrollView, Fragment 上下左右拉动刷新, 不过现在这个项目已经停止维护更新了, 推荐使用Android-Ultra-Pull-To-RefreshMaterialDesignLibrary这个库控件都是遵循了 Google Material Design 设计规范开发出来, 例如有: Flat Button, Rectangle Button, CheckBox, Switch, Progress bar circular indeterminate 等等PhotoViewPhotoView 是 ImageView 的子类, 支持所有 ImageView 的源生行为, 例如: 支持 Pinch 手势自由缩放, 支持双击放大-还原, 支持平滑滚动等等, 并且非常方便的与 ImageLoader-Picasso 之类的网络图片读取库集成使用, 还方便的与 ViewPager 等同样支持滑动手势的控件集成RxAndroid由 JakeWharton 大神主导开发的项目, RxAndroid 是 RxJava 的一个针对 Android 平台的扩展, 主要用于 Android 开发material-dialogsMaterial Dialogs 是一个可高度定制易用, 符合 Material Design 风格的 Dialogs, 兼容 Android API8 以上版本, 个人使用感觉它完全可替代 Android 原生那个, 比原生那个更加简单易用26.Android-ObservableScrollViewObservableScrollView 是一款用于在滚动视图中观测滚动事件的 Android 库, 它能够轻而易举地与 Android 5.0 Lollipop 引进的工具栏(Toolbar) 进行交互, 还可以帮助开发者实现拥有Material Design 应用视觉体验的界面外观, 支持ListView, ScrollView, WebView, RecyclerView, GridView组件Android-BootstrapAndroid 版的Bootstrap, 利用这个库能够实现很多Bootstrap 样式风格, 之前有学过 Html 的人就知道 Bootstrap 是什么玩意啦AndroidSwipeLayout开发者是代码家, AndroidSwipeLayout 是一个支持ListView, GridView, ViewGroup等等左右上下滑动出操作菜单, 类似 qq 消息列表向左滑动显示出多某条信息的操作菜单Dagger 是 Square 公司出品的一个针对 Android 和 Java 的快速依赖注入器, 能够有效减少你敲代码量ListViewAnimations一个轻轻松松给 Android ListView 添加动画效果的库, 支持的动画有: Alpha, SwingRightIn, SwingLeftIn, SwingBottomIn, SwingRightIn and ScaleIn等等, 使用它能很容易就实现帅爆的效果PagerSlidingTabStrip(不建议使用)PagerSlidingTabStrip 是一个给 Android ViewPager添加上ViewPager 滑动指示器, 从 GitHub 上面看, 这个库似乎没有人在维护了, 因此不建议使用, 可使用 SmartTabLayout 来代替AndroidViewAnimations开发者是代码家, 这个库实现很多很酷炫的 Android 动画, 动画效果是借鉴 Animate.css 来实现的, 非常酷, 而且这个使用起来也是非常简单AndroidSlidingUpPanelAndroidSlidingUpPanel 是一个上拉面板, 就是向上滑动的时候往上飞出一个显示面板控件, 该库效果在 Google Music, Google Maps and Rdio等 App 应用到MaterialDrawerMaterialDrawer 是一个类似 Google 官方 NavigationView 侧滑显示控件, 个人认为 NavigationView 并没有 MaterialDrawer 实用, 因为 NavigationView 自由度不是很好, 很多都写死了不可以自由定义布局, 而 MaterialDrawer 能够实现跟 NavigationView 一样的效果, 同时还支持自定义效果, 自由度非常高Material-AnimationsMaterial-Animations 是一个很好过渡动画库, 可以应用于Activity 与 Activity 之间的跳转, Fragment 与 Fragment 之间的跳转, 以及各个 View 变化前后的过渡动画MaterialViewPager一个简单易用 Material Design 风格的 ViewPager 库fastjsonFastjson 是一个 Java 语言编写的高性能功能完善的 JSON 库. 它采用一种“假定有序快速匹配”的算法, 把 JSON Parse的性能提升到极致, 是目前Java语言中最快的JSON库. Fastjson接口简单易用, 已经被广泛使用在缓存序列化, 协议交互, Web输出, Android 客户端等多种应用场景cardslib (不建议使用)Cardslib 是早期由 Gabriele Mariotti 开发的一个为开发者方便实现各种 Card UI 的 Android 开源代码库, 后来 Google 官方提供自己封装了 CardView 在 v7 包下, 使用 Google 官方的可以完全替代了这个库, 因此这个也被弃用了Android-Ultra-Pull-To-Refresh开发者是廖祜秋, 这个是一个非常强大的下拉刷新库, 继承ViewGroup 可以包含任何 View, 功能甚至比 SwipeRefreshLayout 强大, 使用起来也非常容易, 还可以自由定制自己的 UI 样式greenDAOgreenDAO 是一个可以帮助 Android 开发者快速将 Java 对象映射到 SQLite 数据库的表单中的 ORM解决方案, 通过使用一个简单的面向对象 API, 开发者可以对 Java 对象进行存储, 更新, 删除和查询, greenDAO 相对 OrmLite, AndrORM 这两个 ORM 开源库, 性能是最高的AndroidStaggeredGridAndroidStaggeredGrid 是一个支持多列并且每一行的 item 大小不一, 交错排列的 GridView, 就是实现瀑布流样式效果, 目前该库已经被弃用了, 开发者建议我们使用Google 官方控件RecyleView 中的 StaggeredGridLayoutManager 布局来实现瀑布流效果Otto 是 Square 公司出的一个事件库 (pub-sub 模式), 用来简化应用程序组件之间的通讯, otto 修改自 Google 的 Guava 库, 专门为 Android 平台进行了优化, 与上面介绍的 EventBus 相比, 两个库各有各的优点, 完全取决于我们自己项目的需求来选择它们哪一个xUtils 是一个快速开发框架, 里面包含 DbUtils, ViewUtils, HttpUtils, BitmapUtils 四大模块, 可用于快速开发, 支持大文件上传, 拥有更加灵活的 ORM, 最低兼容 Android 2.2realm-javaRealm 一个轻量的 Android 版本的数据存储库, 比 Android 原生系统的 SQLite 更加简洁快速对数据进行操作47.Android-CleanArchitectureCleanArchitecture 是一个非常典型使用 MVP 架构的项目, 大家如果还没有理解 MVP 架构的可以看看这个项目StickyListHeadersStickyListHeaders 是一个实现能够固定在屏幕顶部的ListView Section Header库, 就是当前 section 的 header 固定在屏幕顶部, 当滑动到其他 section 时, 其他 section 的 header会代替之前的section 的header, 固定到屏幕顶部, 类似于Android4.0 的手机通讯录的效果AppIntroAppIntro 是一个让人轻松快速搭建漂亮酷炫的引导页库ActiveAndroidActiveAndroid 是采用Rails中的 Active Record架构模式设计的适用于 Android 平台的轻量级 ORM 架构, 几乎可以不用写任何 SQL 代码实现快速开发android-volleyVolley 是谷歌官方开发团队在 2013 年 Google I-O 大会推出的一个新的网络通信框架, 这个框架把AsyncHttpClient 和Universal-Image-Loader 的优点集于了一身,既可以像AsyncHttpClient 一样非常简单地进行HTTP 通信,也可以像Universal-Image-Loader 一样轻松加载网络上的图片, 这个库并不是官方的, 只是托管同步在 Maven, 官方只提供的 Jar 包twoway-viewTwoWayView 是简化 RecyclerView 开发的一个库, 可以在其Base LayoutManager 基础上构建各种各样的布局, 该库内置了几个常用布局 List, Grid, Staggered Grid,Spannable Grid ShowcaseViewShowcaseView 是一个非常适合用于对用户进行第一次使用进行指导的库,使用起来非常简单还可以自定义样式CalligraphyCalligraphy 是一个用来简化 Android 应用使用自定义字体的类库, 该类库会自动查找应用中的 TextView 并设置其使用的字体NineOldAndroidsNineOldAndroids 由 JakeWharton 大神开发的一个向下兼容的动画库, 主要是使低于API 11的系统也能够使用 View 的属性动画, 不过现在 JakeWharton 大神已经不推荐使用该库, 而是推荐我们使用官方封装在 Support 库里面的动画android-floating-action-buttonFloatingActionButton 是一个悬浮操作按钮, 官方在 Support Design 包下也有封装一个类似这个库效果的FloatingActionButton, 值得说明的是这个库是早在官方封装之前就存在的, 个人感觉这个库比官方那个更加好用CircleImageViewCircleImageView 是一个轻松帮你实现圆形效果 ImageView 图片库, CircleImageView 是基于 ImageView 扩展出来, 因此它拥有ImageView 控件所有属性, 简单易用值得你使用的库materialMaterial 是将 Material Design 风格控件封装在该库当中, 目前封装有Progress, Button, Switch, Slider, Spinner, Text Field, TabPageIndicator, SnackBar, Dialog, BottomSheetDialog, Dynamic themeActionBar-PullToRefreshActionBar-PullToRefresh 是一个下拉刷新, 下拉刷新时在ActionBar 出现加载中提示的库FloatingActionButton又一个悬浮操作按钮库, 该库添加支持监听滑滚动事件, 当向下滑时按钮隐藏, 向上滑时按钮显示, 还有动画效果, 支持监听ListView, ScrollView, RecylerViewAndroidAsyncRebound 是 Facebook 推出的一个弹性动画库, 可以让动画看起来真实自然, 像真实世界的物理运动, 带有力的效果, 使用的参数则是 Facebook 的 origami 中使用的android-commonandroid-common-lib 是 Trinea 大神收集的一些开发通用的缓存, 公共 View 以及一些常用工具类RippleEffectRippleEffect 是一个实现在Android 任何组件点击出现Material Design 的波纹效果, 向下兼容到 Android API9 SmoothProgressBarSmoothProgressBar 是一个帮你的 App 方便实现可定制, 平滑动画的水平滚动进度条库recyclerview-animatorsRecyclerView Animators 是一个对 Recycler 控件的 Item 添加以及删除增加动画效果, 动画效果有Scale, Fade, Flip, Slide 里面各种各样效果circular-progress-button一个带进度显示的 Button, 效果和动画做的都非常赞DroidPluginDroidPlugin 是 360 手机助手在 Android 系统上实现了一种新的插件机制: 它可以在无需安装, 修改的情况下运行APK文件, 此机制对改进大型APP的架构, 实现多团队协作开发具有一定的好处dynamic-load-apkExoPlayerExoPlayer 是Google 开发团队开源出来的一个媒体播放库, 比Android 框架原生的 MediaPlayer 拥有更多优点支持动态的自适应流 HTTP(DASH) 和平滑流, 支持高级的HLS特性, 支持自定义和扩治你的使用场景等等Crouton (不建议使用)Crouton 是一个显示提示信息的显示工具类, 可以用来代替Toast, 默认显示在窗口的顶部, 可以按队列一个接着一个显示, 不过该库已经被弃用, 不推荐使用robospiceRoboSpice 是一个使你建立异步的长时间的运行任务异常轻松的一个网络库,在网络请求,缓存支持,和提供开箱即用的 rest 请求方面尤为强大Hugo 是 JakeWharton 大神推出的一个用于打印 Log, hugo 是基于注解被调用的, 引入相关依赖后, 在方法上加上 @DebugLog 即可输出 Log, 使用非常简单AsyncHttpClient 是又一款 Android 异步请求库, 该库支持WebSocket 协议, 使用起来也比较简单易用UltimateRecyclerViewUltimateRecyclerView 是一个功能强大的RecyclerView(advanced and flexible version of ListView), 包括了下拉刷新, 加载更多, 多种动画, 空数据提示, 拖动排序, 视差处理, 工具栏渐变, 滑动删除, 自定义floating button, 多种刷新效果, scrollbar, sticky header, 多 layout 支持等等元素, 而且使用起来跟 RecyclerView 一样的方便MaterialEditTextMaterialEditText 是就职于 Flipboard 的员工扔物线开发的, 在AppCompat v21 中也提供了Material Design 的控件EditText, 可是由于比较难用, 没有提供设置颜色的 Api, 于是就产生这个第三方库Side-Menu.AndroidSide Menu 是 Yalantis 组织开源出来, 该组织因开源出一些动画很棒的开源库为大家所熟知该库是其中一个, 该库是提供翻页动画效果的侧边菜单, 动画体验超赞的drag-sort-listviewandroid-times-squareTimesSquare 是 Square 公司出品的一款显示日历选择日期的控件, 可以让用户选择多个日期GreenDroid(不建议使用)GreenDroid 是一个封装好的 Android UI 界面库, 不过该库已经被弃用了, 不建议使用Logger 是一个简单, 漂亮, 强大 Android 打印日志库Acra 是一个能够让 Android 应用自动将崩溃报告以谷歌文档电子表的形式进行发送的库, 旨在当应用发生崩溃或出现错误行为时, 开发者可以获取到相关数据FadingActionBarFadingActionBar 是一个支持 ListView, ScrollView, WebView 向下滚动时逐渐显示 ActionBar 库AndroidImageSliderAndroidImageSlider 库开发者是代码家, 该库是为 Banner 图片滑动提供多种动画效果, 还可以轻易为 Banner 加载网络图片SystemBarTintSystemBarTint 是一个实现沉浸式状态栏库, 适用于 Android 系统 4.4 其以上的版本android-menudrawerMenuDrawer 是一款滑出式菜单库, 通过拖动屏幕边缘滑出菜单,支持屏幕上下左右划出, 支持当前View 处于上下层, 支持Windows 边缘, ListView 边缘, ViewPager 变化划出菜单等RoundedImageViewRoundedImageView 一个快速支持图片圆角显示效果的库, 该库特点是能快速加载, 为了提高加载速度, 该库不用创建原始位图的副本, 不使用 clipPath, 不使用 setXfermode 裁剪的位图等方式来实现 ImageView 圆角, 使用也非常简单android-pulltorefresh(不建议使用)另一个下拉刷新库, 但是该库已经停止维护, 因此不建议使用, 推荐使用 Android-Ultra-Pull-To-RefreshBolts-AndroidBolts 是一款底层类库集合, 在后台实现异步操作, 并提供接口反馈当前异步执行的程度 (可以通过接口实现UI进度更新), 最后反馈执行的结果给UI主线程, 与AsyncTask比较: (1)使用的是无大小限制的线程池; (2)任务可组合可级联,防止了代码耦合NumberProgressBarNumberProgressBar 开发者是代码家, 这是一个带简约性感数字显示的进度条库, 使用非常简单方便SwipeBackLayoutSwipeBackLayout 是一个支持屏幕上下左右滑动返回上层Activity, 关闭当前 Activity, 类似简书 Appandroid-gif-drawable一个支持 gif 显示的 view, 用 jni 实现的, 编译生成 so 库后直接 xml 定义 view 即可, 简单易用VitamioBundleVitamio 是一款 Android 与 iOS 平台上的全能多媒体开发框架, 特点:(1) 全面支持硬件解码与 GPU 渲染, (2) 能够流畅播放720P 甚至 1080P 高清 MKV, FLV, MP4, MOV, TS, RMVB 等常见格式的视频, (3) 在 Android 与 iOS 上跨平台支持 MMS, RTSP, RTMP, HLS(m3u8)等常见的多种视频流媒体协议, 包括点播与直播SmartTabLayoutSmartTabLayout 是一个自定义的Tab title strip, 基于Google Samples 中的android-SlidingTabBasic 项目, 滑动时Indicator 可平滑过渡uCrop 是Yalantis 组织开源的图片裁剪库, 支持缩放, 旋转图片, 支持各种比例的裁剪框, 非常强大的一个图片裁剪库android-crop又一个图片裁剪库, 向下兼容到 Api 10, 个人感觉这个库并没有比上面介绍的 uCrop 强大HoloEveryWhereHoloEveryWhere 是一套 Android 开发库, 提供了全套 Holo Style 控件, 它的外观与功能和标准 Holo Style 控件基本相同, 唯一不同的是它可以运行在低于 4.0 版本的 Android 系统上AVLoadingIndicatorViewAVLoadingIndicatorView 库含有各种各样漂亮的加载动画效果, 使用起来也非常简单, 和平时使用 ProgressBar 一样sweet-alert-dialogSquare 公司占有 7 席项目名称RetrofitLeakCanaryTimesSquareFaceBook 公司占有 4 席项目名称React NativeJakeWharton 大神占有 5 席项目名称Butter KnifeActionBarSherlockViewPagerIndicatorNineOldAndroids代码家大神占有 4 席项目名称AndroidSwipeLayoutAndroidViewAnimationsAndroidImageSlideNumberProgressBar感谢所有为开源而辛辛苦苦付出努力的人, 相信有你们 Android 会发展的更加美好, 让我们一起为他们辛辛苦苦付出的努力鼓掌吧!使用默认参数,点击ok,回到主窗口。
android-recovery
#设置环境变量 #建立etc连接 #新建目录 #挂载/tmp为内存文件系统tmpfs #开启recovery(/sbin/recovery)服务 #开启adbd服务(用于调试)
三、Recovery
2. recovery服务
recovery服务是Recovery开启模式中最关键旳部分。它完毕 Recovery模式全部旳工作。
1.ui_init():Recovery服务使用了一种基于framebuffer旳简朴ui。 2.get_arg():获取Main system 传递给Recovery服务参数 3.parserargc/argv:解析我们取得参数。 4.根据参数分析旳成果,进一步分析是否升级,是否wipe等。 5.假如安装失败执行: prompt_and_wait()待顾客处理。 6.安装成功执行: finish_recovery(),清除参数,以及备份升级log
规避措施成为砖头措施:
1.在升级包中不包括uboot,recovery镜像,使在升级过程断电旳 情况下,也不会损坏uboot,和recovery。能够使用双备份升级 和一键恢复升级方式,进行恢复升级。
2.在升级包中不包括uboot,使在升级过程断电旳情况下,也不会 损坏uboot,。能够使用一键恢复升级方式从外部存储设备加载 recovery,进行恢复升级。
四、全包升级与差分升级
全包升级与差分升级包旳升级过程都是zip文件旳升级过 程。所以升级旳流程是一样旳,唯一不同旳地方就是从 升级包中提取升级脚本旳不同,执行不同旳升级过程。
#如: 全包升级脚本中包括格式化system分区旳语句,差分升级则没有
android gesturedetector原理 -回复
android gesturedetector原理-回复Android GestureDetector 原理及使用Android 提供了GestureDetector 类来帮助开发者实现手势识别功能。
本文将详细介绍GestureDetector 的原理和使用方法。
一、GestureDetector 原理GestureDetector 是Android 框架为开发者封装的一个手势识别工具类。
它可以用来监听和处理用户的触摸手势事件,如滑动、点击、长按等。
GestureDetector 使用了事件监听器的设计模式,通过回调方法通知开发者触摸手势的开始、结束、移动等事件。
在Android 中,触摸手势是由MotionEvent 对象来表示的。
MotionEvent 包含了触摸事件的详细信息,如触摸的坐标、触摸的时间、触摸的压力等。
GestureDetector 利用MotionEvent 对象中的信息来判断用户的手势操作。
在GestureDetector 的实现中,主要使用了以下几个方法:1. onDown(MotionEvent e):当用户按下屏幕时调用,返回值表示是否消耗该事件。
2. onShowPress(MotionEvent e):当用户按下屏幕后未松开时调用。
3. onSingleTapUp(MotionEvent e):当用户手指离开屏幕并且没有发生滑动操作时调用,返回值表示是否消耗该事件。
4. onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):当用户滑动屏幕时调用。
5. onLongPress(MotionEvent e):当用户长按屏幕时调用。
6. onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):当用户快速滑动屏幕时调用。
android源码分析精典
Android 2.1 源码结构分析leeAndroid 2.1|-- Makefile|-- bionic (bionic C库)|-- bootable (启动引导相关代码)|-- build (存放系统编译规则及generic等基础开发包配置)|-- cts (Android兼容性测试套件标准)|-- dalvik (dalvik JAVA虚拟机)|-- development (应用程序开发相关)|-- external (android使用的一些开源的模组)|-- frameworks (核心框架——java及C++语言)|-- hardware (主要保护硬解适配层HAL代码)|-- out (编译完成后的代码输出与此目录)|-- packages (应用程序包)|-- prebuilt (x86和arm架构下预编译的一些资源)|-- sdk (sdk及模拟器)|-- system (文件系统库、应用及组件——C语言)`-- vendor (厂商定制代码)bionic 目录|-- libc (C库)| |-- arch-arm (ARM架构,包含系统调用汇编实现)| |-- arch-x86 (x86架构,包含系统调用汇编实现)| |-- bionic (由C实现的功能,架构无关)| |-- docs (文档)| |-- include (头文件)| |-- inet (?inet相关,具体作用不明)| |-- kernel (Linux内核中的一些头文件)| |-- netbsd (?nesbsd系统相关,具体作用不明)| |-- private (?一些私有的头文件)| |-- stdio (stdio实现)| |-- stdlib (stdlib实现)| |-- string (string函数实现)| |-- tools (几个工具)| |-- tzcode (时区相关代码)| |-- unistd (unistd实现)| `-- zoneinfo (时区信息)|-- libdl (libdl实现,dl是动态链接,提供访问动态链接库的功能)|-- libm (libm数学库的实现,)| |-- alpha (apaha架构)| |-- amd64 (amd64架构)| |-- arm (arm架构)| |-- bsdsrc (?bsd的源码)| |-- i386 (i386架构)| |-- i387 (i387架构?)| |-- ia64 (ia64架构)| |-- include (头文件)| |-- man (数学函数,后缀名为.3,一些为freeBSD的库文件)| |-- powerpc (powerpc架构)| |-- sparc64 (sparc64架构)| `-- src (源代码)|-- libstdc++ (libstdc++ C++实现库)| |-- include (头文件)| `-- src (源码)|-- libthread_db (多线程程序的调试器库)| `-- include (头文件)`-- linker (动态链接器)`-- arch (支持arm和x86两种架构)bootable 目录.|-- bootloader (适合各种bootloader的通用代码)| `-- legacy (估计不能直接使用,可以参考)| |-- arch_armv6 (V6架构,几个简单的汇编文件)| |-- arch_msm7k (高通7k处理器架构的几个基本驱动)| |-- include (通用头文件和高通7k架构头文件)| |-- libboot (启动库,都写得很简单)| |-- libc (一些常用的c函数)| |-- nandwrite (nandwirte函数实现)| `-- usbloader (usbloader实现)|-- diskinstaller (android镜像打包器,x86可生产iso)`-- recovery (系统恢复相关)|-- edify (升级脚本使用的edify脚本语言) |-- etc (init.rc恢复脚本)|-- minui (一个简单的UI)|-- minzip (一个简单的压缩工具)|-- mtdutils (mtd工具)|-- res (资源)| `-- images (一些图片)|-- tools (工具)| `-- ota (OTA Over The Air Updates升级工具) `-- updater (升级器)build目录.|-- core (核心编译规则)|-- history (历史记录)|-- libs| `-- host (主机端库,有android “cp”功能替换)|-- target (目标机编译对象)| |-- board (开发平台)| | |-- emulator (模拟器)| | |-- generic (通用)| | |-- idea6410 (自己添加的)| | `-- sim (最简单)| `-- product (开发平台对应的编译规则)| `-- security (密钥相关)`-- tools (编译中主机使用的工具及脚本)|-- acp (Android "acp" Command)|-- apicheck (api检查工具)|-- applypatch (补丁工具)|-- apriori (预链接工具)|-- atree (tree工具)|-- bin2asm (bin转换为asm工具)|-- check_prereq (检查编译时间戳工具)|-- dexpreopt (模拟器相关工具,具体功能不明)|-- droiddoc (?作用不明,java语言,网上有人说和JDK5有关)|-- fs_config (This program takes a list of files and directories)|-- fs_get_stats (获取文件系统状态)|-- iself (判断是否ELF格式)|-- isprelinked (判断是否prelinked)|-- kcm (按键相关)|-- lsd (List symbol dependencies)|-- releasetools (生成镜像的工具及脚本)|-- rgb2565 (rgb转换为565)|-- signapk (apk签名工具)|-- soslim (strip工具)`-- zipalign (zip archive alignment tool)dalvik目录 dalvik虚拟机.|-- dalvikvm (main.c的目录)|-- dexdump (dex反汇编)|-- dexlist (List all methods in all concrete classes in a DEX file.)|-- dexopt (预验证与优化)|-- docs (文档)|-- dvz (和zygote相关的一个命令)|-- dx (dx工具,将多个java转换为dex)|-- hit (?java语言写成)|-- libcore (核心库)|-- libcore-disabled (?禁用的库)|-- libdex (dex的库)|-- libnativehelper (Support functions for Android's class libraries)|-- tests (测试代码)|-- tools (工具)`-- vm (虚拟机实现)development 目录(开发者需要的一些例程及工具)|-- apps (一些核心应用程序)| |-- BluetoothDebug (蓝牙调试程序)| |-- CustomLocale (自定义区域设置)| |-- Development (开发)| |-- Fallback (和语言相关的一个程序)| |-- FontLab (字库)| |-- GestureBuilder (手势动作)| |-- NinePatchLab (?)| |-- OBJViewer (OBJ查看器)| |-- SdkSetup (SDK安装器)| |-- SpareParts (高级设置)| |-- Term (远程登录)| `-- launchperf (?)|-- build (编译脚本模板)|-- cmds (有个monkey工具)|-- data (配置数据)|-- docs (文档)|-- host (主机端USB驱动等)|-- ide (集成开发环境)|-- ndk (本地开发套件——c语言开发套件)|-- pdk (Plug Development Kit)|-- samples (例程)| |-- AliasActivity (?)| |-- ApiDemos (API演示程序)| |-- BluetoothChat (蓝牙聊天)| |-- BrowserPlugin (浏览器插件)| |-- BusinessCard (商业卡)| |-- Compass (指南针)| |-- ContactManager (联系人管理器)| |-- CubeLiveWallpaper (动态壁纸的一个简单例程)| |-- FixedGridLayout (像是布局)| |-- GlobalTime (全球时间)| |-- HelloActivity (Hello)| |-- Home (Home)| |-- JetBoy (jetBoy游戏)| |-- LunarLander (貌似又是一个游戏)| |-- MailSync (邮件同步)| |-- MultiResolution (多分辨率)| |-- MySampleRss (RSS)| |-- NotePad (记事本)| |-- RSSReader (RSS阅读器)| |-- SearchableDictionary (目录搜索)| |-- SimpleJNI (JNI例程)| |-- SkeletonApp (空壳APP)| |-- Snake (snake程序)| |-- SoftKeyboard (软键盘)| |-- Wiktionary (?维基)| `-- WiktionarySimple(?维基例程)|-- scripts (脚本)|-- sdk (sdk配置)|-- simulator (?模拟器)|-- testrunner (?测试用)`-- tools (一些工具)external 目录.|-- aes (AES加密)|-- apache-http (网页服务器)|-- astl (ASTL (Android STL) is a slimmed-down version of the regular C++ STL.)|-- bison (自动生成语法分析器,将无关文法转换成C、C++)|-- blktrace (blktrace is a block layer IO tracing mechanism)|-- bluetooth (蓝牙相关、协议栈)|-- bsdiff (diff工具)|-- bzip2 (压缩工具)|-- clearsilver (html模板系统)|-- dbus (低延时、低开销、高可用性的IPC机制)|-- dhcpcd (DHCP服务)|-- dosfstools (DOS文件系统工具)|-- dropbear (SSH2的server)|-- e2fsprogs (EXT2文件系统工具)|-- elfcopy (复制ELF的工具)|-- elfutils (ELF工具)|-- embunit (Embedded Unit Project)|-- emma (java代码覆盖率统计工具)|-- esd (Enlightened Sound Daemon,将多种音频流混合在一个设备上播放)|-- expat (Expat is a stream-oriented XML parser.)|-- fdlibm (FDLIBM (Freely Distributable LIBM))|-- freetype (字体)|-- fsck_msdos (dos文件系统检查工具)|-- gdata (google的无线数据相关)|-- genext2fs (genext2fs generates an ext2 filesystem as a normal (non-root) user)|-- giflib (gif库)|-- googleclient (google用户库)|-- grub (This is GNU GRUB, the GRand Unified Bootloader.)|-- gtest (Google C++ Testing Framework)|-- icu4c (ICU(International Component for Unicode)在C/C++下的版本)|-- ipsec-tools (This package provides a way to use the native IPsec functionality )|-- iptables (防火墙)|-- jdiff (generate a report describing the difference between two public Java APIs.)|-- jhead (jpeg头部信息工具)|-- jpeg (jpeg库)|-- junit (JUnit是一个Java语言的单元测试框架)|-- kernel-headers (内核的一些头文件)|-- libffi (libffi is a foreign function interface library.)|-- libpcap (网络数据包捕获函数)|-- libpng (png库)|-- libxml2 (xml解析库)|-- mtpd (一个命令)|-- netcat (simple Unix utility which reads and writes dataacross network connections)|-- netperf (网络性能测量工具)|-- neven (看代码和JNI相关)|-- opencore (多媒体框架)|-- openssl (SSL加密相关)|-- openvpn (VPN开源库)|-- oprofile (OProfile是Linux内核支持的一种性能分析机制。
详解Android框架MVVM分析以及使用
详解Android框架MVVM分析以及使⽤Android MVVM 分析以及使⽤⾸先我们需要知道什么是MVVM,他的功能和优点,以及他的缺点。
MVVM是Model-View-ViewModel的简写。
它本质上就是MVC 的改进版。
MVVM 就是将其中的View 的状态和⾏为抽象化,让我们将视图 UI 和业务逻辑分开。
当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展⽰内容⽽涉及的业务逻辑。
微软的WPF带来了新的技术体验,如Silverlight、⾳频、视频、3D、动画……,这导致了软件UI层更加细节化、可定制化。
同时,在技术层⾯,WPF也带来了诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。
MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应⽤⽅式时发展演变过来的⼀种新型架构框架。
它⽴⾜于原有MVP框架并且把WPF的新特性糅合进去,以应对客户⽇益复杂的需求变化。
WPF的数据绑定与Presentation Model相结合是⾮常好的做法,使得开发⼈员可以将View和逻辑分离出来,但这种数据绑定技术⾮常简单实⽤,也是WPF所特有的,所以我们⼜称之为Model-View-ViewModel(MVVM)。
这种模式跟经典的MVP(Model-View-Presenter)模式很相似,除了你需要⼀个为View量⾝定制的model,这个model就是ViewModel。
ViewModel包含所有由UI特定的接⼝和属性,并由⼀个 ViewModel 的视图的绑定属性,并可获得⼆者之间的松散耦合,所以需要在ViewModel 直接更新视图中编写相应代码。
How Amigo works (Android Hotfix Terminator)
application
How Amigo works (core diagram)
bug.apk diff.apk
patch.apk
release dex
release so
dexOpt dex
replace Application
replace ClassLoader
rewrite Resources
rewrite Application
How Amigo works (auto-upgrade)
support new Activity support new Receiver support new Service support new Provider permission? meta-data?
classes.dex
?
limits
work immediately
Amigo.work(context, patchApkFile);
make it clear
Amigo.clear(context);
Comparison
Amigo class x so x resource x instant work compatibility patch size usage upgrade yes yes yes optional high largest easy yes Tinker QZone yes yes yes high small hard yes high large hard AndFix depends yes low small hard -
How Amigo works (core)
replace original application with
Android进阶解密
精彩摘录
精彩摘录
DVM中的应用每次运行时,字节码都需要通过即时编译器(Just In Time,JIT)转换为机器码,这会使得 应用的运行效率降低。而在ART中,系统在安装应用时会进行一次预编译(Ahead Of Time,AOT),将字节码预 先编译成机器码并存储在本地,这样应用每次运行时就不需要执行编译了,运行效率也大大提高。
10.2 Java虚拟机结 构
10.3对象的创建
10.4对象的堆内存 布局
1
10.5 oopklass模型
2
10.6垃圾标记 算法
3 10.7 Java对
象在虚拟机中 的生命周期
4
10.8垃圾收集 算法
5
10.9本章小结
11.1 Dalvik虚拟机 11.2 ART虚拟机
11.3 DVM和ART的诞 生
11.4本章小结
12.2 Android中的 ClassLoader
12.1 Java中的 ClassLoader
12.3本章小结
13.1热修复的产生
13.2热修复框架的 种类和对比
13.3资源修复 13.4代码修复
13.5动态链接 库的修复
13.6本章小结
1
14.1 Hook技 术概述
2
14.2 Hook技 术分类
04
8.4 Window的 添加过程 (WMS处理 部分)
05
8.5 Window的 删除过程
06
8.6本章小Leabharlann 结19.1系统源码 中的JNI
9.2
2
MediaRecord
er框架中的
JNI
3
9.3数据类型 的转换
4
9.4方法签名
Android热修复学习之旅——HotFix完全解析
Android热修复学习之旅——HotFix完全解析Android dex分包原理介绍QQ空间热修复方案基于Android dex分包基础之上,简单概述android dex分包的原理就是:就是把多个dex文件塞入到app的classloader之中,但是android dex拆包方案中的类是没有重复的,如果classes.dex和classes1.dex中有重复的类,当classes.dex和classes1.dex中都具有同一个类的时候,那么classloader会选择加载哪个类呢?这要从classloader的源码入手,加载类是通过classloader的loadClass方法实现的,所以我们看一下loadClass的源码:/*** Loads the class with the specified name. Invoking this method is* equivalent to calling {@code loadClass(className, false)}.* <p>* <strong>Note:</strong> In the Android reference implementation, the* second parameter of {@link #loadClass(String, boolean)} is ignored* anyway.* </p>** @return the {@code Class} object.* @param className* the name of the class to look for.* @throws ClassNotFoundException* if the class can not be found.*/public Class<?> loadClass(String className) throws ClassNotFoundException { return loadClass(className, false);}protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {Class<?> clazz = findLoadedClass(className);if (clazz == null) {ClassNotFoundException suppressed = null;try {clazz = parent.loadClass(className, false);} catch (ClassNotFoundException e) {suppressed = e;}if (clazz == null) {try {clazz = findClass(className);} catch (ClassNotFoundException e) {e.addSuppressed(suppressed);throw e;}}}return clazz;}简单来说就是ClassLoader用loadClass方法调用了findClass方法,点进去发现findClass是抽象方法,而这个方法的实现是在它的子类BaseDexClassLoader中,而BaseDexClassLoader 重载了这个方法,得到BaseDexClassLoader,进入到BaseDexClassLoader类的findClass方法中#BaseDexClassLoader@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException { Class clazz = pathList.findClass(name);if (clazz == null) {throw new ClassNotFoundException(name);}return clazz;}#DexPathListpublic Class findClass(String name) {for (Element element : dexElements) {DexFile dex = element.dexFile;if (dex != null) {Class clazz = dex.loadClassBinaryName(name, definingContext);if (clazz != null) {return clazz;}}}return null;}#DexFilepublic Class loadClassBinaryName(String name, ClassLoader loader) {return defineClass(name, loader, mCookie);}private native static Class defineClass(String name, ClassLoader loader, int cookie);一个ClassLoader可以包含多个dex文件,每个dex文件是一个Element,多个dex文件排列成一个有序的数组dexElements,当找类的时候,会按顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找类则返回,如果找不到从下一个dex文件继续查找。
提高Android测试的代码覆盖率的实用技巧
提高Android测试的代码覆盖率的实用技巧Android测试是开发过程中至关重要的一环,而测试的代码覆盖率则是衡量测试质量的重要指标之一。
提高Android测试的代码覆盖率可以帮助开发人员发现潜在的问题,提升软件的稳定性和可靠性。
本文将介绍几个实用技巧,帮助Android开发者提高测试的代码覆盖率。
一、了解代码覆盖率概念在开始讨论具体的提高代码覆盖率的技巧之前,我们首先需要了解什么是代码覆盖率。
代码覆盖率是衡量测试用例对代码执行情况的度量指标,可分为语句覆盖率、分支覆盖率、路径覆盖率等。
其中,语句覆盖率是最基本的一种,表示被测试用例执行到的代码语句占总代码语句的比例。
二、选择合适的测试框架在Android开发中,有多种测试框架可供选择,如JUnit、Espresso、Robolectric等。
选择合适的测试框架是提高代码覆盖率的第一步。
对于单元测试,可以使用JUnit框架编写独立的、隔离的测试用例;对于UI测试,Espresso框架则是首选;而Robolectric框架则可以用于在本地JVM上运行Android测试,提高测试效率。
三、编写有效的测试用例编写有效的测试用例是提高代码覆盖率的关键。
在编写测试用例时,需要从不同的角度对代码进行覆盖,尽量覆盖所有可能的情况。
可以根据不同的输入条件、边界条件和异常场景编写测试用例,确保代码的各种情况都能得到覆盖。
四、使用模拟对象与桩对象在进行Android测试时,某些依赖于外部资源的代码很难进行覆盖,比如网络请求、数据库操作等。
为了解决这个问题,可以使用模拟对象(Mock)或者桩对象(Stub)进行测试。
模拟对象可以模拟外部资源的行为,桩对象则可以提供固定的返回结果,从而使得测试用例能够更加全面地覆盖代码。
五、利用覆盖率工具进行分析Android开发工具包(SDK)提供了一些覆盖率分析工具,如Emma、JaCoCo等。
这些工具可以帮助开发者分析测试用例的覆盖情况,并生成相应的报告。
Android应用程序包 坏的、好的和更好的说明书
Android parcels: the bad, the good and the better Introducing Android’s Safer ParcelHao KeBernardo RufinoYang YangMaria UretskyAbout UsHao Ke (@haoOnBeat)Security EngineerAndroid Malware ResearchGoogleBernardo RufinoSoftware EngineerAndroid Platform SecurityGoogleYang YangSecurity EngineerAndroid VRPGoogleSpecial thanksMaria Uretsky Tech Lead Android VRP Google Kevin Deus ISE Manager Android VRP GoogleAgenda●Parcel Mismatch problems●Bundle “FengShui” - Self changing Bundle ●Bundle “FengShui” - Making it safe(r)●CVE-2021-0928 (Novel in Android 12-beta) ●CVE-2021-0928 - Making it safe(r)●Parcel Mismatch and Android VRP●QuestionsParcel Mismatch problems: Parcel and Parcelable●Parcel: A container for sending serialized (aka. parceled) data across binderIPCs.●Parcelable:○Sender Side: Objects serialized into the Parcel (writeToParcel)○Receiver Side:Reconstructed back into the original Object (createFromParcel)Parcel Mismatch problems: Parcelable Containersprivate void readListInternal (@NonNull List outVal , int N , @Nullable ClassLoader loader ) { while (N > 0) {Object value = readValue (loader ); outVal .add (value ); N --; }public final Object readValue (@Nullable ClassLoader loader ) {int type = readInt ();switch (type) {case VAL_PARCELABLE :return readParcelable (loader );…case VAL_LIST :return readArrayList (loader );}…●“A final class of methods are for writing and reading standard Java containers of arbitrary types.”●Array, List, ArrayList, Map, SparseArray..public final ArrayList readArrayList (@Nullable ClassLoader loader ) { int N = readInt (); …ArrayList l = new ArrayList (N ); readListInternal (l , N , loader ); return l ;}Parcel Mismatch problems: Parcelable Containers: Cont’d ●Deserializes “everything” in the container○Other containers○Parcelables and Serializables○(Parcelables and Serializables in other containers)●Of Arbitrary types○Deserializes Parcelables or Serializables of any typeParcel Mismatch problemsParcelable Write:public void writeToParcel(Parcel parcel,int flags){parcel.writeInt(f1);parcel.writeByteArray(f2);}Parcelable Read:f1 = parcel.readInt();if(f1 >0) {parcel.readByteArray(f2); }Parcel Mismatch problems: Cont’d● A parcelable write/read mismatch makes the next entry read be misaligned ●Then, the receiver deserializes the data in an unexpected wayBundle “FengShui” - Self changing Bundle●Bundle b = new Bundle()// Fill bBundle c = new Bundle(b.writeToParcel())● b "!=" c => Self-changing bundleSerializationDeserializationSimulates sending b over processes (IPC)Bundle “FengShui” - Self changing Bundle ●Vulnerable example●Leveraged in following cross-processflow:○A: Sends Bundle x to B○A: <x is serialized>○B: <x is deserialized>○B: Inpects x (TOC) and sends to C○B: <x is serialized>○C: <x is deserialized>○C: Uses x (TOU)●Challenge: Hide item ("intent" => 42)in Bundle from B○Item only appears to C○In Android 12Bundle “FengShui” - Self changing BundleA ===(PA )====>B ====(PB)===> CBundle “FengShui” - Self changing BundleVulnerable A ===(PA)====> B ====(PB)===> CBundle “FengShui” - Self changing BundleBundle “FengShui” - Self changing BundleBundle “FengShui” - Self changing BundleBundle “FengShui” - Self changing BundleBundle “FengShui” - Self changing BundleAndroid 12/SBundle “FengShui” - Self changing Bundle: ExploitsDifferent!Bundle “FengShui” - Self changing Bundle: Exploits ●Abuses AccountManagerService○Where KEY_INTENT check happens○TOCTOU mismatch:■Bundle object ("self-")changed from deserialization to reserialization ●Triggers arbitrary Activity launching, from Settings app○Settings app (uid=1000 SYSTEM_UID) is privileged and can launch arbitrary activities○“LaunchAnyWhere”●Knowingly used in Malware campaigns (not covered in this talk)○Silently install packages●Fix the individual r/w mismatches○Yes, but doesn't scale●Fix AccountManagerService○Yes, but what about other code paths?●Fix Bundle○Yes!○What's wrong with Bundle?○=> Lazy Bundle●Fix the individual r/w mismatches => Yes, but doesn't scale…more●Fix the individual r/w mismatches○Yes, but doesn't scale●Fix AccountManagerService○Yes, but what about other code paths?●Fix Bundle○Yes!○What's wrong with Bundle?○=> Lazy Bundle●=> Fix AccountManagerService? YesBetween (6) and (7)=> b2 = unparcel(parcel(bundle))=> Verifyb2.get(KEY_INTENT) "==" bundle.get(KEY_INTENT)=> If not, fail and log●Fix the individual r/w mismatches○Yes, but doesn't scale●Fix AccountManagerService○Yes, but what about other code paths?●Fix Bundle○Yes!○What's wrong with Bundle?○=> Lazy Bundle●Fix Bundle○Yes!○What's wrong with Bundle?■Structure implicitly defined by the items and their payloads■Eager deserialization upon first retrieval/query ○=> Lazy Bundle●What's wrong with Bundle?○Structure implicitly defined by the items and their payloads ○If there is a r/w mismatch, the next read is affectedb.putParcelable("1", p1)b.putParcelable("2", p2) b.getParcelable("1")b.getParcelable("2")●What's wrong with Bundle?○Structure implicitly defined by the items and their payloads ○Prefix item lengthb.putParcelable("1", p1) b.putParcelable("2", p2)b.getParcelable("1")b.getParcelable("2")●What's wrong with Bundle?○Eager deserialization upon first retrieval/query○To read an item => read all previous items (in practice we read all the bundle)b.putParcelable("1", p1) b.putParcelable("2", p2)// b.getParcelable("1")b.getParcelable("2")●What's wrong with Bundle?○Eager deserialization upon first retrieval/query○With length prefix, we can skip items => only read (custom) items when queried ○=> Lazy bundleb.putParcelable("1", p1) b.putParcelable("2", p2)// b.getParcelable("1")b.getParcelable("2")●What's wrong with Bundle?○Lazy bundle: More resilient against system crashes / DoSBundle b =getIntent().getExtras() // Parcelled formb.getParcelable(k1)b // Map form●What's wrong with Bundle?○Lazy bundle: More resilient against system crashes / DoSParcelled formBundle b =getIntent().getExtras() // Parcelled formb.getParcelable(k1)b // Map form Map form●What's wrong with Bundle?○Lazy bundle: More resilient against system crashes / DoSBundle b =getIntent().getExtras() // Parcelled formb.getParcelable(k1)b // Map formX●What's wrong with Bundle?○Lazy bundle: More resilient against system crashes / DoSBundle b =getIntent().getExtras() // Parcelled formb.getParcelable(k1)b // Map form●What's wrong with Bundle?○Lazy bundle: More resilient against system crashes / DoSBundle b =getIntent().getExtras() // Parcelled formb.getParcelable(k1)b // Map formCVE-2021-0928 (Novel in Android 12-beta)●Arbitrary code execution in any app’s process (including system app processUID:1000)○Different exploit technique than Bundle FengShui○Fixed in Android 12’s official release○Reported and PoC-ed by Michał Bednarski (@BednarTildeOne)CVE-2021-0928 - Background: Broadcast What happens when an app calls sendBroadcast(intent) ?Background Cont’d: Broadcast - ActivityInfo Arbitrary code execution via tampering the ActivityInfo value.●ActivityThread (in app’s process) calls handleReceiver and eventually uses theapplicationInfo object (within ActivityInfo) to create a LoadedApk instance.●The LoadedApk object assigns the applicationInfo object’s sourceDir value to itsappdir, which is eventually used to to create the application’s classLoader.●Hence controlling the sourceDir value, the attacker application can make thevictim process load an attacker-controlled APK and execute arbitrary code from there.CVE-2021-0928 - The Mismatch●When exceptions occurs:○The read stops before fully consuming the data○Exceptions caught gracefullyCVE-2021-0928: OutputConfiguration Deserialization private OutputConfiguration(@NonNull Parcel source){int rotation = source.readInt();int surfaceSetId = source.readInt();int surfaceType = source.readInt();int width = source.readInt();int height = source.readInt();…boolean isMultiResolutionOutput =source.readInt()==1;ArrayList<Integer> sensorPixelModesUsed =newArrayList<Integer>();source.readList(sensorPixelModesUsed,Integer.class.getClassLoader());…}CVE-2021-0928: OutputConfiguration Deserializationprivate OutputConfiguration(@NonNull Parcel source){int rotation = source.readInt();int surfaceSetId = source.readInt();int surfaceType = source.readInt();int width = source.readInt();int height = source.readInt();…boolean isMultiResolutionOutput =source.readInt()==1;ArrayList<Integer> sensorPixelModesUsed =newArrayList<Integer>();source.readList(sensorPixelModesUsed,Integer.class.getClassLoader());…}CVE-2021-0928CVE-2021-0928CVE-2021-0928●system_server prepares the Parcel Object with Intent,ActivityInfo, other params●Victim app reads the Parcel object:○Exception only triggers when victim app’s deserializing the Intent○Read stops before data fully consumed○Exception handled, deserialization continues○Intent’s deserialization finished before the full Intent object is read○Starts reading ActivityInfo, from the wrong offset, within the attacker-controlled Intent object○……●Victim app execute the broadcast, using attacker controlledActivityInfo○Arbitrary code executionCVE-2021-0928 - Prerequisites●Parcelable R/W mismatch via triggering exceptions○Read “less” than write, causing the next parameter read at the wrong offset ○Exception only triggers in application’s process●Build PoC in the Intent object○Embed (R/W Mismatched) Parcelable objects in Intent. (Only became available in Android 12(S)-beta)CVE-2021-0928 - Prerequisites●Parcelable R/W mismatch via triggering exceptions○Read “less” than write, causing the next parameter read at the wrong offset○Exception only triggers in application’s process■ClassNotFoundException with system_server specific classPackageManagerException●Build PoC in the Intent object○Embed (R/W Mismatched) Parcelable objects in Intent. (Only became available in Android 12(S)-beta)CVE-2021-0928 - Prerequisites●Parcelable R/W mismatch via triggering exceptions○Read “less” than write, causing the next parameter read at the wrong offset ○Exception only triggers in application’s process●Build PoC in the Intent object○Embed (R/W Mismatched) Parcelable objects in Intent. (Only became available in Android 12(S)-beta)CVE-2021-0928 - PrerequisitesBuild PoC in the Intent object●Embed (R/W Mismatched) Parcelable objects in Intent. (Only became available inAndroid 12(S)-beta)splitDependencies = source.readSparseArray(null);readSparseArray - Parcelable Container method。
android getinstalledpackages参数 -回复
android getinstalledpackages参数-回复[android getinstalledpackages参数]是指在Android开发中使用的一个方法,用于获取已安装应用程序的包信息。
通过这个方法,开发者可以获取应用程序的包名、版本号、图标、权限等信息。
在本文中,我将分步介绍如何使用getInstalledPackages参数,以及它的一些常见用法和注意事项。
第一步:导入相关类和接口在Android开发中,我们需要先导入一些相关的类和接口才能使用getInstalledPackages方法。
首先,在项目的build.gradle文件中,确保已经添加了以下依赖项:implementation 'androidx.core:core:1.6.0'然后,在你的Java文件中,导入PackageManager类和PackageInfo 类:import android.content.pm.PackageManager;import android.content.pm.PackageInfo;第二步:获取PackageManager对象为了能够使用getInstalledPackages方法,我们需要获取PackageManager对象。
PackageManager类是Android系统中用来管理应用程序包信息和权限的类,因此我们需要通过系统服务获取它的实例。
可以使用以下代码获取PackageManager对象:PackageManager packageManager = getPackageManager();第三步:调用getInstalledPackages方法在获得PackageManager对象之后,我们就可以调用它的getInstalledPackages方法来获取已安装应用程序的包信息了。
getInstalledPackages方法返回一个List<PackageInfo>类型的对象,包含了所有已安装应用程序的包信息。
enhancedscroller源码解读
第一部分:介绍1. 什么是enhancedscroller?enhancedscroller是一个用于构建iOS和Android应用程序的开源软件项目,它提供了一种高性能和灵活的滚动视图组件。
这个库旨在解决滚动视图在移动端应用开发中的性能和灵活性问题,为开发者提供一种更加高效和便捷的滚动视图解决方案。
2. 为什么要解读enhancedscroller的源码?作为开发者,在学习和使用一个开源库时,了解其源码是非常重要的。
通过阅读enhancedscroller的源码,开发者可以更加深入地理解这个库的实现原理和设计思想,为自己在实际项目中的应用提供更多的灵活性和优化方案。
解读enhancedscroller的源码对于希望深入理解移动端应用开发和滚动视图实现的开发者来说是非常有益的。
第二部分:准备工作1. 下载源码在进行源码解读之前,首先需要从enhancedscroller的官方仓库中下载源代码。
可以在GitHub上搜索enhancedscroller,然后找到其官方仓库并选择下载源代码的方式进行下载。
一般来说,enhancedscroller的源码会以ZIP压缩包的形式提供,下载后解压即可。
2. 安装开发环境为了更好地阅读和理解源码,建议在自己的开发环境中安装相关的开发工具和依赖库。
如果是iOS开发者,可以在Xcode中打开enhancedscroller的工程文件;如果是Android开发者,可以使用Android Studio进行相关的配置和导入。
第三部分:源码解读1. 整体结构在阅读源码之前,可以先了解一下enhancedscroller的整体结构。
通常一个开源库的源码结构会包括各种配置文件、源代码文件、测试文件等,通过对整体结构的了解,可以更快地找到自己感兴趣的部分进行深入学习。
2. 关键模块在源码解读的过程中,可以重点关注一些关键模块,比如滚动视图的布局计算、重用机制的实现、滚动事件的处理等。
Android Hotfix 新方案——Amigo 源码解读
Android Hotfix 新方案——Amigo 源码解读首先我们先来看看如何使用这个库。
用法在project 的build.gradle中dependencies {classpath 'me.ele:amigo:0.0.3'}在module 的build.gradle中apply plugin: 'me.ele.amigo'就这样轻松的集成了Amigo。
生效补丁包补丁包生效有两种方式可以选择:∙稍后生效补丁包∙如果不想立即生效而是用户第二次打开App 时才打入补丁包,则可以将新的Apk 放到/data/data/{your pkg}/files/amigo/demo.apk,第二次打开时就会自动生效。
可以通过这个方法∙File hotfixApk = Amigo.getHotfixApk(context);∙获取到新的Apk。
同时,你也可以使用Amigo 提供的工具类将你的补丁包拷贝到指定的目录当中。
∙FileUtils.copyFile(yourApkFile, amigoApkFile);∙∙立即生效补丁包∙如果想要补丁包立即生效,调用以下两个方法之一,App 会立即重启,并且打入补丁包。
∙Amigo.work(context);∙Amigo.work(context, apkFile);∙删除补丁包如果需要删除掉已经下好的补丁包,可以通过这个方法Amigo.clear(context);提示:如果apk 发生了变化,Amigo 会自动清除之前的apk。
自定义界面在热修复的过程中会有一些耗时的操作,这些操作会在一个新的进程中的Activity 中执行,所以你可以通过以下方式来自定义这个Activity。
<meta-dataandroid:name="amigo_layout"android:value="{your-layout-name}" /><meta-dataandroid:name="amigo_theme"android:value="{your-theme-name}" />组件修复Amigo 目前能够支持增加Activity 和BroadcastReceiver。
Android 主要的热修复方案原理分析
Android 主要的热修复方案原理分析目前较为成熟的热修复框架主要有AndFix、Nuwa以及微信的热更新思想。
现在将其主要思想总结如下:AndFixAndFix是支付宝开源的一套热修复框架,使用简单,成功率高,基本满足大多数的bug修复场景。
引入到项目中非常方便,主要分两步:代码整合build.gradle添加依赖 compile 'com.alipay.euler:andfix:0.4.0@aar'Application.onCreate()方法中添加PatchManager patchManager = new PatchManager(this);patchManager.init(appversion);//current versionpatchManager.loadPatch();然后和后端协商一个补丁包下载服务器,在每次下载更新包到本地后patchManager.addPatch(path);打补丁AndFix提供了一个打补丁包的工具,可以去这里下载,使用方法如下:apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias> -e <***>-a,--alias <alias> keystore entry alias.-e,--epassword <***> keystore entry password.-f,--from <loc> new Apk file path.-k,--keystore <loc> keystore path.-n,--name <name> patch name.-o,--out <dir> output dir.-p,--kpassword <***> keystore password.-t,--to <loc> old Apk file path.AndFix的思想是直接更改修复的方法,具体我们可以看源码。
全网独家盘点Android热修复方案(含阿里巴巴、美团、腾讯等)
全⽹独家盘点Android热修复⽅案(含阿⾥巴巴、美团、腾讯等)上⼀个⼤的系列⽂章叫 “⼿把⼿讲解”, 历时10个⽉,出产博⽂⼆⼗余篇,讲解细致,⼏乎每⼀篇都提供了详实的原理讲解,提供了可运⾏githubDemo,并且针对Demo 中的关键地⽅进⾏了重点拆解。
相信每⼀位详细阅读⽂章的同⾏都会有所收获。
但是,讲解虽详细,但是缺乏对于技术的深度的挖掘。
从今天开始开辟新的专题: 移动架构师专业技能深⼊浅出,以⼀步步成为架构师为⽬标,详述⼀项架构师技能的最直接使⽤价值,横向周边知识以及纵深专业技术.最直接使⽤价值:⽹上最怕看到⼀种⽂章,全⽂开篇⾼⼤上,让⼈觉得遥不可及,通篇看下来却没有展⽰技术如何落地,落地之后是何种效果。
⽂章写出来,就要以最容易让⼈接受的⽅式带读者进⼊作者的世界,⽽不是装作⼀副⾼⾼在上的样⼦俯视众⽣。
所以,⽂章开篇,⼀定是最直接的展⽰技术的落地效果。
提供可运⾏Demo可以让读者亲⾃尝试。
横向周边知识:⼀项核⼼技术,必然不是独⽴存在,技术是⼀个体系,但是⼀篇⽂章能够详述的技术有限,必然是以⼀项技术为中⼼,其他技术作为辅助。
核⼼技术需要详述,但是周边技术,也需要交代,参天⼤树拔地⽽起也少不得⼟壤作为依附。
⽤简明的语⾔交代周边知识,并提供这些知识正确的研究⽅向。
也是⼀个负责任的博⽂作者不可忽视的⼀步。
纵深专业技术: 做技术,最忌讳的就是浅尝辄⽌。
稍微深⼊⼀点就退出去,⼀来不利于理解底层实现,长此以往永远只是⼀个技术⼩⽩,成不了⼤师;⼆来不利于长久记忆, 记忆⼒再强的⼈时间长了,技术细节必然会记忆模糊。
但是如果深⼊内核,理解了原理,在技术的⼤⽅向上绝对不会偏差。
作为要成为架构师的男⼈,即使记不了那么多细节,但是对于⼤⽅向的把握绝对不能错。
所以,技术纵深很有必要。
前情提要上⼀篇提到了热修复的其中⼀种Muitidex⽅案,并且给出了演⽰Demo。
但是真正完整去展现现实中的热修复开源框架,远远不够。
商米特殊代码说明
特殊代码说明一、获取商米设备标识商米建议通过获取到以下内容来判断是否商米设备:1.设备的品牌名 brand(如:SUNMI)商米的品牌名统一为 SUNMI2.设备的系统型号 model(如:V1-B18)系统型号组成为产品型号+硬件特性+‘-’+软件特性其中以V、M、P、L开头为手持设备,以T、D、S开头为横屏设备(截至2017年12月)3.设备的ROM版本号(如:1.1.0)。
4.设备的ROM顺序号(如:128)。
可以下载Demo,仿照Demo在自己项目src下面新建android.os包(固定写法),将SystemProperties.java放入该包下,按以下方法获取指定的值:获取brand的代码为:String brand =SystemProperties.get("ro.product.brand");获取model的方法为:String model =SystemProperties.get("ro.product.model");获取ROM版本号的代码为:String versionname =SystemProperties.get("ro.version.sunmi_versionname");获取ROM顺序号的方法为:String versioncode =SystemProperties.get("ro.version.sunmi_versioncode");二、获取设备的SN号1.在AndroidManifest.xml中添加如下权限。
<uses-permission android:name="android.permission.READ_PHONE_STATE" />2.在需要的地方用以下代码获取商米SN号。
Class c =Class.forName("android.os.SystemProperties");Method get = c.getMethod("get",String.class);Log.i("sunmi", "the sn:" + (String)get.invoke(c, "ro.serialno")));Log.i("sunmi", "First four characters:" +(String) get.invoke(c, "ro.serialno").substring(0, 4)); } catch (Exception e) {e.printStackTrace();}3.在需要的地方用以下代码获取客户SN号,限定最多16位数字或大小写字母。
androidjava层实现hook替换method
androidjava层实现hook替换method Android上的热修复框架 AndFix ⼤家都很熟悉了,它的原理实际上很简单: ⽅法替换——Java层的每⼀个⽅法在虚拟机实现⾥⾯都对应着⼀个ArtMethod的结构体,只要把原⽅法的结构体内容替换成新的结构体的内容,在调⽤原⽅法的时候,真正执⾏的指令会是新⽅法的指令;这样就能实现热修复,详细代码见。
需要了解Android 虚拟机的⽅法调⽤过程才能彻底理解。
众所周知,AndFix是⼀种 native 的hotfix⽅案,它的替换过程是⽤ c 在 native层完成的,但其实,我们也可以⽤纯Java实现它!⽅法替换原理既然我们知道 AndFix 的原理是⽅法替换,那么为什么直接替换Java⾥⾯的ng.reflect.Method有什么问题吗?直接这样貌似很难下结论,那我们换个思路。
我们实现⽅法替换的结果,就是调⽤原⽅法的时候最终是调⽤被替换的⽅法。
因此,我们可以看看ng.reflect.Method类的invoke⽅法。
(Foo.bar()这种直接调⽤与反射调⽤Foo.class.getDeclaredMethod(“bar”).invoke(null) 有什么区别吗?)1private native Object invoke(Object receiver, Object[] args, boolean accessible)2throws IllegalAccessException, IllegalArgumentException, InvocationTargetException; 这个invoke是⼀个native⽅法,它的native实现在art/runtime/native/java_lang_reflect_⾥⾯,这个jni⽅法最终调⽤了art/runtime/的InvokeMethod⽅法:1 object InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod,2 jobject javaReceiver, jobject javaArgs, bool accessible) {3// 略...45 mirror::ArtMethod* m = mirror::ArtMethod::FromReflectedMethod(soa, javaMethod);67 mirror::Class* declaring_class = m->GetDeclaringClass();89// 按需初始化类,略。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Android Hotfix 新方案——Amigo 源码解读首先我们先来看看如何使用这个库。
用法在project 的build.gradle中dependencies {classpath 'me.ele:amigo:0.0.3'}在module 的build.gradle中apply plugin: 'me.ele.amigo'就这样轻松的集成了Amigo。
生效补丁包补丁包生效有两种方式可以选择:∙稍后生效补丁包∙如果不想立即生效而是用户第二次打开App 时才打入补丁包,则可以将新的Apk 放到/data/data/{your pkg}/files/amigo/demo.apk,第二次打开时就会自动生效。
可以通过这个方法∙File hotfixApk = Amigo.getHotfixApk(context);∙获取到新的Apk。
同时,你也可以使用Amigo 提供的工具类将你的补丁包拷贝到指定的目录当中。
∙FileUtils.copyFile(yourApkFile, amigoApkFile);∙∙立即生效补丁包∙如果想要补丁包立即生效,调用以下两个方法之一,App 会立即重启,并且打入补丁包。
∙Amigo.work(context);∙Amigo.work(context, apkFile);∙删除补丁包如果需要删除掉已经下好的补丁包,可以通过这个方法Amigo.clear(context);提示:如果apk 发生了变化,Amigo 会自动清除之前的apk。
自定义界面在热修复的过程中会有一些耗时的操作,这些操作会在一个新的进程中的Activity 中执行,所以你可以通过以下方式来自定义这个Activity。
<meta-dataandroid:name="amigo_layout"android:value="{your-layout-name}" /><meta-dataandroid:name="amigo_theme"android:value="{your-theme-name}" />组件修复Amigo 目前能够支持增加Activity 和BroadcastReceiver。
只需要将新的Activity 和BroadcastReceiver 加到新的Apk 包中就可以了。
Service 和ContentProvider 将会在未来的版本中支持更新。
集成Amigo 十分简单,但是明白Amigo 的实现更加重要。
源码分析在Amigo这个类中实现了主要的修复工作。
我们一起追追看,到底是怎样的实现。
检查补丁包Amigo.java...if (demoAPk.exists() && isSignatureRight(this, demoAPk)) {SharedPreferences sp = getSharedPreferences(SP_NAME,MODE_MULTI_PROCESS);String demoApkChecksum = checksum(demoAPk);boolean isFirstRun = !sp.getString(NEW_APK_SIG,"").equals(demoApkChecksum);...这段代码中,首先检查是否有补丁包,并且签名正确,如果正确,则通过检验校验和是否与之前的检验和相同,不同则为检测到新的补丁包。
释放Apk当这是新的补丁包时,首先第一件事就是释放。
ApkReleaser.work(this, layoutId, themeId)在这个方法中最终会去开启一个ApkReleaseActivity,而这个Activity 的layout 和theme 就是之前从配置中解析出来,在work 方法中传进来的layoutId 和themeId。
ApkReleaseActivity.java@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);...new Thread() {@Overridepublic void run() {super.run();DexReleaser.releaseDexes(demoAPk.getAbsolutePath(),dexDir.getAbsolutePath());NativeLibraryHelperCompat.copyNativeBinaries(demoAPk, nativeLibraryDir);dexOptimization();handler.sendEmptyMessage(WHAT_DEX_OPT_DONE);}}.start();}在ApkReleaseActivity 的onCreate()方法中会开启一个线程去进行一系列的释放操作,这些操作十分耗时,目前在不同的机子上测试,从几秒到二十几秒之间不等,如果就这样黑屏在用户前面未免太不优雅,所以Amigo 开启了一个新的进程,启动这个Activity。
在这个线程中,做了三件微小的事情:∙释放Dex 到指定目录∙拷贝so 文件到Amigo 的指定目录下拷贝so 文件是通过反射去调用NativeLibraryHelper这个类的nativeCopyNativeBinaries()方法,但这个方法在不同版本上有不同的实现。
∙o如果版本号在21以下oNativeLibraryHelperopublic static int copyNativeBinariesIfNeededLI(File apkFile, File sharedLibraryDir) {final String cpuAbi = Build.CPU_ABI;final String cpuAbi2 = Build.CPU_ABI2;return nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi,cpuAbi2);}会去反射调用这个方法,其中系统会自动判断出primaryAbi 和secondAbi。
o如果版本号在21以上copyNativeBinariesIfNeededLI(file, file)这个方法已经被废弃了,需要去反射调用这个方法NativeLibraryHelperpublic static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {for (long apkHandle : handle.apkHandles) {int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,handle.extractNativeLibs, HAS_NATIVE_BRIDGE);if (res != I NSTALL_SUCCEEDED) {return res;}}return I NSTALL_SUCCEEDED;}所以首先得去获得一个NativeLibraryHelper$Handle类的实例。
之后就是找primaryAbi。
Amigo 先对机器的位数做了判断,如果是64位的机子,就只找64位的abi,如果是32位的,就只找32位的abi。
然后将Handle 实例当做参数去调用NativeLibraryHelper的findSupportedAbi来获得primaryAbi。
最后再去调用copyNativeBinaries去拷贝so 文件。
∙优化dex 文件∙ApkReleaseActivity.java∙private void dexOptimization() {...for (File dex : validDexes) {new DexClassLoader(dex.getAbsolutePath(), optimizedDir.getAbsolutePath(), null,DexUtils.getPathClassLoader());Log.e(TAG, "dexOptimization finished-->" + dex);}}∙DexClassLoader 没有做什么事情,只是调用了父类构造器,他的父类是BaseDexClassLoader。
在BaseDexClassLoader 的构造器中又去构造了一个DexPathList 对象。
在DexPathList类中,有一个Element 数组∙DexPathList∙/** list of dex/resource (class path) elements */private final Element[] dexElements;∙Element 就是对Dex 的封装。
所以一个Element 对应一个Dex。
这个Element 在后文中会提到。
∙优化dex 只需要在构造DexClassLoader 对象的时候将dex 的路径传进去,系统会在最后会通过DexFile的∙DexFile.java∙native private static int openDexFile(String sourceName, String outputName,int flags) throws IOException;∙来这个方法来加载dex,加载的同时会对其做优化处理。
∙这三项操作完成之后,通知优化完毕,之后就关闭这个进程,将补丁包的校验和保存下来。
这样第一步释放Apk 就完成了。
之后就是重头戏替换修复。
替换修复替换classLoaderAmigo 先行构造一个AmigoClassLoader对象,这个AmigoClassLoader是一个继承于PathClassLoader的类,把补丁包的Apk 路径作为参数来构造AmigoClassLoader对象,之后通过反射替换掉LoadedApk 的ClassLoader。
这一步是Amigo 的关键所在。
替换Dex之前提到,每个dex 文件对应于一个PathClassLoader,其中有一个Element[],Element 是对于dex 的封装。
Amigo.javaprivate void setDexElements(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException {Object dexPathList = getPathList(classLoader);File[] listFiles = dexDir.listFiles();List<File> validDexes = new ArrayList<>();for (File listFile : listFiles) {if (listFile.getName().endsWith(".dex")) {validDexes.add(listFile);}}File[] dexes = validDexes.toArray(new File[validDexes.size()]);Object originDexElements = readField(dexPathList, "dexElements"); Class<?> localClass =originDexElements.getClass().getComponentType();int length = dexes.length;Object dexElements = Array.newInstance(localClass, length);for (int k = 0; k < length; k++) {Array.set(dexElements, k, getElementWithDex(dexes[k], optimizedDir));}writeField(dexPathList, "dexElements", dexElements);}在替换dex时,Amigo 将补丁包中每个dex 对应的Element 对象拿出来,之后组成新的Element[],通过反射,将现有的Element[] 数组替换掉。