±à¼ÍƼö: |
±¾ÎÄÖ÷Òª½éÉÜ·´ÉäµÄ¶¨ÒåÒÔ¼°×é³É£¬·´ÉäµÄ¼òµ¥ÊÂÀýÒÔ¼°·´ÉäÔÚAndroid¿ò¼Ü²ãµÄÓ¦Óã¬Ï£Íû¶ÔÄúµÄѧϰÓÐËù°ïÖú¡£
±¾ÎÄÀ´×ÔÓÚ΢ÐŹ«Öںţ¬ÓÉ»ðÁú¹ûÈí¼þAlice±à¼¡¢ÍƼö¡£ |
|
1.·´ÉäµÄ¶¨ÒåÒÔ¼°×é³É
¹ØÓÚ·´É䣬һ°ãÊéÉϵ͍ÒåÊÇÕâÑùµÄ:JAVA·´Éä»úÖÆÊÇÔÚÔËÐÐ״̬ÖУ¬¶ÔÓÚÈÎÒâÒ»¸öÀ࣬¶¼Äܹ»ÖªµÀÕâ¸öÀàµÄËùÓÐÊôÐԺͷ½·¨£»¶ÔÓÚÈÎÒâÒ»¸ö¶ÔÏ󣬶¼Äܹ»µ÷ÓÃËüµÄÈÎÒâ·½·¨ºÍÊôÐÔ£»ÕâÖÖ¶¯Ì¬»ñÈ¡ÐÅÏ¢ÒÔ¼°¶¯Ì¬µ÷ÓöÔÏó·½·¨µÄ¹¦ÄܳÆÎªjavaÓïÑԵķ´Éä»úÖÆ£¬Õ⼸¾ä½âÊÍ˵Ã÷ÁË·´ÉäµÄ×÷Ó㬶¯Ì¬µÄ¸úÀà½øÐн»»¥£¬±ÈÈç»ñÈ¡Òþ²ØÊôÐÔ£¬ÐÞ¸ÄÊôÐÔ£¬»ñÈ¡¶ÔÏ󣬴´½¨¶ÔÏó»òÕß·½·¨µÈµÈ£¬×ÜÖ®¾ÍÒ»¾ä»°:
·´ÉäÊÇÒ»ÖÖ¾ßÓÐÓëÀà½øÐж¯Ì¬½»»¥ÄÜÁ¦µÄÒ»ÖÖ»úÖÆ ΪʲôҪǿµ÷¶¯Ì¬½»»¥ÄØ£¿
ÒòΪһ°ãÇé¿ö϶¼ÊǶ¯Ì¬¼ÓÔØ£¬Ò²¾ÍÊÇÔÚÔËÐеÄʱºò²Å»á¼ÓÔØ£¬¶ø²»ÊÇÔÚ±àÒëµÄʱºò£¬ÔÚÐèÒªµÄʱºò²Å½øÐмÓÔØ»ñÈ¡£¬»òÕß˵Äã¿ÉÒÔÔÚÈκÎʱºò¼ÓÔØÒ»¸ö²»´æÔÚµÄÀൽÄÚ´æÖУ¬È»ºó½øÐи÷ÖÖ½»»¥,»òÕß»ñȡһ¸öûÓй«¿ªµÄÀàµÄËùÓÐÐÅÏ¢£¬»»¾ä»°Ëµ£¬¿ª·¢Õß¿ÉÒÔËæÊ±ËæÒâµÄÀûÓ÷´ÉäµÄÕâÖÖ»úÖÆ¶¯Ì¬½øÐÐÒ»Ð©ÌØÊâµÄÊÂÇé¡£
·´ÉäµÄ×é³É
ÓÉÓÚ·´Éä×îÖÕÒ²±ØÐëÓÐÀà²ÎÓ룬Òò´Ë·´ÉäµÄ×é³ÉÒ»°ãÓÐÏÂÃæ¼¸¸ö·½Ãæ×é³É:
1.java.lang.Class.java£ºÀà¶ÔÏó£»
2.java.lang.reflect.Constructor.java£ºÀàµÄ¹¹ÔìÆ÷¶ÔÏó£»
3.java.lang.reflect.Method.java£ºÀàµÄ·½·¨¶ÔÏó£»
4.java.lang.reflect.Field.java£ºÀàµÄÊôÐÔ¶ÔÏó£»
ÏÂÃæÒ»ÕÅͼ˵Ã÷Á˹ØÏµ:

