JAVA: 達成可以在外部使用{@hide}的class

為了要達成JAVA可以在外部使用{@hide}的class, 我上網找了一些資料發現是可行的! 現在分享一下

1. 一切的初始來自這網頁, 原本我以為唯一方法是將{@hide}拿掉

http://www.answerspice.com/c119/1485505/where-is-androidossystemproperties

Where is android.os.SystemProperties
I’m looking at the Android Camera code and when I try importing android.os.SystemProperties
It cannot be found.

here is the file I’m looking at. [HERE]

I created a new 2.1 project and tried importing this namespace again, but It still cannot be found. I checked developer.android.com and SystemProperties was not listed
Did i miss something?

==Answer==
This is the class in the Android source code
http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/os/SystemProperties.java&sa=N&cd=1&ct=rc

See {@hide} in the class JavaDoc? That means this class won’t be exported as part of the public SDK.

The camera app uses it as it’s internal and they won’t use the public SDK to build it.

You may still be able to get at this class
(1) by reflection
or
(2) by getting the source, removing @hide and making your own customized SDK.
However pretty much by definition you are now going ‘off SDK’ and therefore your app may well be broken or get different behavior on OS versions as the Android folks will make little effort not to change this class between versions.

2. 於是我先試了方法二 (2) by getting the source, removing @hide and making your own customized SDK.

這的確是滿快的方式, 就是你只要將前面註解的@hide 移除, 再重新compile即可, 系統會自動更新current.xml 然後work!

3. java反射机制 也就是(1) by reflection
為了保持原本source的完整性, 不要去更改. 那麼就是方法一
然而這個方法通常都是比較複雜的, 因為畢竟是外部調用嘛
找到的資料大多是Integer為參數的例子
http://java.sun.com/developer/technicalArticles/ALT/Reflection/

try {
Class cls = Class.forName(“method2”);
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod(
“add”, partypes);
method2 methobj = new method2();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj
= meth.invoke(methobj, arglist);
Integer retval = (Integer)retobj;
System.out.println(retval.intValue());
}
catch (Throwable e) {
System.err.println(e);
}

http://tech.srcsky.com/developer/java/371072.html

//Class classType = operationClass.class;
// 返回本类对象
Object invokeOperation = classType.newInstance();
if (oper.equals(“+”)) {
// 根据类对象名称去查找对应的方法
Method addMethod = classType.getMethod(“add”, new Class[] {
int.class, int.class });
// 调用查找 到的方法执行此方法的处理
Object result = addMethod.invoke(invokeOperation, new Object[] {
new Integer(first), new Integer(second) });

然而String的例子真的不多! 所以只能try and error, 最後有找到

c= Class.forName(“quicktime.util.QTHandle”);
String s= new String(“PICT”);
c = Class.forName(“quicktime.util.QTUtils”);
m = c.getMethod(“toOSType”, new Class[] { s.getClass() });
Integer type= (Integer)m.invoke(null, new Object[] { s });

我最後的寫法

Class hideClass = Class.forName(“android.os.SystemProperties”);
invokeOperation = hideClass.newInstance();
get_Method = hideClass.getMethod(“get”, String.class);
final String dmi_manu= (String)get_Method.invoke(null, new Object[] { new String(“dmi.manu”) });

4 thoughts on “JAVA: 達成可以在外部使用{@hide}的class

發表迴響