存档

‘Android浏览器’ 分类的存档

使用内部(com.android.internal)和隐藏(@hide)API[第3部分,定制android平台]

2011年7月6日 没有评论

本文翻译自https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-3-custom-android-platform/

在前一篇文章中我展示了如何创建定制的original-android.jar,包含内部API和隐藏API中的所有类。

接下的步骤很明显,就是修改现有的android平台(SDK_DIR/platforms/platform-X/android.jar)。您可以简单的用第2部分创建的original-android.jar替换android.jar,但这样您的所有工程都能够无限制的使用内部API和隐藏API。这不是很合适,因为在大多数工程中,您可能并不允许这样。而且,您基本上希望禁止使用这些API(这是ADT/android.jar的缺省行为),只是在少数工程中要用到内部和隐藏API。

为了达到这种灵活性,需要创建一个新的定制的android平台。当没有必要使用内部和隐藏API时,您使用原始的android平台。当需要访问内部和隐藏API时,您使用定制的android平台。

Android SDK目录树

让我们看看android SDK是如何组织的:

我们需要"platforms”目录,进去瞧瞧:

这里有一个支持的Android平台列表。

现在让我们瞧瞧这是如何与Eclipse设置关联起来的。选择一个Android工程,右键点击-http://mogoweb.net/files/categories/android-browser/page/>Properties -http://mogoweb.net/files/categories/android-browser/page/> Android。您可以看到一个支持平台的列表(它反映的是…/platforms/文件夹)。下面是截图:

创建新的平台

要创建一个定制的平台,需要复制android-9文件夹,命名为android-9-internals,然后做一些修改:

  1. 从android-9-internals文件夹删除android.jar。
  2. 复制original-android.jar,重命名为android.jar。
  3. 修改build.prop文件:

    …  

    ro.build.version.sdk=9 –http://mogoweb.net/files/categories/android-browser/page/> ro.build.version.sdk=-9

    …

    ro.build.version.release=2.3 –http://mogoweb.net/files/categories/android-browser/page/> ro.build.version.release=2.3.extended

重启eclipse,确认可以看到该新的平台,下面是我所看到的:

为什么我会选择API Level -9? 那是因为必须为一个数字,而且不能是9(或其它已经存在的API Level),否则您的定制平台将不会使用(它会在列表中显示,但不会工作,编译时会取原始的相同数字的平台)。

下面是Libraries视图的截图(当定制平台选中时):

总结

在前一篇文章中,我说明了如何创建一个android.jar的未经裁减版本original-android.jar。本篇文章中,我演示了如何创建使用该original-android.jar的定制android平台。这对于使用隐藏API足够了,但是对于使用内部API还需要更进一步。这是因为ADT仍然禁止使用com.android.internals包中的类(请看上面的截图)。在下一篇文章中,我将告诉您如何定制ADT,允许使用内部API。

分类: Android浏览器 标签:

使用内部(com.android.internal)和隐藏(@hide)API[第2部分,定制android.jar]

2011年7月6日 没有评论

本文翻译自https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-2-hacking-around/

在前一篇文章中,我解释了为什么不通过反射机制,不太容易使用com.android.internal包的内部API和标记为@hide的隐藏API,这是由于android.jar文件没有包含内部API和隐藏API的类,这样在编译时刻就没有办法引用这些类了。

本文将说明如何恢复原始的android.jar,这样就可以使用内部API和隐藏API了,就如同使用公开API一样。

如何获得原始(未裁减)的android.jar?

我们需要修改android.jar,让它包含所有原始的类文件(包括内部和隐藏API)。有两种方法:

1)Android是一个开源项目。我们可以下载源代码,定制构建系统,不从android.jar中移除内部和隐藏类。这种方法比较难。

2)每个模拟器或者真实设备都有一个与android.jar等价的包用于运行时。我们可以取得此jar,解出原始的.class文件,然后复制到android.jar。

我倾向于第二种方法,它比较容易,不需要linux机器(如果您是在windows下工作),也不需要编译所有的源码、定制构建系统,等等。

从设备获取framework.jar

您可以用命令行(adb pull)或者DDMS(从eclipse,或者android sdk单独启动)从设备或者模拟器中下载文件。

(注:模拟器总是在.dex文件中包含代码,而真实设备通常将代码包含在优化版的dex-odex文件。使用odex文件通常比较难,所以本文推荐用模拟器)

运行时刻和Android SDK中android.jar等价的文件是framework.jar. 该文件位于/system/framework/framework.jar。

adb pull /system/framework/framework.jar

当framework.jar下载后,重命名为framework.zip,然后unzip到一个单独的目录,您应该可以得到如下所示的内容:

 

文件classes.dex就是我们要的。

创建framework-classes.zip

首先我们需要将.dex文件转化为.jar文件格式。这可以用一个小工具dex2jar做到,您仅需要运行:

dex2jar classes.dex

当转化完成后,会得到classes.dex.dex2jar.jar文件,将其命名为framework-class.zip。使用zip文件查看器,进到framework-class.zip/com/android/internal:

哇,我们得到了内部API和隐藏API的.class文件(虽然截图只确认了内部API)。

