Android Galler2源码分析

合集下载

Android逆向分析案例——某地图的定位请求分析

Android逆向分析案例——某地图的定位请求分析

Android逆向分析案例——某地图的定位请求分析微信里面有个“附近的人”,相信大家都知道,大概的原理就是调用腾讯地图的sdk进行定位,然后把个人的定位信息发到微信服务器上进行处理,再把一定范围内的人的信息返回并用列表的形式显示出来。

因为刚踏入逆向分析这行,所以抱着学习的态度,研究一下大公司的东西,涨一下知识,嗯,本次的案例就是分析腾讯地图中定位请求数据的加解密,以及搭建简易的APK模拟实现定位请求。

为了分析这一案例,是要掌握一定的分析工具的,其中包括APKTOOL,Sublime-Text,Xposed框架,Wireshark等。

嗯,作为分析笔记,我就不细说了,只是将分析的步骤一步步地列举出来。

首先,下载微信APK,利用APKTOOL在DOS下敲命令生成smali文件夹,这个过程我就不说了,前面博客已介绍过APKTOOL的使用方法。

对于初学者来说,他们喜欢看到直接明了的源代码,所以他们会喜欢用dex2jar去反编译,并利用jd-gui去查看代码,包括我当初也是如此,但现在我为什么不用dex2jar和jd-gui 去分析呢?再往下看看然后用smali文件查看工具Sublime-Text 3打开其刚刚生成的smali文件夹,如下图:嗯,反编译出来的文件数量令人感到窒息的,是不是有点感到逆向分析的痛苦了?要在如此多的smali文件里找到对应的类,并定位到关键的代码,这是需要一定的技巧的,不然你就只能码海捞针了。

顺便一提,这货混淆得太好了,里面的可读性非常差,而且通过smali可以看到代码是有一定的复杂性的,特别多goto 语句,所以如果用jd-gui浏览代码的话,是很不准确的,而且有一些内部类jd-gui是不会显示出来的等等。

总而言之,smali的表达基本是正确的,但jd-gui转变过程并没有那么智能,所以jd-gui所表达的信息很大程度是错的,只能辅助用,不能依赖。

既然我们要找的是地图地位请求,那么肯定涉及到网络,那么又怎么能少了抓包过程呢?好,进入微信,打开wireshark,在点击“附近的人”按钮同时观察wireshark抓到的包,主要是Http协议的包。

Android+2.2+开发环境配置详解

Android+2.2+开发环境配置详解

Android 2.2 开发环境配置详解Google在旧金山Moscone会展中心举办Google I/O 2010大会第二天(美国时间5月20日上午)的会议之上如约正式发布了代号为“Froyo(冻酸奶)”的最新版Android 2.2操作系统。

而紧接着网络中也开始提供SDK(开发者套件)安装包的下载,虽然仅凭SDK 包尚无法让我们体验到诸如Flash10.1等应用,但据官方介绍,新版系统带来性能的大幅度提升,除了支持Flash 10.1,另外还在系统界面、功能等方面进行了许多细节性优化.Android 2.2是非常值得期待,下面是根据个人实践经验配置Android SDK2.2+Eclipse 的开放环境编写的详细步骤。

根据这些步骤,就是门外汉也可有完成。

系统环境的要求可以参考/sdk/requirements.html 一,下载所软件包(1)JDK要求JDK1.5+,建议JDK6.X下载网址/javase/downloads/index.jsp下载后,一步一步安装!设置系统变量JAVA_HOME为你安装目录,在系统变量path的后面加入;%JAVA_HOME%\bin;图1.1 JAVA_HOME设置图1.2 Path系统变量配置本文实践选择JDK1.6.0_19(2)IDEEclipse 3.4 (Ganymede) or 3.5 (Galileo)下载网址/downloads 建议下载下面其中的一个版本Eclipse IDE for Java EE DevelopersEclipse IDE for Java DevelopersEclipse for RCP/Plug-in DevelopersEclipse Classic下载完成后,解压即可!本文选择当前最新的eclipse-reporting-galileo-SR2-win32 (Base On Eclipse 3.5 SR2)(3)Android SDK准确来说下载的不是SDK而是SDK下载安装器,因为下载下来的并没SDK,而需要连接到官方网址下载所需的SDK。