¸ù¾ÝÐéÄâ»úµÄ¹¤×÷ÔÀí,Ò»°ãÇé¿öÏ£¬ÀàÐèÒª¾¹ý:¼ÓÔØ->ÑéÖ¤->×¼±¸->½âÎö->³õʼ»¯->ʹÓÃ->Ð¶ÔØÕâ¸ö¹ý³Ì£¬Èç¹ûÐèÒª·´ÉäµÄÀàûÓÐÔÚÄÚ´æÖУ¬ÄÇôÊ×ÏȻᾹý¼ÓÔØÕâ¸ö¹ý³Ì£¬²¢ÔÚÔÚÄÚ´æÖÐÉú³ÉÒ»¸öclass¶ÔÏó£¬ÓÐÁËÕâ¸öclass¶ÔÏóµÄÒýÓ㬾ͿÉÒÔ·¢»Ó¿ª·¢ÕßµÄÏëÏóÁ¦£¬×ö×Ô¼ºÏë×öµÄÊÂÇéÁË¡£
·´ÉäµÄ×÷ÓÃ
Ç°ÃæÖ»ÊÇ˵ÁË·´ÉäÊÇÒ»ÖÖ¾ßÓÐÓëJavaÀà½øÐж¯Ì¬½»»¥ÄÜÁ¦µÄÒ»ÖÖ»úÖÆ£¬ÔÚJavaºÍAndroid¿ª·¢ÖУ¬Ò»°ãÇé¿öÏÂÏÂÃæ¼¸ÖÖ³¡¾°»áÓõ½·´Éä»úÖÆ.
¡ñ ÐèÒª·ÃÎÊÒþ²ØÊôÐÔ»òÕßµ÷Ó÷½·¨¸Ä±ä³ÌÐòÔÀ´µÄÂß¼£¬Õâ¸öÔÚ¿ª·¢Öкܳ£¼ûµÄ£¬ÓÉÓÚһЩÔÒò£¬ÏµÍ³²¢Ã»Óпª·ÅһЩ½Ó¿Ú³öÀ´£¬Õâ¸öʱºòÀûÓ÷´ÉäÊÇÒ»¸öÓÐЧµÄ½â¾ö·½·¨
¡ñ ×Ô¶¨Òå×¢½â£¬×¢½â¾ÍÊÇÔÚÔËÐÐʱÀûÓ÷´Éä»úÖÆÀ´»ñÈ¡µÄ¡£
¡ñÔÚ¿ª·¢Öж¯Ì¬¼ÓÔØÀ࣬±ÈÈçÔÚAndroidÖеĶ¯Ì¬¼ÓÔØ½â¾ö65kÎÊÌâµÈµÈ£¬Ä£¿é»¯ºÍ²å¼þ»¯¶¼Àë²»¿ª·´É䣬À뿪ÁË·´Éä´ç²½ÄÑÐС£
·´ÉäµÄ¹¤×÷ÔÀí
ÎÒÃÇÖªµÀ£¬Ã¿¸öjavaÎļþ×îÖÕ¶¼»á±»±àÒë³ÉÒ»¸ö.classÎļþ£¬ÕâЩClass¶ÔÏó³ÐÔØÁËÕâ¸öÀàµÄËùÓÐÐÅÏ¢£¬°üÀ¨¸¸Àà¡¢½Ó¿Ú¡¢¹¹Ô캯Êý¡¢·½·¨¡¢ÊôÐԵȣ¬ÕâЩclassÎļþÔÚ³ÌÐòÔËÐÐʱ»á±»ClassLoader¼ÓÔØµ½ÐéÄâ»úÖС£
µ±Ò»¸öÀà±»¼ÓÔØÒÔºó£¬JavaÐéÄâ»ú¾Í»áÔÚÄÚ´æÖÐ×Ô¶¯²úÉúÒ»¸öClass¶ÔÏó,¶øÎÒÃÇÒ»°ãÇé¿öÏÂÓÃnewÀ´´´½¨¶ÔÏó£¬Êµ¼ÊÉϱ¾Öʶ¼ÊÇÒ»ÑùµÄ£¬Ö»ÊÇÕâЩµ×²ãÔÀí¶ÔÎÒÃÇ¿ª·¢Õß͸Ã÷°ÕÁË£¬ÎÒÃÇÇ°ÃæËµÁË£¬ÓÐÁËclass¶ÔÏóµÄÒýÓ㬾ÍÏ൱ÓÚÓÐÁËMethod,Field,ConstructorµÄÒ»ÇÐÐÅÏ¢£¬ÔÚJavaÖУ¬ÓÐÁ˶ÔÏóµÄÒýÓþÍÓÐÁËÒ»ÇУ¬Ê£ÏÂÔõô·¢»ÓÊÇ¿ª·¢Õß×Ô¼ºµÄÏëÏóÁ¦ËùÄܾö¶¨µÄÁË¡£
2.·´ÉäµÄ¼òµ¥ÊÂÀý
Ç°ÃæËµÁËÕâô¶àÀíÂÛ£¬ÏÂÃæ¼òµ¥Êµ¼ùÒ»ÏÂ
public class
Student {
private int age;//ÄêÁä
private String name;//ÐÕÃû
private String address;//µØÖ·
private static String sTest;
public Student() {
throw new IllegalAccessError("Access to default
Constructor Error!");
}
private Student(int age, String name, String address)
{
this.age = age;
this.name = name;
this.address = address;
sTest = "²âÊÔ·´Éä";
}
private int getAge() {
return age;
}
private void setAge(int age) {
this.age = age;
}
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
private String getAddress() {
return address;
}
private void setAddress(String address) {
this.address = address;
}
private static String getTest() {
return sTest;
}
} |
ÔÚÕâÀïΪÁËÁ·Ï°£¬¿ÌÒâÓÃÁËprivateÀ´ÐÞÊγÉÔ±±äÁ¿ºÍ·½·¨ ÏÂÃæ´úÂëÓù¹ÔìÆ÷£¬·½·¨ºÍÊôÐԺ;²Ì¬·½·¨·Ö±ðÀ´»ñȡһÏ£º
public class
StudentClient {
public static void main(String[] args) throws
Exception{
Class<?> clazz=Class.forName("ClassLoader.Student");
Constructor constructors=clazz.getDeclaredConstructor(int.class, String.class,String.class);
constructors.setAccessible(true);
//ÀûÓù¹ÔìÆ÷Éú³É¶ÔÏó
Object mStudent=constructors.newInstance(27,"СÎÄ", "±±¾©Êк£¶¨ÇøXXºÅ");
System.out.println(mStudent.toString());
//»ñÈ¡Òþ²ØµÄintÊôÐÔ
Field mAgeField=clazz.getDeclaredField("age");
mAgeField.setAccessible(true);
int age= (int) mAgeField.get(mStudent);
System.out.println("ÄêÁäΪ:"+age);
//µ÷ÓÃÒþ²ØµÄ·½·¨
Method getAddressMethod=clazz.getDeclaredMethod("getAge");
getAddressMethod.setAccessible(true);
int newage= (int) getAddressMethod.invoke(mStudent);
System.out.println("ÄêÁäΪ:"+newage);
//µ÷Óþ²Ì¬·½·¨
Method getTestMethod=clazz.getDeclaredMethod("getTest");
getTestMethod.setAccessible(true);
String result= (String) getTestMethod.invoke(null);
System.out.println("µ÷Óþ²Ì¬·½·¨:"+result);
}
} |
½á¹ûÈçÏÂ:

´ó¼Ò¶¼¿´µÃ¶®£¬Ó¦¸Ã¿ÉÒÔÀí½â£¬ÓÐͬѧ˵²»ÊÇÓкܶàgetDeclared***ºÍget***µÄ·½·¨Âð£¬
ʵ¼ÊÉ϶¼²î²»¶àµÄ£¬Ö»²»¹ýÓõķ¶Î§²»Ò»Ñù¶øÒÑ¡£
getDeclared***»ñÈ¡µÄÊǽöÏÞÓÚ±¾ÀàµÄËùÓеIJ»ÊÜ·ÃÎÊÏÞÖÆµÄ£»
¶øget***»ñÈ¡µÄÊǰüÀ¨¸¸ÀàµÄµ«½öÏÞÓÚpublicÐÞÊηûµÄ¡£
FieldºÍMethodÒ²ÊÇÒ»ÑùµÄµÀÀí£¬Õâ¸ö´ó¼Ò×¢ÒâһϾͺá£
×îºóÒ»¸öÐèҪעÒâµÄÊǵ÷Óþ²Ì¬·½·¨ºÍµ÷ÓÃʵÀý·½·¨ÓеãÇø±ð£¬µ÷ÓÃʵÀý·½·¨Ò»¶¨ÐèÒªÒ»¸öÀàµÄʵÀý£¬¶øµ÷Óþ²Ì¬·½·¨²»ÐèҪʵÀýµÄÒýÓã¬ÆäʵÕâÊÇJVMµÄÔÚÖ´Ðз½·¨ÉϵÄÓÐËùÇø±ð¡£
JVMÔÚÖ´Ðз½·¨µÄʱºò»á´´½¨Ò»¸ö¶ÑÕ»£¬¶ÑÕ»ÀïÃæ±£´æÁ˾ֲ¿±äÁ¿±íÒÔ¼°ÆäËûµÄһЩ±ØÒªµÄÐÅÏ¢£¬ÆäÖоֲ¿±äÁ¿±íÀïÃæÒ²°üº¬Á˾ֲ¿²ÎÊý£¬¶ø¾Ö²¿²ÎÊýÀïÃæ±£´æÁ˵±Ç°·½·¨µÄÐβΣ¬Èç¹ûÊǵ÷ÓÃʵÀý·½·¨µÄ»°£¬ÄÇôÐβεĵÚÒ»¸ö²ÎÊý¾ÍÊǵ±Ç°µÄÀàµÄÒýÓÃÁË£¬¶øµ÷ÓõÄÊǾ²Ì¬·½·¨µÄ»°£¬ÄÇôµÚÒ»¸ö²ÎÊýÊÇΪnullµÄ£¬ÕâÒ»µãÎÞ·¨Í¨¹ýÈκÎÊÖ¶ÎÈ¥ÈÆ¹ý£¬»»¾ä»°Ëµµ÷ÓÃʵÀý·½·¨Ò»¶¨ÐèÒªÒ»¸öÀàµÄÒýÓ㬹ØÓÚÕâÒ»µã£¬¶ÁÕß¿ÉÒÔ×Ô¼ºÈ¥²éÔÄÓйØJVMµÄÊé¼®¡£
µ±È»ÁË£¬·´ÉäµÄ×÷Óþø²»Ö¹ÕâЩ£¬ÔÚÊý×飬·ºÐÍ£¬Éè¼ÆÄ£Ê½µÈ·½ÃæÒÀÈ»·¢»ÓÁ˾޴óµÄ×÷Ó㬵«ÔÀí²¢Ã»ÓÐÍÑÀëÉÏÃæËµµÄ£¬¶ÁÕß¿ÉÒÔ¶à²é¿´Ïà¹ØÔ´Âëѧϰ£¬Ô´Âë¾ÍÊÇ×îºÃµÄѧϰ×ÊÔ´¡£
3.·´ÉäÔÚAndroid¿ò¼Ü²ãµÄÓ¦ÓÃ
ÕâÊDZ¾ÎÄÐèÒªÖØµã˵Ã÷µÄ£¬ÖÚËùÖÜÖª£¬AndroidÖеÄFrameWorkÊÇÓÃJavaÓïÑÔ±àдµÄ£¬×ÔÈ»Àë²»¿ªÒ»Ð©·´ÉäµÄÓ°×Ó£¬¶øÀûÓ÷´Éä¸üÊÇ¿ÉÒÔ´ïµ½ÎÒÃÇһЩ³£¹æ·½·¨ÄÑÓÚ´ïµ½µÄÄ¿µÄ£¬ÔÙÕß·´ÉäÒ²ÊÇJava²ãÖнøÐÐHookµÄÖØÒªÊֶΣ¬Ä¿Ç°µÄ²å¼þ»¯¸üÊÇ´óÁ¿ÀûÓ÷´Éä¡£
Ê×ÏÈÌá³öÐèÇó:ÈçºÎ¼à¿ØActivityµÄ´´½¨ºÍÆô¶¯¹ý³Ì£¿ ÓÐͬѧ˵ÁË£¬ÎÒÔÚActivityÀïÃæÖØÐ´ÉúÃüÖÜÆÚ·½·¨²»¾Í¿ÉÒÔÁËÂð£¿
ʵ¼ÊÉÏÕâ¸öÊÇ´ï²»µ½ÐèÇóµÄ£¬ÒòΪºÜ¼òµ¥£¬ÕâЩÉúÃüÖÜÆÚ·½·¨µÄµ÷ÓÃÊÇÔÚ´´½¨ºÍÆô¶¯Ö®ºóºÜ¾ÃµÄÊÂÇéÁË£¬ÀïÃæµÄÉúÃüÖÜÆÚ·½·¨Ïà¶ÔÓÚÕû¸öActivityÀ´ËµÊDZȽϺóÃæµÄÊÂÇ飬ҪÏë½â¾öÕâ¸öÎÊÌ⣬±ØÐëÒªÖªµÀActivityÊÇÔõôÀ´£¬Öм侹ýÁËÄĸöÁ÷³Ì£¬×îºóÈ¥ÁËÄÄÀֻÓÐÃ÷°×ÁËÕâЩ£¬²ÅÄÜÖªµÀÔÚÄĸö½×¶Î×öÄÄЩÊÂÇ飬ÎÒÃÇÖªµÀ£¬ActivityµÄÆô¶¯ÊÇÒ»¸öIPC¹ý³Ì£¬Ò²¾ÍÊÇBinder»úÖÆ£¬ÀïÃæ¾¹ýÁ˱¾µØ½ø³Ì->AMS½ø³Ì-->Ôٻص½±¾µØ½ø³Ì£¬ÏÂÃæÊÇʵÀýͼ:

ͼ»µÄÓÐЩ´Ö²Ú£¬´ó¼Ò½«¾Í¿´°É£¬´ÓÉÏÃæ¿ÉÒÔ¿´µ½£¬Activity´Ó±¾µØµ½Ô¶³ÌAMSÒÔºó£¬Ô¶³ÌAMSÖ»ÊÇ×öÁËȨÏÞÒÔ¼°ÊôÐԵļì²é,È»ºóÔٻص½±¾µØ½ø³Ì£¬Õâ²Å¿ªÊ¼ÕæÕýµÄ´´½¨ºÍ¼ì²é£¬ÎÒÃDzŴúÂëÀ´·ÖÎöһϣ¬Éæ¼°µ½µÄÀàÓÐHandlerÒÔ¼°ActivityThreadºÍInstrumentationÀà,Ê×ÏÈ´ÓÔ¶¶Ë½ø³Ì»Øµ½±¾µØ½ø³ÌÖ®ºó£¬ÏµÍ³µÄHandlerÀàH»á·¢ËÍÒ»¸öÏûÏ¢:LAUNCH_ACTIVITY,´úÂëÈçÏÂ:Ê¡ÂÔÁËһЩ·Ç±ØÒª´úÂ룬²»È»Æª·ùÌ«³¤,ÏÂÃæµÄ´úÂë¶¼ÊÇÔÚActivityThread.javaÀïÃæµÄ
public void handleMessage(Message
msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>>
handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"activityStart");
final ActivityClientRecord r = (ActivityClientRecord)
msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} |
Ëæºóµ÷ÓÃÁËhandleLaunchActivity·½·¨£¬handleLaunchActivity·½·¨ÀïÃæÓÖµ÷ÓÃÁË
performLaunchActivity·½·¨£¬´úÂëÈçÏÂ:
private void
handleLaunchActivity(ActivityClientRecord r, Intent
customIntent, String reason) {
// If we are getting ready to gc after going to
the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
// Make sure we are running with the most recent
config.
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
// Initialize before creating the activity
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
....
} |
ÔÚperformLaunchActivityÀïÃæÖÕÓÚ´´½¨ÁËActivityÁË£¬½øÈëperformLaunchActivityÀïÃæ¿´¿´ÓÐÒ»¶Î·Ç³£ºËÐĵĴúÂë:
Activity activity
= null;
try {
//
java.lang.ClassLoader cl = r.packageInfo.getClassLoader
();
//ͨ¹ýmInstrumentation.newActivity()·½·¨´´½¨ÁËActivity,mInstrumentationÊÇInstrumentationÀàµÄʵÀý
£¬¶ÔÏóµÄÀàΪ:Instrumentation.java
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount (activity
. getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e))
{
throw new RuntimeException( "Unable to
instantiate activity " + component
+ ": " + e.toString(), e);
}
} |
ÎÒÃÇÏÖÔÚÒѾ֪µÀÁËActivityµÄ´´½¨ÁË£¬ÊÇÓÉ Instrumentation
µÄ newActivity() ·½·¨ÊµÏÖ£¬ÎÒÃÇ¿´Ò»Ï·½·¨:
public Activity
newActivity(Class<?> clazz, Context context,
IBinder token, Application application, Intent
intent , ActivityInfo info,
CharSequence title, Activity parent, String id,
Object lastNonConfigurationInstance) throws InstantiationException,
IllegalAccessException {
Activity activity = (Activity)clazz.newInstance();
ActivityThread aThread = null;
activity.attach(context, aThread, this, token,
0, application, intent,
info, title, parent, id,
(Activity.NonConfigurationInstances) lastNonConfigurationInstance,
new Configuration(), null, null, null);
return activity;
} |
¿´µ½Ã»£¬×÷ΪËÄ´ó×é¼þµÄActivityÆäʵҲÊÇÒ»¸öÆÕͨ¶ÔÏó£¬Ò²ÊÇÓÉ·´Éä´´½¨µÄ£¬Ö»²»¹ýÓÉÓÚ¼ÓÈëÁËÉúÃüÖÜÆÚ·½·¨£¬²ÅÓÐ×é¼þÕâ¸ö»îÉúÉúµÄ¶ÔÏó´æÔÚ£¬
ËùÒÔ˵AndroidÖз´ÉäÎÞ´¦²»ÔÚ£¬·ÖÎöÍêÁËÆô¶¯ºÍ´´½¨µÄ¹ý³Ì£¬»Øµ½¸Õ²ÅÄǸöÐèÇóÀ´Ëµ£¬ÈçºÎ¼à¿ØActivityµÄÆô¶¯ºÍ´´½¨ÄØ£¿
¶ÁÕß¿ÉÒÔÏÈ×Ô¼ºÏëһϣ¬Ê×ÏÈÆô¶¯ÊÇÓÉHandlerÀ´·¢ËÍÏûÏ¢£¬¾ßÌåµÄÔÚÀïÃæhandlerMessage·½·¨ÊµÏֵģ¬
ÕâÒ²ÊÇHandlerÀïÃæµÄ´¦Àí´úÂëµÄ˳Ðò£¬ÈçÏ´úÂë:
public void dispatchMessage(Message
msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
} |
´ó²»ÁËÎÒÃÇ×Ô¼ºÅªÒ»¸ö×Ô¶¨ÒåµÄHandler.Callback½Ó¿Ú£¬È»ºóÌæ»»µôÄǸöHÀàÀïÃæµÄ´¦Àí½Ó¿Ú£¬ÕâÑù¾Í¿ÉÒÔ¼à¿ØActivityµÄÆô¶¯ÁË£¬ºÃ·½·¨£¬ÎÒÃÇÀ´Ð´Ò»Ï´úÂë:
public static
void hookHandler(Context context) throws Exception
{
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
Method currentActivityThreadMethod =
activityThreadClass.getDeclaredMethod ("currentActivityThread");
currentActivityThreadMethod.setAccessible(true);
//»ñÈ¡Ö÷Ï̶߳ÔÏó
Object activityThread = currentActivityThreadMethod.invoke
(null);
//»ñÈ¡mH×Ö¶Î
Field mH = activityThreadClass.getDeclaredField
("mH");
mH.setAccessible(true);
//»ñÈ¡Handler
Handler handler = (Handler) mH.get (activityThread);
//»ñÈ¡ÔʼµÄmCallBack×Ö¶Î
Field mCallBack = Handler.class.getDeclaredField
("mCallback");
mCallBack.setAccessible(true);
//ÕâÀïÉèÖÃÁËÎÒÃÇ×Ô¼ºÊµÏÖÁ˽ӿڵÄCallBack¶ÔÏó
mCallBack.set(handler, new UserHandler(handler));
} |
public class
UserHandler implements Callback {
//Õâ¸ö100Ò»°ãÇé¿öÏÂ×îºÃÒ²·´Éä»ñÈ¡£¬ µ±È»ÁËÄãÒ²¿ÉÒÔÖ±½ÓдËÀ£¬¸úϵͳµÄ±£³ÖÒ»Ö¾ͺÃÁË
public static final int LAUNCH_ACTIVITY = 100;
private Handler origin;
public UserHandler( Handler mHandler) {
this.origin = mHandler;
}
@Override
public boolean handleMessage(Message msg) {
if (msg.what == LAUNCH_ACTIVITY) {
//ÕâÑùÿ´ÎÆô¶¯µÄʱºò¿ÉÒÔ×öЩ¶îÍâµÄÊÂÇé
Log.d("[app]","×öÄãÏëÒªµÄÊÂÇé");
}
origin.handleMessage(msg);
return false;
}
} |
ºÃÁË£¬ActivityµÄÆô¶¯¼à¿Ø¾ÍÕâÑùÁË£¬Ò»°ãдÔÚapplicationÀïÃæµÄattachBaseContext()·½·¨ÀïÃæ£¬ÒòΪÕâ¸ö·½·¨Ê±»ú×îÔç¡£
ºÃÁË£¬ÏÂÃæÀ´ËµËµActivityµÄ´´½¨µÄ¼à¿Ø£¬Ç°ÃæÎÒÃÇÖªµÀÁË£¬InstrumentationµÄnewActivity·½·¨¸ºÔð´´½¨ÁËActivity£¬ÄÇÃ´Í»ÆÆ¿ÚÒ²¾ÍÊÇÔÚÕâÀïÁË£¬´´½¨ÎªÎÒÃÇ×Ô¶¨ÒåµÄInstrumentation£¬È»ºó·´ÉäÌæ»»µô¾ÍºÃ£¬Í¬Ê±ÖØÐ´newActivity·½·¨£¬¿ÉÒÔ×öЩÊÂÇ飬±ÈÈç¼Ç¼ʱ¼äÖ®À࣬ÏÂÃæÊÇ´úÂë:
public static
void hookInstrumentation() throws Exception{
Class<?> activityThread=Class.forName ("android.app.ActivityThread");
Method currentActivityThread=activityThread. getDeclaredMethod ("currentActivityThread");
currentActivityThread.setAccessible(true);
//»ñÈ¡Ö÷Ï̶߳ÔÏó
Object activityThreadObject=currentActivityThread. invoke(null);
//»ñÈ¡Instrumentation×Ö¶Î
Field mInstrumentation=activityThread.getDeclaredField ("mInstrumentation");
mInstrumentation.setAccessible(true);
Instrumentation instrumentation= (Instrumentation)
mInstrumentation.get(activityThreadObject);
CustomInstrumentation customInstrumentation=new
CustomInstrumentation(instrumentation);
//Ìæ»»µôÔÀ´µÄ,¾ÍÊǰÑϵͳµÄinstrumentationÌæ»»Îª×Ô¼ºµÄInstrumentation¶ÔÏó
mInstrumentation.set(activityThreadObject, CustomInstrumentation);
Log.d("[app]","Hook Instrumentation³É¹¦");
} |
public class
CustomInstrumentation extends Instrumentation{
private Instrumentation base;
public CustomInstrumentation(Instrumentation base)
{
this.base = base;
}
//ÖØÐ´´´½¨ActivityµÄ·½·¨
@Override
public Activity newActivity(ClassLoader cl, String
className, Intent intent) throws InstantiationException,
IllegalAccessException, ClassNotFoundException
{
Log.d("[app]","you are hook!,×ö×Ô¼ºÏëÒªµÄÊÂÇé");
Log.d("[app]","className="+className+"
intent="+intent);
return super.newActivity(cl, className, intent);
}
} |
ͬÑùÔÚapplicationµÄattachBaseContext×¢Èë¾ÍºÃ£¬µ±È»ÁË£¬Instrumentation»¹ÓÐÆäËû·½·¨¿ÉÒÔÖØÐ´£¬´ó¼Ò¿ÉÒÔÈ¥ÊÔÒ»ÊÔ£¬ÏÂÃæÊÇÔËÐеĽá¹û:

¿´µ½Ã»£¬¼à¿ØÆô¶¯ºÍ´´½¨¶¼ÊµÏÖÁË£¬ÆäʵÕâÀïÃæÒ²ÓкöàÀ©Õ¹µÄ£¬±ÈÈçÆô¶¯ActivityµÄʱºò£¬InstrumentationÒ»ÑùÊÇ¿ÉÒÔ¼à¿ØµÄ£¬Äã¶®µÄ£¬ÔÙ´ÎÖØÐ´·½·¨£¬È»ºóʵÏÖ×Ô¼ºµÄÂß¼£¬ÁíÍ⣬small²å¼þ»¯¿ò¼Ü¾ÍÊÇHookÁËInstrumentationÀ´¶¯Ì¬¼ÓÔØActivityµÄ£¬´ó¼ÒÓÐÐËȤ¿ÉÒÔÈ¥¿´¿´£¬³ýÁËÒÔÉÏ·½·¨£¬»¹Óкܶ෽·¨¿ÉÒÔÓÃÀàËÆµÄÊÖ¶ÎȥʵÏÖ£¬´ó¼ÒÒ»¶¨Òª¶àÁ·Ï°£¬ºÃ¼ÇÐÔ²»ÈçÀñÊÍ·¾ÍÊÇÕâ¸öµÀÀí¡£
ʹÓ÷´ÉäÐèҪעÒâµÄµØ·½
´ÓÇ°Ãæ¿ÉÒÔ¿´³ö£¬Ê¹Ó÷´Éä·Ç³£·½±ã£¬¶øÇÒÔÚÒ»Ð©ÌØ¶¨µÄ³¡ºÏÏ¿ÉÒÔʵÏÖÌØ±ðµÄÐèÇ󣬵«ÊÇʹÓ÷´ÉäÒ²ÊÇÐèҪעÒâһϼ¸µãµÄ:
·´Éä×îºÃÊÇʹÓÃpublicÐÞÊηûµÄ£¬ÆäËûÐÞÊηûÓÐÒ»¶¨µÄ¼æÈÝÐÔ·çÏÕ£¬±ÈÈçÕâ¸ö°æ±¾ÓУ¬ÁíÍâµÄ°æ±¾¿ÉÄÜûÓС£
´ó¼Ò¶¼ÖªµÀµÄAndroid¿ªÔ´´úÂëÒýÆðµÄ¼æÈÝÐÔµÄÎÊÌâ,ÕâÊÇAndroidϵͳ¿ªÔ´µÄ×î´óµÄÎÊÌâ£¬ÌØ±ðÊÇÄÇЩµÚÈý·½µÄROM£¬ÒªÉ÷Óá£
Èç¹û´óÁ¿Ê¹Ó÷´É䣬ÔÚ´úÂëÉÏÐèÒªÓÅ»¯·â×°£¬²»È»²»ºÃ¹ÜÀí£¬Ð´´úÂë²»½ö½öÊÇʵÏÖ¹¦ÄÜ£¬»¹ÓÐά»¤ÐԺͿɶÁÐÔ·½·¨Ò²ÐèÒª¼ÓÇ¿£¬demoÖпÉÒÔÖ±½ÓÕâÑù´Ö²ÚЩ£¬ÔÚÏîÄ¿Öл¹ÊÇÐèÒªºÃºÃ×éÖ¯·âװϵġ£
|