读老罗android总结

原创 2016年06月01日 18:00:57

Android笔记

1.android组件设计思想

  把android应用程序组件化的好处是降低模块间的耦合性,同时提高模块的复用性。Android组件设计思想不依赖于进程,即进程即使由于内存紧张而被杀掉,但是运行在里面的组件还是存在的。这样就可以在组件再次需要使用时重新启用,进而降低了移动应用程序的复杂度。这种设计思想非常适合内存小的移动设备。

  1).设备特性对移动客户端应用程序的影响

-低频率

影响程序运行速度,尤其是程序启动速度,因为用户对程序启动时间最为敏感。

-小容量内存

影响同时运行的程序的数量,而且系统会在内存紧张时杀掉进程,以便回收内存。

-小面积屏幕

单窗口操作模式,导致用户需要频繁地切换程序或者重新打开程序。

组件化的基本思想:

具体实现:

l 程序由组件组成

Activity 前台交互

Service 后台计算

Broadcast Receiver  广播通信

Content Provider 数据封装

l 组件与进程剥离

组件关闭时,进程可以继续存在,进而提高重新启动时的速度

进程关闭时,组建可以继续存在,进而保护被杀进程里的组件                

l 组件就是程序的入口

2.android源代码开发和调式环境搭建

Android源码下载

$ mkdir ~/bin
$ PATH=~/bin:$PATH

$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

$ mkdir WORKING_DIRECTORY
$ cd WORKING_DIRECTORY

$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.2_r1

$ repo sync

Android源码编译与运行

$ . build/envsetup.sh

$ lunch full-eng

$ make j8

$ emulator &

Java代码开发和调式

安装eclipse

-sudo apt-get install eclipse

拷贝.classpath文件

-cd/path/to/android/root

-cp development/ide/eclipse/.classpth .

-chmod u+w .classpath

修改eclipse内存配置

-打开/usr/lib/eclipse/eclipse.ini

--Xms-Xmx均设置为2048m

导入Android源码到Eclipse

File > New > Java Project

Pick a project name, "android" or anything you like.

Select "Create project from existing source", enter the path to your Android root directory, and click Finish.

新增App工程到Android源码工程

Project > Properties

Select "Java Build Path" from the left-hand menu.

Choose the "Source" tab.

Click "Add Folder..."

Add your app's src directory.

Click OK.

使用Eclipse调试Java

码启动emulator

$ cd /path/to/android/root

$ . build/envsetup.sh$ lunch 1

$ emulator &

打开ddms

$ ddms

$ Select a process

打开eclipse

Run > Debug Configuration...

Right-click "Remote Java Application", select "New".

Pick a name, i.e. "android-debug" or anything you like.

Set the "Project" to your project name.

Keep the Host set to "localhost", but change Port to 8700.

Click the "Debug" button and you should be all set.

3.android系统架构概述

-------android专用驱动------------------------

Logger:完全内存操作,适合频繁读写

Binderclient/server模型;进程间一次数据拷贝;进程内直接调用

Ashmem:使用文件描述符描述,通过binder在进程间传递

-------android硬件抽象层-------------

内核空间主要负责硬件访问逻辑

用户空间主要负责参数和访问流程控制,

HAL Module通过设备文件访问内核空间部分设备驱动,并通过HAL Module对硬件进行管理(系统服务通过jni访问HAL Module)

应用程序通过系统服务队硬件进行访问(应用程序通过binder ipc访问系统服务)

4.android应用程序进程管理

Android系统里面的应用程序时被系统托管的,即系统根据需要来创建进程以及回收进程。进程创建发生在组件启动时,它们是由zygote进程创建的。Zygote进程是由系统中的第一个进程init负责启动。此外,用来运行各种系统服务的system server进程也是由zygote进程创建的。进程回收发生在内存紧张时,由Low Memory Killer执行。此外,组建管理服务AcitivityManagerService和窗口管理服务WindowManagerService也会在适当的时候主动进行进程回收。每一个应用程序进程根据运行情况被赋予优先级,当需要回收进程的时候,按照优先级从低到高的顺序进行回收。

---------------------------zygote进程启动过程分析-------------------------------

l Zygote进程是由init进程启动

---   加载文件:/system/app_process

---   --start-system-server:启动system server进程