AndroidGallery2源代码分析

AndroidGallery2源代码分析

AndroidGallery2源代码分析打开图库中图⽚为什么从模糊变清晰1. 有⼀点要明⽩,图⽚要进⾏显⽰,⾸先要先将图⽚进⾏decode,然后才⼲显⽰2. 图⽚decode须要时间,越⼤的图⽚,细节越多的图⽚,那么它decode时间就越长3. 最笨的做法就是,等图⽚decode完了,我们再显⽰,在decode完之前就看到⿊⾊的背景。

但这种做法不太友好,尤其是⼤的图⽚的时候,等待的时间就越长为了给客户更好的⽤户体验,我们会先decode⼀张图⽚的thumbnail即缩略图, 当我们点击⼀张图⽚进来之后,我们⾸先看到的是这个图⽚的thumbnail,这样⽤户就知道图⽚有被显⽰可是,因为thumbnail的分辨率有限,贴到屏幕上之后就会⽐較模糊。

这就是为什么⼀開始看到模糊的原因4. 这个时候,还是逃不掉decode整张图⽚的步骤,我们全然能够等整张图⽚decode完成之后再更新到屏幕。

但我们觉得这样的⽅式也不是太好,为什么不是decode出⼀部分就显⽰⼀部分呢?所以终于的⽅法是:我们将整个图⽚分成⼩块(tile),high resolution的图⽚,tile的size是510,普通图⽚的tile size是254,然后我们依照从上到下,从左到右的顺序依次decodetile,所以你看到图⽚⼀⼩块⼀⼩块的显⽰,图⽚逐步变清晰的过程所以,眼下此⽅案已经做到了最优化,只是因为本⾝decode须要时间,我们不能做到⼀下显⽰清晰图⽚,或者缩短图⽚变清晰的时间。

void updateFromConfiguration(Context context, Resources resources, int wPx, int hPx,int awPx, int ahPx) {Configuration configuration = resources.getConfiguration();isLandscape = (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE);isTablet = resources.getBoolean(R.bool.is_tablet);isLargeTablet = resources.getBoolean(R.bool.is_large_tablet);if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {isLayoutRtl = (configuration.getLayoutDirection() == YOUT_DIRECTION_RTL);} else {isLayoutRtl = false;}widthPx = wPx;heightPx = hPx;availableWidthPx = awPx;availableHeightPx = ahPx;updateAvailableDimensions(context);}图⽚双击变⼤算法图⽚双击放⼤倍数和图⽚⼤⼩、显⽰图⽚的view⼤⼩,及图⽚当前的scale⼤⼩均有关系。

Gallery 3D 源码分析汇总

Gallery 3D 源码分析汇总

Gallery 3D 分析文章分类:移动开发Gallery 3D 分析yer 是个抽象类。

有5个变量,分别是mX;mY(位置坐标);mWidth;mHeight(宽与高);mHidden (是否隐藏); 一个抽象方法,非抽象子类都有实现。

Java代码其他的可以在子类中重写有好几个类都继承了Layer抽象类:BackgroundLayerCanvasLayerGridLayerHudLayerLoadingLayerRootLayer其中用到的RenderView类Java代码里面有个静态final 类Lists里面定义了updateList,opaqueList,blendedList,hitTestList,systemList等以Layer为对象内容的ArrayList;以及一个清空所有ArrayList的方法Clear().Gallery 3D 代码分析之概览文章分类:移动开发Gallery 3D UI 非常炫,如下图所示:需要明确的几个问题伪2D 还是3D:gallery3d 基于android SDK OpenGL ES 接口开发,使用了Java API,没有使用NDK。

图片如何显示:在OpenGL ES 中,要显示图片,需要定义一个四边形,然后把图片当作texture 贴到四边形上。

布局及特效如何实现:这是gallery3d 的精华所在,需认真分析。

大数据量图片/cache 如何实现和管理:gallery3d 有缓冲区的设计,非常不错,需要认真分析。

