如何调用Android隐藏API


作为Android应用的开发者,在Android平台上开发,最熟悉的莫过于android sdk。SDK给开发者带来的巨大的便利,使得Android平台的应用开发效率大大提高。不过遗憾的是,Android的功能远不止SDK暴露的那么多,还有很多隐藏的东西Google都没有通过SDK暴露给用户开发者。查看Android源代码时就会发现,这些隐藏的API都有一个共同的特点:类或者方法前都有@hide。如图:

<ignore_js_op>

一、如何隐藏API的?

1)  在正常情况下,即不加@hide的时候,所有的public的类或者方法,在编译时都会编译生成到stub library的jar文件中。这个stub library其实是个空实现,但是它包含了所有的public方法。所以用这个stub library,应用开发者就可以在eclipse中进行开发了。

2)  但一旦加了@hide,那么在编译生成stublibrary时,凡是被@hide标记的类或者方法都被移除了。所以应用开发者就无法通过这个stub library“直接”调用被隐藏的类或者方法。如果强行在eclipse里调用隐藏的类或者方法,则eclipse会报错。典型的例子就是Android SDK中的android.jar,这个stub library所包含的就是已经被移除的的API。上图中,ActivityManager的forceStopPackage()方法在Android SDK中是无法找到的。

二、隐藏的API可以调用吗?

1)  那么应用开发者可以使用这些隐藏的API吗? 答案是肯定的。在真实的运行环境中,所有的API都是存在的并且是被实现的。那么很容易就会想到用“反射”。如果我们已经知道目标类的类名和方法名,以及参数列表,那么这样的方法即使被@hide了,我们依然可以通过反射来调用它。对于Java反射,这里我们不准备展开,不是很了解的同学请自行学习研究。下面是一个反射的例子。

IActivitManageram = ActivityManagerNative.getDefault();

Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class); forceStopPackage.setAccessible(true);

forceStopPackage.invoke(am, yourpkgname);  

2)  反射虽好,不过写起来真麻烦,本来一个调用代码,一行就可以搞定,但是现在用发射写的话,需要好多行。有没有其他更加方便的办法呢,其实是有的。上面我们提到在Android SDK中的android.jar是一个阉割版,如果我们能生成一个完整版,这个问题就迎刃而解了。方法是现在整套Android源代码,然后做一次完整的编译。在out/target/common/obj/JAVA_LIBRARIES/目录下可以根据需要提取自己所要的stublibrary。以framework为例:将out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar复制到eclipse开发环境中,用userlibrary的方式挂载,使其的优先级比android.jar要高即可。

以下是在eclipse中的设置步骤:

<ignore_js_op> 
<ignore_js_op> 
<ignore_js_op> 
<ignore_js_op> 
<ignore_js_op> 
<ignore_js_op> 
<ignore_js_op> 
<ignore_js_op> 
<ignore_js_op>

三、需要注意的一些问题

1)  无论是反射还是使用自编译的stublibrary,只能解决调用隐藏API的问题,而无法越过权限检查。

2)  Google之所以将有些API隐藏,有些原因可能是因为这些API属于内部逻辑,不想对外暴露,也有可能是API接口还未最终确定下来。所以在低版本Android上的隐藏API不一定能在高版本的Android上使用。这点是一定要注意的。也就说隐藏API的兼容性比较差。因此利用反射调用隐藏API时,一定要注意根据Android的版本采用不同的方式去反射。

分类: android solve

时间: 2024-10-14 11:18:09

如何调用Android隐藏API的相关文章

Unity调用Android的API实现分享功能&lt;转&gt;

问题:如何在unity3d的游戏中实现分享功能,如图 思路: 1.分享功能的实现方式有多种,较方便快捷的一种是直接调用android的API来调出系统的分享界面 2.unity3d里面调用android的API需要为此编写一个android的插件 3.在插件(android的jar包)里面调用Intent类来实现Activity间的消息传递,换出系统的分享控制台 代码: Android插件代码 1 package com.XXX.XXX; 2 3 import android.content.I

Android初学------使用Android隐藏API