创建original-android.jar

Android SDK中的android.jar位于ANDROID_SDK/platforms/android-X/android.jar(这里X代表API Level,比如X==9)。

复制android.jar为custom-android.zip。unzip到custom-android文件夹。从framework-class.zip中复制所有.class文件到custom-android文件夹(您需要替换所有已有的.class文件)。

然后zip文件夹custom-android为original-android.zip,重命名为original-android.jar。

步骤总结

  1. 选择目标平台X(我使用API Leve 9的平台,所以X == 9)
  2. 创建平台X的模拟器
  3. 启动模拟器,从中下载/system/framework/framework.jar文件
  4. 重命名framework.jar为framework.zip
  5. 从framework.zip解压出classes.dex
  6. 使用dex2jar将classes.dex转化为classes.jar
  7. 重命名classes.jar为framework-classes.zip
  8. ANDROID_SDK/platforms/android-X/复制android.jar,重命名为custom-android.zip
  9. 解压custom-android.zip到custom-android目录
  10. 从framework-classes.zip复制所有文件到custom-android文件夹(替换已有文件)
  11. zip压缩custom-android文件夹为original-android.zip
  12. 重命名original-android.zip为original-android.jar

完成。

结论

我们恢复了原始的android.jar,包含内部API和隐藏API的.class文件。这只是第一步,下一步是创建定制的平台,使用未裁减版本的android.jar,然后加入到Android SDK platforms目录。

分类: Android浏览器 标签:

使用内部(com.android.internal)和隐藏(@hide)API[第1部分,介绍]

2011年7月5日 1 条评论

本文翻译自http://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/#more-79

Android有两类API在SDK中不能使用。

第一类就是位于包com.android.internal的API,我将这些API称为内部API。第二类API就是用@hide标记的类和函数,虽然严格说这不是一个API而是一系列隐藏API的集合,我仍然假定这是一个API,称为隐藏API。

隐藏API的例子

你阅读android的源码,就会发现有些常量、函数和类标记为@hide.

这里有一个隐藏常量的例子,来自WifiManager(source code of API Level 10).

另外一个例子是隐藏函数setWifiAppEnabled,来自WifiManager(source code of API Level 10).

所以您只要看到@hide属性,这就是一个隐藏API。

内部API和隐藏API的不同

隐藏API隐藏是为了防止开发人员使用SDK中未完成或者未稳定(接口和架构方面看)的部分。比如,Bluetooth API在API Level 5(android 2.0)之前就存在,但在API Level 3和4(android 1.5和1.6)中使用@hide隐藏起来了。当该API稳定下来,google的开发人员移除@hide属性,在API Level 5中就有Bluetooth API了。还有很多东西在Level 4和5之间发生了变化。如果程序依赖于某些隐藏API,可能会在新版本的Android OS上运行出现问题。

而内部API则不计划对外开放。这是android的内部餐厅,开发人员可以视为黑盒子。这里面的东西同样可能发生改变。同样的,如果您的程序依赖于内部API,在新的Android发布后,可能遇到麻烦。

下面总结它们之间的不同:

隐藏API = 正在开发中;

内部API = 黑盒

内部和隐藏API的编译时和运行时对比

当您使用Android SDK进行开发时,会引用一个非常重要的jar文件android.jar。它位于Android SDK的平台目录SDK_DIR/platforms/platform-X/android.jar(其中X为API Level,可以是5或者10或其它的数字)。在android.jar中,com.android.internal中所有的类移除了,同样的,所有标记为@hide的类、枚举、字段、方法也移除了。

但是当您在设备中运行应用程序时,加载的是framework.jar(大约等价于android.jar),它没有被裁减,包含所有的内部类和隐藏API。所以您可以使用反射机制来访问隐藏API和内部API(当然,这种方法使用起来不太方便,下面我将介绍不使用反射机制访问这些API的方法)。

关于内部API还有一些特别。Eclipse的ADT插件增加了一条额外规则,禁止使用来自com.android.internal包的任何东西。所以,即使您使用了原始(未裁减)的android.jar,也不容易在eclipse中使用内部API。