动画引擎:简单的讲,动画引擎对外可表现为一个接口:Java代码即,给定初始值(initVal),动画引擎根据逝去的时间(timeElapsed)和动画总时间(duration)计算下一帧对应的值(currentVal),这个值可能是位置坐标,也可能是一个矩阵matrix,或者是其它的属性。

显示一帧就调用该函数更新actor的属性,各个帧连起来显示就成了动画。

使用Android自带Gallery组件实现CoverFlow,源码+解析(An-Beer工作室)

使用Android自带Gallery组件实现CoverFlow,源码+解析(An-Beer工作室)

使用Android自带Gallery组件实现CoverFlow,源码+解析android, gallery, coverflow, 源码, 解析本帖最后由 kearnel 于 2010-10-24 11:46 编辑首先声明,源代码转载自国外Neil Davies,使用Apache2.0开源协议,请使用源代码的人自觉遵守协议内容。

本文为Kearnel原创,转载请注明出处。

以下是正文:使用过Android自带的gallery组件的人都知道,gallery实现的效果就是拖动浏览一组图片,相比iphone里也是用于拖动浏览图片的coverflow,显然逊色不少。

实际上,可以通过扩展gallery,通过伪3D变换可以基本实现coverflow的效果。

本文通过源代码解析这一功能的实现。

具体代码作用可参照注释。

最终实现效果如下:要使用gallery,我们必须首先给其指定一个adapter。

在这里,我们实现了一个自定义的ImageAdapter,为图片制作倒影效果。

传入参数为context和程序内drawable中的图片ID数组。

之后调用其中的createReflectedImages()方法分别创造每一个图像的倒影效果,生成对应的ImageView数组,最后在getView()中返回。

