Android使用隐藏api的方法(使用被@hide的api)

本文介绍了如何在Android开发中去除@hide标记的API,包括自制SDK、直接使用classes.jar及反射调用等方法,并提供了具体步骤。

今天去方案公司,看了build来build的去,我独自把Android系统的Audio整个流程部分复习一篇,看了他们辛苦的build,深感同情,看了一部分Audio程序,发现一些被表示@hide的常量和方法,自己总有一种占有欲和支配欲太强了,所以打算把@hide去掉,也参考网上的一些方法,不过晚上大部分的意见是通过反射的方法,我在下面总结,通过发射的方法我第一次见,是我打算写一个APP去让蓝牙配对,结果那个连接方法被hide了,所以那一次就有心想个办法处理掉.

<a> : 自制自己的SDK,然后用自己制作的SDK去开发APP,然后作为系统的APP安装在系统中,那么先拿到Android source code,make一个新的SDK,

    $ . build/envsetup.sh
    $ make sdk

或者:

$ . build/envsetup.sh
$ make PRODUCT-sdk-sdk

我用的是第二种方式.
<b> : 知道如何make SDK,那么就来修改一个作为例子,比如,修改AudioManager.java中STREAM_BLUETOOTH_SCO,这个蓝牙Strean type的常量本来是被标记的@hide,我需要它显示出来,那么就删除这个@hide,如下:(其他标记了@hide的常量和方法可以以此类推)

 

<c> : 然make SDK,其中获得android.jar,那么我们在app开发时,我们可以添加这个android.jar,似乎我的make速度很慢,现在还没有make出来,从以前build整个Android source生成的来看,它大致放在: out/host/linux-x86/sdk/android-sdk_eng.stevewang_linux-x86/platforms/android-4.2/目录下可以看到android.jar 文件,将android.jar放到Android APP工程libs下.

我想今天晚上它是make不完了,下次更新这个地方.

 

<2> : 不用删除@hide,那就要直接拿出Android的classes.jar库了,将这个库直接放到libs下,refresh一下工程就可以用了,不过这个方法有点让人郁闷,太耗内存了,eclipse可以增大内存并且关掉auto... build,否则eclipse卡的要死,会假死;

加载classes.jar库后如下:

 

<3> : 反射的方法,这种办法只是在以前连接蓝牙用过,下面是网友的:

使用Android隐藏的API主要有两种办法:1.利用Java反射机制,使用反射的方法得到隐藏API;2.使用源码编译时生成的全编译过的classes.jar包。

举例说明,下面的代码如果直接使用会报错。
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);  
       mWindow = PolicyManager.makeNewWindow(mContext);  
       mWindow.setWindowManager(mWindowManager, null, null);  
1,使用Java反射机制,改为以下代码,就可以正常使用了。

mWindowManager = (WindowManager) mContext  
                .getSystemService(Context.WINDOW_SERVICE);  
        // using reflect mechanism to invoke hide api   
        String POLICYMANAGER_CLASS_NAME = "com.Android.internal.policy.PolicyManager";  
        try {  
            Class policyClass;  
            policyClass = Class.forName(POLICYMANAGER_CLASS_NAME);  
            Log.i(TAG, policyClass.toString());  
            Method meths[] = policyClass.getMethods();  
            Method makenewwindow = null;  
            // Method makenewwindow = policyClass.getMethod("makeNewWindow");   
            for (int i = 0; i < meths.length; i++) {  
                if (meths[i].getName().endsWith("makeNewWindow"))  
                    makenewwindow = meths[i];  
            }  
            Log.i(TAG, makenewwindow.toString());  
            mWindow = (Window) makenewwindow.invoke(null, mContext);  
            } catch (Exception e) {  
            e.printStackTrace();  
        }  
        mWindow.setWindowManager(mWindowManager, null, null);  

http://qgjie456.blog.163.com/blog/static/35451367201252631615148/

 

 

本文参照了如下内容:

我所介绍的方法必须要在linux下编译,但仅仅只是编译sdk,开发还是在windows下,假如你现在还不会android源码编译,请先搞定这个,再往下看。下面的方法二真的是非常的方便,解决了我好多问题,强烈建议你耐心看看。

根据java 编程规范,我们知道这个api (静态变量)被隐藏掉了,所以在sdk中无法使用。在知道了原因之后,我们有几种解决方案(强烈建议使用方法二):

方法一:自己将源代码中的@hide去掉,然后编译一个sdk来替换默认的sdk。 
在linux上使用  make PRODUCT-sdk-sdk 命令,编译一个新的sdk出来,注意编译后其实我们不需要整个sdk,只需要android.jar这个文件替换掉sdk里的android.jar,例如:笔者的sdk里的jar对应的目录为:

F:/Program Files/Android/android-sdk-windows/platforms/android-8/android.jar

具体编译sdk的方法是,在linux编译环境下用命令make PRODUCT-sdk-sdk ,成功后,会有如下提示:

Package SDK: out/host/linux-x86/sdk/android-sdk_eng.stevewang_linux-x86.zip

我们进入到linux编译环境的 out/host/linux-x86/sdk/android-sdk_eng.stevewang_linux-x86/platforms/android-2.2/目录下可以看到android.jar 文件。使用此文件替换   F:/Program Files/Android/android-sdk-windows/platforms/android-8/android.jar 即可。替换前记得备份

此方法较为麻烦,建议使用方法二

方法二:添加framework 编译出来的classes.jar文件到eclipse的build path 
其实在编译android的时候,我们将framework 编译到一个临时的jar包中了,这个jar包的路径一般为:
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
我们只需要在linux上android源代码目录下使用make 命令即可生成此文件。

由于这个jar文件中的api 还没有重新打包,里面被@hide掉的api并没有被去掉。所以我们依然能够引用里面被@hide的api。而sdk 中的android.jar文件时重新打包生成的,其里标记有@hide的api已经被去掉了。所以我们把 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar 拷贝到本地pc上。然后在工程中添加此jar包。
具体方法:
1 . 拷贝linux编译生成的  out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar到本机PC。
2,在eclipse的Android项目中,选择项目属性->Java Build Path->Libraries->Add Library->User Library->Next-> UserLibraries进入到User Libraries管理界面,点击New新建一个User Library,比如android_framework,点击Add Jars把Jar包加入到建立的User Library中,最后点击OK。
3.选择项目属性->Java Build Path->Order and Export,使用右面的“UP”键,把所建立的User Libraries移到Android SDK的上面。这样做的意思就是优先使用classes.jar中的API,其次使用android.jar中的API。为什么不直接使用classes.Jar?因为我在使用时发现,android.jar中有的东西classes.jar中没有。
如下图:
 
之后我们的工程错误消失了:
 
到此问题基本解决.

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值