---   创建名称为zygotesocket:用来和activitymanagerservice通信

l 启动dalvik虚拟机

------常见一个dalvik虚拟机实力

------加载java和核心类以及其JNI方法

------初始化主线程的JNI环境

l 加载部分android核心类及其JNI方法

5.android应用程序消息处理机制

Android应用程序是由消息驱动的,即在android应用程序主线程中,所有函数都是在一个消息循环中执行的。Android应用程序其它线程也可以像主线程一样拥有消息循环。主线程一旦发生阻塞就会影响UI的流畅性,甚至发生ANR问题。掌握android应用程序消息处理机制有助于熟练地使用同步和异步编程,提高出现的运行性能。

MessageQueueLooper的关系

 

主线程使用异步任务的原因:

l 主线程任务繁重

----执行组件生命周期函数

----执行业务逻辑

----执行用户交互

----执行UI渲染

l 主线程处理某个消息时间过长会产生ANR

-----service生命周期函数-20s

-----broadcast receiver接受前/后台优先级广播函数分别为10s/60s

-----影响输入时间处理的函数5s

-----影响进程启动的函数10s

-----影响activity切换函数2s

HandlerThread适合用来处理不需要更新UI的后台任务

AyncTask适合用来处理需要更新UI的后台任务

6.android应用程序输入事件处理机制

输入事件是专门负责与用户进行交互的。触摸屏和键盘事件是同意由系统输入管理器InputManager进行分发的,即InputManager负责从硬件接收事件输入,然后再将接收到的输入事件分发到当前激活的窗口处理。此外,InputManager也能接受模拟的输入事件,用来模拟用户触摸和点击等事件。当前激活的窗口所运行在现场接收到InputManager分发过来的输入事件之后,会将她们封装成输入消息,然后交给当前获得焦点的控件处理。

7.android应用程序UI架构

Android系统采用的是一种称为surfaceUI架构为应用程序提供用户界面。在android应用程序中,每一个activity组件都关联有一个或者若干个窗口,每一个窗口都对应一个surface。有了这个surface之后,应用程序就可以在上面渲染窗口的UI。最终这些已经绘制好的surface都会被统一提交给surface管理服务SurfaceFlinger进行合成,最后显示在屏幕上。

总体架构:

 

窗口的结构:

ViewRootImpl是一个虚拟根View,用来控制窗口的渲染,以及用来与WindowManagerService

SurfaceFlinger通信。

DecorView是窗口的真正根View

ContentView描述窗口的主题风格。

8.android应用程序资源管理框架

Android应用程序主要由代码和资源组成。资源主要就是指那些与UI相关的东西,例如UI布局、字符串和图片等。代码和资源分开可以使得应用程序在运行时根据实际需要来组织UI。这样就可使得应用程序只需要编译一次,就可以支持不同的UI布局。这种特性使得应用程序在运行时可以适应不同的屏幕大小和密度,以及不同的国家和语言等。资源在Android应用程序编译的过程中,也会被编译成二进制格式。这是为了压缩资源存储空间,以及加快运行时的资源解析速度。Android应用程序在运行的时候,资源管理器AssetManagerResources会根据当前的机器设置,即屏幕大小、密度、方向,以及国家、地区语言的信息,查找正确的资源,并且进行解析,最后将它们渲染在UI上。

android资源的编译过程

l Android编译过程主要是将XML文件从文本格式编译为二进制格式

-----二进制的XML文件占用空间更小。这是由于所有XML元素的标签、属性名称、属性值和内容所涉及到的字符串都会同意收集到一个字符串资源池中去,并且会去重。同样的字符串使用同一个整数索引值来指定该字符串的位置。

-----二进制格式的XML文件的解析速度更快。这是由于被编译的二进制文件避免了进行字符串解析,从而提高了速度。

l 为了支持运行时快速定位最匹配资源,编译过程还会有为资源生成ID,以及生产资源索引表

-----赋予每个非assets资源一个ID值,这些值以常量的形式定义在一个R.java文件中

-----生成一个resources.arsc文件,用来描述那些具有ID值得资源的配置信息,它的内容就相当于是一个资源索引表。

9.APK防反编译技术

l 添加非法指令

① 在APK包含一个无关类Bomb,该类有一个成员函数drop

② 将APKclasses.dex解压出来,并且用dexdump进行反编译,找到Bomb.dropclasses.dex的偏移。