您可以自己检查一下。在eclipse中创建一个新的Android工程(或使用现有的),查看它的引用库(右键点击工程,Properties –http://mogoweb.net/files/categories/android-browser/page/> Java Build Path –http://mogoweb.net/files/categories/android-browser/page/> Libraries)。

重要总结:在SDK中内部API和隐藏API处理方式基本上相同(都从android.jar中移除),但内部API在Eclipse ADT插件中显示禁止了。

不通过反射机制使用内部API和隐藏API

本系列文章的终极目标是给程序员不用反射而使用内部API和隐藏API的方法。如果您完成了在后面文章中的所有步骤,您将可以向象使用官方API那样使用内部API和隐藏API,没有必要使用反射。

但是如果您使用这些非公开的API,必须意识到存在一个巨大的风险。首先不能保证这些API在Android OS升级后不会变化,其次也不能保证在不同厂家的不同设备上有一致的行为。这完全取决您自己。

有以下三种场景:

  1. 开启内部API和隐藏API(场景A)
  2. 仅开启隐藏API(场景B)
  3. 仅开启内部API(场景C)

场景A是场景B和C的综合。场景B是最简单的(不需要修改eclipse ADT插件)。

场景A:阅读1,2,3,4,5

场景B:阅读1,2,3,5

场景C:阅读1,2,3,4,5

分类: Android浏览器 标签:

设置Android平台开发环境

2011年6月22日 没有评论

注:本文并非关于如果使用Eclipse开发Android应用程序。

本文主要翻译自android的文档"Using Eclipse”,但去掉了关于mac部分的内容,并且更新了一些过时的内容。

基本设置

首先,需要确保常规的Android开发系统已经设置好,本文中使用$ANDROID_SOURCE指代android源码根目录。

cd $ANDROID_SOURCE

make

重要:Eclipse build仅仅用于错误检查。真正开发中还是需要在Eclipse中编辑代码,在shell中进行make。

Eclipse需要一个目录列表来搜索Java文件,称作"Java Build Path”,保存在.classpath文件。android提供了一个示例版本供参考。

cd $ANDROID_SOURCE

cp development/ide/eclipse/.classpath .

chmod u+w .classpath

如果需要的话,可以编辑该.classpath拷贝。

增加Eclipse的内存设置

Android工程很大,在编译时可能造成Eclipse的Java虚拟机内存耗光。我们可以通过修改eclipse.ini避免这一问题。在ubuntu下,eclipse.ini位于eclipse所在目录。

Eclipse 3.6(Helios)的内存相关设置的缺省值为:

-XX:MaxPermSize=256

-Xms40m

-Xmx384m

Android开发的推荐设置为

-Xms128m

-Xmx512m

-XX:MaxPermSize=256m

现在可以启动Eclipse

eclipse

首先为Android开发创建一个工程:

1. File http://mogoweb.net/files/categories/android-browser/page/> New http://mogoweb.net/files/categories/android-browser/page/> Java Project

2. 给一个工程名,比如"android”

3. 去掉Use default location前的勾选,点击Browse…按钮,选择$ANDROID_SOURCE路径。

4. 点击Finish

5. 等待工程建立

一旦工程的workspace创建起来,Eclipse就会开始building(取决于project菜单下的Build Automatically是否勾选)。理论上,build应该没有错误。

当同步代码时

每次同步代码库,或者在Eclipse外修改文件(特别是.classpath),您需要刷新Eclipse视图:

1. Window http://mogoweb.net/files/categories/android-browser/page/> Show View http://mogoweb.net/files/categories/android-browser/page/> Navigator

2. 在Navigator视图,右键点击工程名

3. 点击上下文菜单Refresh

添加Apps到Build路径

缺省的.classpath包含了和系统系统和一些示例app的代码,可能并没有包含您所需要的app。要添加app,您必须添加app的源路径,可以在Eclipse中进行:

1. Project http://mogoweb.net/files/categories/android-browser/page/> Properties

2. 在左手边菜单中选择"Java Build Path

3. 选择"Source”页

4. 点击"Add Folder…”

5. 添加您的app的src目录

6. 点击OK

完成后,列表中的"source folder”路径类似于:

android/packages/apps/YOURAPP/src

取决于您所包含的app,您可能还需要添加android/dalvik/libcore下其他的src目录。

Eclipse格式

您可以导入development/ide/eclipse下的文件,让Eclipse遵从Android的编码风格:

1. 选择Window http://mogoweb.net/files/categories/android-browser/page/> Preferences http://mogoweb.net/files/categories/android-browser/page/> Java http://mogoweb.net/files/categories/android-browser/page/> Code Style.

2. Use Formatter http://mogoweb.net/files/categories/android-browser/page/> Import导入android-formatting.xml

3. Organize Imports http://mogoweb.net/files/categories/android-browser/page/> Import导入android.importorder

使用Eclipse调试模拟器

您可以使用eclipse调试模拟器,单步跟踪代码。首先,启动模拟器:

cd $ANDROID_ROOT

. build/envsetup.sh

lunch 1

make

emulator

在另外一个shell,启动DDMS

cd $ANDROID_SOURCE

ddms

现在,在eclipse中,您可以attach到模拟器:

1. Run http://mogoweb.net/files/categories/android-browser/page/> Open Debug Dialog…

2. 右键点击"Remote Java Application”,选择"New”

3. 给一个名字,比如"android-debug”

4. 设置"Project”为您的工程名

5. 保持Host为"localhost”不变,但将端口改成8700

6. 点击"Debug”按钮。

在Eclipse 3.6中build android 2.3.4相关问题

按照上面的方法导入android 2.3.4源码后,出现如下问题:

Project ‘gingerbread’ is missing required library: ‘out/target/common/obj/JAVA_LIBRARIES/google-common_intermediates/javalib.jar’

Project ‘gingerbread’ is missing required library: ‘out/target/common/obj/JAVA_LIBRARIES/gsf-client_intermediates/javalib.jar’

解决的方法是,在Java Build Path中,点击Libraries标签页,移除这两个文件,然后点击Source标签页,点击Add Folder…按钮,加入frameworks/ex/common/java

再build,就不会有错误了。

分类: Android浏览器 标签: ,