1./*2.* Copyright (C) 2010 Neil Davies3.*4.* Licensed under the Apache License, Version 2.0 (the "License");5.* you may not use this file except in compliance with the License.6.* You may obtain a copy of the License at7.*8.* /licenses/LICENSE-2.09.*10.* Unless required by applicable law or agreed to in writing, software11.* distributed under the License is distributed on an "AS IS" BASIS,12.* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13.* See the License for the specific language governing permissions and14.* limitations under the License.15.*16.* This code is base on the Android Gallery widget and was Created17.* by Neil Davies neild001 'at' gmail dot com to be a Coverflow widget18.*19.* @author Neil Davies20.*/21.public class ImageAdapter extends BaseAdapter {22.int mGalleryItemBackground;23.private Context mContext;24.25.private Integer[] mImageIds ;26.27.private ImageView[] mImages;28.29.public ImageAdapter(Context c, int[] ImageIds) {30.mContext = c;31.mImageIds = ImageIds;32.mImages = new ImageView[mImageIds.length];33.}34.35.public boolean createReflectedImages() {36.// The gap we want between the reflection and the original image37.final int reflectionGap = 4;38.39.int index = 0;40.for (int imageId : mImageIds) {41.Bitmap originalImage = BitmapFactory.decodeResource(42.mContext.getResources(), imageId);43.int width = originalImage.getWidth();44.int height = originalImage.getHeight();45.46.// This will not scale but will flip on the Y axis47.Matrix matrix = new Matrix();48.matrix.preScale(1, -1);49.50.// Create a Bitmap with the flip matrix applied to it.51.// We only want the bottom half of the image52.Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,53.height / 2, width, height / 2, matrix, false);54.55.// Create a new bitmap with same width but taller to fit56.// reflection57.Bitmap bitmapWithReflection = Bitmap.createBitmap(width,58.(height + height / 2), Config.ARGB_8888);59.60.// Create a new Canvas with the bitmap that's big enough for61.// the image plus gap plus reflection62.Canvas canvas = new Canvas(bitmapWithReflection);63.// Draw in the original image64.canvas.drawBitmap(originalImage, 0, 0, null);65.// Draw in the gap66.Paint deafaultPaint = new Paint();67.canvas.drawRect(0, height, width, height + reflectionGap,68.deafaultPaint);69.// Draw in the reflection70.canvas.drawBitmap(reflectionImage, 0, height + reflectionGap,71.null);72.73.// Create a shader that is a linear gradient that covers the74.// reflection75.Paint paint = new Paint();76.LinearGradient shader = new LinearGradient(0,77.originalImage.getHeight(), 0,78.bitmapWithReflection.getHeight() + reflectionGap,79.0x70ffffff, 0x00ffffff, TileMode.CLAMP);80.// Set the paint to use this shader (linear gradient)81.paint.setShader(shader);82.// Set the Transfer mode to be porter duff and destination in83.paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));84.// Draw a rectangle using the paint with our linear gradient85.canvas.drawRect(0, height, width,86.bitmapWithReflection.getHeight() + reflectionGap, paint);87.88.ImageView imageView = new ImageView(mContext);89.imageView.setImageBitmap(bitmapWithReflection);90.imageView91..setLayoutParams(new youtParams(160, 240));92.// imageView.setScaleType(ScaleType.MATRIX);93.mImages[index++] = imageView;94.95.}96.return true;97.}98.99.public int getCount() {100.return mImageIds.length;101.}102.103.public Object getItem(int position) {104.return position;105.}106.107.public long getItemId(int position) {108.return position;109.}110.111.public View getView(int position, View convertView, ViewGroup parent) {112.113.// Use this code if you want to load from resources114./*115.* ImageView i = new ImageView(mContext);116.* i.setImageResource(mImageIds[position]); i.setLayoutParams(new117.* youtParams(350,350));118.* i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);119.*120.* //Make sure we set anti-aliasing otherwise we get jaggies121.* BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();122.* drawable.setAntiAlias(true); return i;123.*/124.125.return mImages[position];126.}127.128./**129.* Returns the size (0.0f to 1.0f) of the views depending on the130.* 'offset' to the center.131.*/132.public float getScale(boolean focused, int offset) {133./* Formula: 1 / (2 ^ offset) */134.return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));135.}136.137.}138.}复制代码仅仅实现了图片的倒影效果还不够,因为在coverflow中图片切换是有旋转和缩放效果的,而自带的gallery中并没有实现。

Android7.0Gallery图库源码分析2-分析启动流程

Android7.0Gallery图库源码分析2-分析启动流程

Android7.0Gallery图库源码分析2-分析启动流程前⾯⼀讲解了Gallery启动Activity以及界⾯如何绘制,现在开始讲解启动流程的代码逻辑。

GalleryActivity的onCreate⽅法中调⽤initializeByIntent()⽅法,顾名思义这个⽅法就是根据Intent事件来初始化的。

1private void initializeByIntent() {2 Intent intent = getIntent();3 String action = intent.getAction();45if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)) {6 startGetContent(intent);7 } else if (Intent.ACTION_PICK.equalsIgnoreCase(action)) {8 ......9 } else if (Intent.ACTION_VIEW.equalsIgnoreCase(action)10 || ACTION_REVIEW.equalsIgnoreCase(action)){11 startViewAction(intent);12 } else {13//我们从桌⾯启动应⽤时Intent的Action是android.intent.action.MAIN,所以会⾛到这⼀步14 startDefaultPage();15 }16 }我们看⼀下这个⽅法,它是通过Bundle来传输数据1public void startDefaultPage() {2 ......3 Bundle data = new Bundle();4 data.putString(AlbumSetPage.KEY_MEDIA_PATH,5 getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));6 getStateManager().startState(AlbumSetPage.class, data);7 ......8 }上⾯这个⽅法涉及的东西很多,AlbumSetPage继承⾃ActivityState,显⽰所有相册缩略图的页⾯,也就是进⼊Gallery显⽰的第⼀个界⾯。

android onimageavailable中的逻辑

android onimageavailable中的逻辑`onImageAvailable()`是Android Camera2 API中的一个回调方法,用于在图像可用时进行处理。

其逻辑通常如下:1. 在Camera2 API中,你需要创建一个`ImageReader`对象来接收相机捕捉到的图像。

在`onImageAvailable()`方法中,你将处理这个可用的图像。

2. 首先,你需要从回调方法的参数中获取`ImageReader`对象,以便访问可用的图像。

通常是通过`ImageReader`的`acquireNextImage()`方法获取最新的图像。

如下所示:```java@Overridepublic void onImageAvailable(ImageReader reader) {Image image = reader.acquireNextImage();// 处理图像...}```3. 一旦你获得了图像,你可以使用`Image`对象来获取图像的相关信息,如宽度、高度、像素数据等。

4. 对于每个图像,你可以根据需要进行各种处理,例如保存到设备存储、显示在用户界面、进行图像处理等。

你可以使用`Image`对象的方法来获取和操作图像的像素数据。

5. 在处理完图像后,你应该释放`Image`对象以避免内存泄漏。

使用`Image`对象的`close()`方法来释放资源。

例如:```java@Overridepublic void onImageAvailable(ImageReader reader) {Image image = reader.acquireNextImage();// 处理图像...// 释放图像资源image.close();}```注意:在处理图像时,请确保在一个合适的线程上进行,以避免阻塞主线程。

以上是`onImageAvailable()`方法的基本逻辑,你可以根据自己的需求在该方法中进行图像处理和后续操作。

androidcamera系统架构源码分析(5)

androidcamera系统架构源码分析(5)写到第五篇,我们已经把大致的流程已经贯穿完了,还有很多东西没有讲,日后慢慢再说。

不过现在有一个重要的问题,就是整个流利里各种buf,provider,bufmgr,queue类等之间的关系,说白了就是buf类和buf辅助类之前的关系。

理清这些类的关系和这些类的作用,再从Buf流理解一下整个框架,CamAdapter和CamClient是怎么通过Buf联系,会对日后的分析有一个很大的帮助。

也相当于对本文的一个总结。

本来为了避免贴太多代码,想直接写中文总结的,后来发现贴代码虽然看得更辛苦一点,但细节更清晰,还是贴代码吧DisplayClient::onThreadLoop(Command const& rCmd){ // (0) lock Processor. //pImgBufQueue的实现在ImgBufQueue.cpp里spIImgBufQueue> pImgBufQueue; pImgBufQueue = mpImgBufQueue; /** (1) Prepare all TODO buffers. pImgBufQueue里有两个Buf队列mTodoImgBufQue 和mDoneImgBufQue 下面的函数用StreamImgBuf生成好ImgBufQueNode,把buf的标志位设为eSTATUS_TODO 后调用ImgBufQueue的enqueProcessor()把所有的Buf都放入到mTodoImgBufQue做接收数据的准备**/ prepareAllTodoBuffers(pImgBufQueue); // (2) Start 只是通知队列,不做任何队列的数据处理pImgBufQueue->startProcessor(); // (3) Do until disabled. while ( 1 ) { /**(.1) 在此处会ImgBufQueue的dequeProcessor()等待通知,并接收数据收到通知后,接收的是mDoneImgBufQue,一个ImgBufQueNode队列接收到队列后把整个mDoneImgBufQue传入handleReturnBuffers()中被处理handleReturnBuffers()首先会获得单个ImgBufQueNode中的IImgBuf,即最原始的Mem 接下来就是操作mem。

Android HAL分析报告

Android HAL分析报告1 HAL简介Android 的HAL(Hardware Abstract Layer硬件抽象层)是Google因应厂商「希望不公开源码」的要求下,所推出的新观念,其架构如下图。

虽然HAL 现在的「抽象程度」还不足,现阶段实作还不是全面符合HAL的架构规划,不过也确实给了我们很好的思考空间。

图1:Android HAL 架构规划这是Patrick Brady (Google) 在2008 Google I/O 所发表的演讲「Anatomy & Physiology of an Android」中,所提出的Android HAL 架构图。

从这张架构图我们知道,HAL 的目的是为了把Android framework 与Linux kernel 完整「隔开」。

让Android 不至过度依赖Linux kernel,有点像是「kernel independent」的意思,让Android framework 的开发能在不考虑驱动程序的前提下进行发展。

在Android 原始码里,HAL 主要的实作储存于以下目录:1. libhardware_legacy/ - 过去的实作、采取链接库模块的观念进行2. libhardware/ - 新版的实作、调整为HAL stub 的观念3. ril/ - Radio Interface Layer在HAL 的架构实作成熟前(即图1的规划),我们先就目前HAL 现况做一个简单的分析。

另外,目前Android 的HAL实作,仍旧散布在不同的地方,例如Camera、WiFi 等,因此上述的目录并不包含所有的HAL 程序代码。

图2:Android HAL / libhardware_legacy 过去的libhardware_legacy 作法,是比较传统的「module」方式,也就是将*.so 档案当做「shared library」来使用,在runtime(JNI 部份)以direct function call 使用HAL module。

Android12系统源码分析:NativeTombstoneManager

Android12系统源码分析:NativeTombstoneManagerAndroid12系统源码分析:NativeTombstoneManager概述android12新增的system_server进程(LocalService)本地服务,⽤于管理native tombstones。

该服务在开机Systemerver初始化流程启动,添加到LocalService,然后启动⼀个ServiceThread线程⽤于(mHandler.post)处理本服务的业务。

NativeTombstoneManager的功能主要是:监听/data/tombstones ⽬录⽂件变动,解析为TombstoneFile 对象保存,通知dropbox特定tombstones ⽂件删除特定tombstones ⽂件检索值得关注的是AMS对该服务的使⽤,也是Android11新增API:getHistoricalProcessExitReasons()软件架构如图:BootReceiver SystemServer 开机启动仅添加本地服务LocalServices.addService NativeTombstoneManager.class SystemService AppExitInfoTracker Nativ eTombs toneManager tombs toneServ ic e void clearHistoryProcessExitInfo()ActivityManagerService Nativ eTombs toneManager tombs toneServ ic e public getHistoricalProcessExitReasons()暴露接⼝给appNativeTombstoneManagerServiceNativ eTombs toneManager mManagerpublic v oid onStart()public v oid onBootPhas e()TombstoneFile by:qiuchengParcelFileDescriptorRetrieverNativeTombstoneManagerpriv ate v oid handleTombs tone()priv ate v oid handleProtoTombs tone()public v oid c ollec tTombs tones ()服务核⼼实现TombstoneWatcher 监听⽬录:/data/tombstones FileObserver 图:NativeTombstoneManager类图启动流程SystemServer SystemServer SystemServiceManager SystemServiceManager NativeTombstoneManagerService NativeTombstoneManagerService NativeTombstoneManager NativeTombstoneManager LocalServicesLocalServices 1startCoreServices23by:qiucheng4NativeTombstoneManager567addService(NativeTombstoneManager.class8startOtherServices9startBootPhasePHASE_ACTIVITY_MANAGER_READY10onBootPhase111213registerForPackageRemoval14handleTombstone图:NativeTombstoneManager服务启动时序图服务⽐较简单,和其他SystemServer启动的服务⼀样,frameworks/base/services/core/java/com/android/server/os/NativeTombstoneManagerService.java public class NativeTombstoneManagerService extends SystemService {private NativeTombstoneManager mManager;@Overridepublic void onStart() {mManager = new NativeTombstoneManager(getContext());//仅添加本地服务,没有binder服务LocalServices.addService(NativeTombstoneManager.class, mManager);}@Overridepublic void onBootPhase(int phase) {if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {mManager.onSystemReady();}}}本服务也是SystemService⼯具类的⼦类,通过重写onStart、onBootPhase获得代码流程在onStart中初始化真正的服务实现NativeTombstoneManager,实例化后添加到LocalServicesframeworks/base/services/core/java/com/android/server/os/NativeTombstoneManager.javapublic final class NativeTombstoneManager {NativeTombstoneManager(Context context) {//启动handler线程,⽤于后续处理本服务的业务final ServiceThread thread = new ServiceThread(TAG + ":tombstoneWatcher",THREAD_PRIORITY_BACKGROUND, true /* allowIo */);thread.start();mHandler = thread.getThreadHandler();//启动⽂件监听/data/tombstonesmWatcher = new TombstoneWatcher();mWatcher.startWatching();}void onSystemReady() {registerForUserRemoval();registerForPackageRemoval();// 开机阶段先扫描⼀次/data/tombstones⽬录mHandler.post(() -> {final File[] tombstoneFiles = TOMBSTONE_DIR.listFiles();for (int i = 0; tombstoneFiles != null && i < tombstoneFiles.length; i++) {if (tombstoneFiles[i].isFile()) {handleTombstone(tombstoneFiles[i]);开机流程有三个动作启动handler线程,⽤于后续处理本服务的业务TombstoneWatcher启动⽂件监听/data/tombstones开机阶段先扫描⼀次/data/tombstones⽬录看⼀下handleTombstoneframeworks/base/services/core/java/com/android/server/os/NativeTombstoneManager.javaprivate void handleTombstone(File path) {final String filename = path.getName();if (!filename.startsWith("tombstone_")) {return;}if (filename.endsWith(".pb")) {handleProtoTombstone(path);BootReceiver.addTombstoneToDropBox(mContext, path, true);} else {BootReceiver.addTombstoneToDropBox(mContext, path, false);如果是以pb结尾的原型⽂件,则handleProtoTombstone⽅法中为该⽂件⽣成TombstoneFile对象,并添加到数据结构private final SparseArray<TombstoneFile> mTombstones;并且,每个新⽣成的tombstone⽂件都会同步给dropbox新⽂件的监听frameworks/base/services/core/java/com/android/server/os/NativeTombstoneManager.javaclass TombstoneWatcher extends FileObserver {TombstoneWatcher() {super(TOMBSTONE_DIR, FileObserver.CREATE | FileObserver.MOVED_TO);}@Overridepublic void onEvent(int event, @Nullable String path) {mHandler.post(() -> {handleTombstone(new File(TOMBSTONE_DIR, path));});内部类TombstoneWatcher,当⽬录/data/tombstones有⽂件⽣成时,回调到onEvent,然后通过handleTombstone⽅法做处理AciivtyManager#getHistoricalProcessExitReasonsActivityManager ActivityManager ActivityManagerServiceActivityManagerServiceLocalServicesLocalServicesNativeTombstoneManagerNativeTombstoneManagergetHistoricalProcessExitReasonsenforceNotIsolatedCallerenforceDumpPermissionForPackageby:qiuchenggetServicecollectTombstonesnew ParceledListSlice<ApplicationExitInfo>(results)图:getHistoricalProcessExitReasons⽅法时序图需要注意返回的数据结构的处理ApplicationExitInfo。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

图库Gallery2Gallery2主要功能是实现本地存储器、MTP存储器和网络存储器中媒体(图像和视频)的浏览、显示和更多操作(删除、分享、选择和缩放等)。

下面用一张简单的用例图描述了Gallery2的功能和职责。

Gallery 主要是4个页面的跳转:AlbumSetPage.Java(相册缩略图);AlbumPage.java(单个相册照片缩略图);PhotoPage.java(单张照片);SlideShowPage.java(幻灯片界面);跳转过程:AlbumSetPage.Java→AlbumPage.java→PhotoPage.javaSlideShowPage.java是单独的。

这些界面类父类为ActivityState.java;这些界面的切换由StateManager.java负责。

1 界面跳转过程:在Galley2模块,我们先从程序的入口看起,在androidManifest.xml中注册Application标签(Android 系统会为每个程序运行时创建一个Application的类对象且仅创建一个,他的生命周期等于这个程序的生命周期,它是全局的单实例的,一般做一些全局的初始化操作),应用创建时就会被初始化,维护应用内部全局数据,主要看几个函数:initializeAsyncTask(), GalleryUtils.initialize(this),GalleryUtil是Gallery的工具类,获得了屏幕参数,WindowManager,Resource等Gallery 从launcher进入Gallery,进入GalleryActivity.ava@Overrideprotected void onCreate(Bundle savedInstanceState) {…...setContentView(yout.main);if (savedInstanceState != null) {getStateManager().restoreFromState(savedInstanceState);} else {initializeByIntent();}}private void initializeByIntent() {Intent intent = getIntent();String action = intent.getAction();if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)){ startGetContent(intent);} else if(Intent.ACTION_PICK.equalsIgnoreCase(action)) { // We do NOT really support the PICKintent. Handle it as// the GET_CONTENT. However, we needto translate the type// in the intent here.Log.w(TAG, "action PICK is notsupported");String type =Utils.ensureNotNull(intent.getType());if(type.startsWith("vnd.android.cursor.dir/")) {if(type.endsWith("/image")) intent.setType("image/*");if(type.endsWith("/video")) intent.setType("video/*");}startGetContent(intent);} else if(Intent.ACTION_VIEW.equalsIgnoreCase(action)||ACTION_REVIEW.equalsIgnoreCase(action)){startViewAction(intent);} else {startDefaultPage();}}从这个函数看,如果从相册应用图标进入,会走startDefaultPage流程,如果外部打开图片,会走startGetContent流程。

public void startDefaultPage() {PicasaSource.showSignInReminder(this);Bundle data = new Bundle();data.putString(AlbumSetPage.KEY_MEDIA_PATH,getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));getStateManager().startState(AlbumSetPage.class,data);mVersionCheckDialog =PicasaSource.getVersionCheckDialog(this);if (mVersionCheckDialog != null) {mVersionCheckDialog.setOnCancelListener(this);}}这样我们看到的是AlbumSetPage.Java这个界面了。

我们从起始页面开始,点击某个相册:一个相册是一个SlotView对象,这里不详细说明SlotView,相关介绍请访问:/discovery_by_joseph/article/details/17500425在onCreate()中初始化了SlotView。

并且对SlotView进行了监听:mSlotView.setListener(new SlotView.SimpleListener() {@Overridepublic void onDown(int index) {AlbumSetPage.this.onDown(index);}@Overridepublic void onUp(boolean followedByLongPress) {AlbumSetPage.this.onUp(followedByLongPress);}@Overridepublic void onSingleTapUp(int slotIndex) {AlbumSetPage.this.onSingleTapUp(slotIndex);}@Overridepublic void onLongTap(int slotIndex) {AlbumSetPage.this.onLongTap(slotIndex);}});接下来我们看红色部分:public void onSingleTapUp(int slotIndex) {if (!mIsActive) return;if (mSelectionManager.inSelectionMode()) {MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);if (targetSet == null) return; // Content is dirty, we shall reload soon mSelectionManager.toggle(targetSet.getPath());mSlotView.invalidate();} else {// Show pressed-up animation for the single-tap.mAlbumSetView.setPressedIndex(slotIndex);mAlbumSetView.setPressedUp();mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0), FadeTexture.DURATION);}}这里发了消息:消息处理是在onCreate中创建的:mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {@Overridepublic void handleMessage(Message message) {switch (message.what) {case MSG_PICK_ALBUM: {try {pickAlbum(message.arg1);} catch (Exception e) {Log.d(TAG, "exception when pickAlbum");}}default: throw new AssertionError(message.what);}}};}private void pickAlbum(int slotIndex) {if (!mIsActive) return;......mActivity.getStateManager().startStateForResult(AlbumPage.class, REQUEST_DO_ANIMATION, data);}@Overrideprotected void onStateResult(int requestCode, int resultCode, Intent data) {if (data != null && data.getBooleanExtra(AlbumPage.KEY_EMPTY_ALBUM, false)) {showEmptyAlbumToast(Toast.LENGTH_SHORT);}switch (requestCode) {case REQUEST_DO_ANIMATION: {mSlotView.startRisingAnimation();}}}接收到动作消息,启动相册页面AlbumPage。

后续的进入到单张页面:PhotoPage.java 也是同样的过程,但是我们在代码里看到的是下面:private void pickPhoto(int slotIndex, boolean startInFilmstrip) {if (!mIsActive) return;......if (startInFilmstrip) {mActivity.getStateManager().switchState(this, FilmstripPage.class, data);} else {mActivity.getStateManager().startStateForResult(SinglePhotoPage.class, REQUEST_PHOTO, data);}}这里我们看到跳转的是SinglePhotoPage 不是PhotoPage。

相关文档
最新文档