③ 用vim以二进制方式打开classes.dex转到Bomb.drop的偏移处,将前两个字节修改为FF FF(非法指令);

④ 重新打包和签名APK,用adb install命令安装,日志提示checksum不一致。

⑤ 用dexdump验证APKchecksum,并且将正确的checksum替换原classes.dexchecksum;

⑥ 重新打包和签名APK,用adb install安装,DONE

l 隐藏敏感代码

① 在APK包含一个无关类Bomb,该类有一个函数drop,前面留有18个字节的垃圾指令;

② 将APKclasses.dex解压出来,并且用dexdump进行反编译,找到Bomb.dropclasses.dex的偏移;

③ 用vim以二进制方式打开classes.dex,转到Bomb.drop的偏移处,将前18个字节修改为一下指令;

 

④ 用dexdump查看classes.dex的头部信息,找到class_def的偏移,以及Bomb类的class index;

⑤ class_def的偏移,加上Bomb类的class index乘以32的积,即可得到用来描述Bomb类的class_def结构体偏移,再往前4个字节,即为其access_flags,将它的第16位设置为1,一般就是设置为0x10001,也就是将0100 0000设置为0100 0100,这样可以将Bomb类设置为已验证

⑥ 用dexdump验证APKchecksum,并且将正确的checksum替换原classes.dexchecksum

⑦ 重新打包和签名APK,用adb install安装,DONE

l 伪APK加密技术

① ZIP中的每一个文件都有一个2字节大小的全局方式位标记,其中第0位表示是否加密

② 如果ZIP中的一个文件标志为加密,那么在解压时,就需要指定解压密码

③ APK默认都是不加密的,也就是APK在安装解压时,它里面的文件的加密位标志都会被忽略

④ Apktool发现APK是加密的时候,会抛出一个异常出来

⑤ 利用上述差异,就可以给APK设置一个加密标志,但不对其进行加密,从而阻止Apktool反编译

 

l 总结与思考

① APK在安装时,会对APK进行验证,主要是checksum验证和指令合法性验证

② 安装通过验证的APK会被标记为已验证,并且会被优化

③ 安装没有通过验证的APK仍然会被成功安装,但是它会被标记为未验证

④ 未验证的APK的某个类在被加载时,会被验证,一旦验证失败,就会抛出异常

⑤ 反编译工具会对APK的所有类进行验证,不管这个类安装后会不会被加载,一旦验证不通过,就会抛出异常

⑥ 根据以上的APK安装、验证和加载流程,就可以通过以下两个方法来阻止反编译:

----包含一个有非法指令(不能执行)的类,但是这个类保证永远不会被加载

----包含一个有非法指令(能执行)的类,同时将该类预先设置为已验证的

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

老罗android视频开发源码和ppt

  • 2013年10月17日 22:03
  • 1.99MB
  • 下载

《老罗的Android之旅》导读PPT

虽然好几个月没更新博客了,但是老罗一直有在准备可以分享的东西的。除了早前在微博分享Android4.2相关技术之外,这次还特意准备了13个PPT,总结之前所研究过的东西。内容从Android组件设计思...

老罗Android源代码情景分析

  • 2014年08月04日 15:12
  • 5.17MB
  • 下载

老罗 Android

  • 2012年09月04日 12:55
  • 572KB
  • 下载

《老罗Android》学习之SQLite

1、SQlite是什么? SQLite 是进程内的数据库引擎,不存在数据库的客户端和服务器,使用SQLite只需要带上它的一个动态库,就可以享用它的全部功能。 2、SQLiteOpenHelper...
  • ymangu
  • ymangu
  • 2014年05月26日 22:00
  • 823

老罗Android视频http协议开发包

  • 2015年01月26日 15:07
  • 1.62MB
  • 下载

在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口 (学习老罗的)

主要是在 ~/Android_4.2.2_SourceCode/frameworks/base/services/jni个夹子里面操作的。 根据老罗的方法我也是实现成功了。 但是和上一篇文章一样...
  • oldmtn
  • oldmtn
  • 2013年07月01日 14:59
  • 3004

老罗Android入门到开发视频

  • 2017年10月28日 01:15
  • 47B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:读老罗android总结
举报原因:
原因补充:

(最多只允许输入30个字)