通过编译Android源码 得到class.jar 里面包含了很多Android 的各种api封装类 . 然后 你可以获取到  这样一个jar文件,里面包含了:   这样一些你是用不了的类,但是呢,我们要让他变成我们可以使用的类,. 就需要这样做了. 第一步:  导出解压出你需要的class 文件 如图:   我把os里面的一些class 文件解压出来了, 因为里面有我需要的一些类..... 然后呢...... 变class 为jar文件 怎么变呢 参考 :http://blog.sina.co

Android工程中怎样使用隐藏API

使用android 隐藏api的前提:我们需要得到Android系统源码编译输出的一个文件 out\\target\\common\\obj\\JAVA_LIBRARIES\\framework_intermediates\\classes.jar 这个包里面包含所有的系统api, 隐藏的, 公开的 添加 jar方法 右键功能菜单->Properties->Java Build Path Libraries选项卡 这时应该有一个列表,  如果你没有添加过, 应该只有一项, 就是系统自带的And

Android应用开发中如何使用隐藏API(转)

一开始需要说明的是,Google之所以要将一些API隐藏(指加上@hide标记的public类.方法或常量)是有原因的.其中很大的原因就是Android系统本身还在不断的进化发展中.从1.0.1.1到现在即将问世的Android 2.3.4. 这些隐藏的API本身可能是不稳定的,所以,使用隐藏API,意味着程序更差的兼容性. 如果要我给出建议的话,最好还是不要使用隐藏的API.不过有时为了实现Android应用某些特殊的功能或者效果,隐藏的API往往能发挥意想不到的作用.这些API具体能做些什么

Android应用开发中如何使用隐藏API

一开始需要说明的是,Google之所以要将一些API隐藏(指加上@hide 标记的public类.方法或常量)是有原因的.其中很大的原因就是Android系统本身还在不断的进化发展中.从1.0.1.1到现在即将问世的Android 2.3.4. 这些隐藏的API本身可能是不稳定的,所以,使用隐藏API,意味着程序更差的兼容性. 如果要我给出建议的话,最好还是不要使用隐藏的API.不过有时为了实现Android应用某些特殊的功能或者效果,隐藏的API往往能发挥意想不到的作用.这些API具体能做些什

cocos2d-x调用android内嵌浏览器打开网页

cocos2d-x调用android内嵌浏览器打开网页,可以从入口传入网址,C++调用android 的api即可实现.方法也很简单 1. 修改"cocos2dx\platform\win32"下的CCApplication.h和CCApplication.cpp,添加函数 头文件声明 void openURL(const char* pszUrl); cpp文件实现: void CCApplication::openURL(const char* pszUrl) { ShellExe

Android中的隐藏API和Internal包的使用之获取应用电量排行

今天老大安排一个任务叫我获取手机中应用耗电排行(时间是前天晚上7点到第二天早上10点),所以在网上各种搜索,没想到这种资料还是很多的,发现了一个主要的类:PowerProfile,但是可以的是,这个类没有曝光给我们开发者,所以我们不能调用它 那怎么办呀?,还是有办法的,这个类是藏在:com.android.internal.os.PowerProfile com.android.internal.os.PowerProfile.PowerProfile这个类就是负责解析记录文件,我们可以创建一个

Android 内部API (com.android.internal)和隐藏API(@hide)概述

内部API和隐藏代码的例子 在翻阅Android源码的时候有时会遇到一些奇怪的代码,例如下面这个: //注:这段代码在源码android/provider/Telephony.java中. import android.util.Patterns; import com.android.internal.telephony.SmsApplication; import java.util.HashSet; //-- 还有这种(下面这段摘自同一文件):         /**          *

如何调用系统隐藏的API,或者使用系统未开放的类

一.反射 可以通过反射来调用系统隐藏的API, 但对于已经被系统隐藏的类似乎不太行得通. 二.使用系统源码编译后的classes.jar 路径:out/target/common/obj/JAVA_LIBRARIES/framework_intermediates 将此jar包添加到项目中后,在使用系统相关类或者隐藏的API时,就不会出现错误标识的小红点提示. 需要注意的是: 1,在manifest中标识:android:sharedUserId="android.uid.system"