Android如何完全调试framework层代码
2014-07-25 09:46
836 查看
from:http://blog.csdn.net/i2cbus/article/details/21739261
1 之前写过一篇文章:《Android实现开机调试system_process》
2 google的eclipse插件ADT的已经能够很方便的调试Android的apk了,但是调试的时候应用程序已经进入Activity。
3 如果我们想了解一下Activity的启动过程,只有看代码+看log输出了吗?本文可以告诉你:NO!
4 相信大家比较感兴趣的都是代码,这里先把代码再放出来
ZygoteInit.java
[java]
view plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
public static List<String> readCommandOutput(String command) {
Runtime rt =Runtime.getRuntime();
java.lang.Processproc;
try {
proc =rt.exec(command);
if (proc.waitFor() != 0) {
return null;
}
LinkedList<String>list = new LinkedList<String>();
InputStreamReader ir = new InputStreamReader(proc.getInputStream());
BufferedReader in = new BufferedReader(ir);
String line = null;
while ((line = in.readLine()) != null) {
list.add(line);
}
return list;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static String getPackageName(){
String strPid =Integer.toString(android.os.Process.myPid());
String cmd = "ps";
List<String>result = readCommandOutput(cmd);
if(result == null){
return "";
}
for(String info:result){
if(info.contains(strPid)){
int index = info.lastIndexOf(" ");
if(index >=0){
StringsubStr = info.substring(index+1);
Log.i(TAG,subStr);
return subStr;
}
}
}
return "";
}
public static boolean needDebug(String packageName){
String debugProcess = android.os.SystemProperties.get("persist.sys.debug");
Log.i(TAG,debugProcess);
if(debugProcess.equals(packageName)){
return true;
}
return false;
}
public static void main(Stringargv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
registerZygoteSocket();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to cleanup after startup
gc();
// If requested, start system server directlyfrom Zygote
if (argv.length != 2) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
if (argv[1].equals("start-system-server")) {
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
String packageName = getPackageName();
if(needDebug(packageName)){
android.ddm.DdmHandleAppName.setAppName(packageName,UserHandle.myUserId());
android.os.Debug.waitForDebugger();
}
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
5 如果有兴趣,继续往下看!
6 readCommandOutput:用于执行命令并获取命令的输出
7 getPackageName()有于获取当前进程的包名
这里默认进程名称即为包名
获取ps的输出
然后通过pid找到本程序所在的输出行。
提取出本程序所在的输出行包名
8 needDebug()用于判断当前进程是否需要调试,原理是这样的:
使用者通过setprop persist.sys.debug 包名来设置包的名称
needDebug获取 persist.sys.debug
再与本进程的包名进行比较,以判断是否要调试
9 接下来的动作就和《Android实现开机调试system_process》一样了:
设置App在DDM中的名称:
android.ddm.DdmHandleAppName.setAppName(packageName,UserHandle.myUserId());
等待调试器来连接:
android.os.Debug.waitForDebugger();
10 接下来重新编译和烧录,mmm...,一个漫长的过程,但是结果将会证明一确都是值得的。
11 接下来,创建一个伪工程,修改Manifest中的package为需要调试的程序包名
12 再在工程中将需要调试的framework层代码引进来
13 接下来,adb shell连接到android,进行命令行
14 执行命令:
setprop persist.sys.debug 包名
15 在需要调试的代码上设置断点
16 接下来,启动应用程序,注意,是直接启动程序,而不是通过eclipse启动调试!
17 enjoy it!
18 (完)
1 之前写过一篇文章:《Android实现开机调试system_process》
2 google的eclipse插件ADT的已经能够很方便的调试Android的apk了,但是调试的时候应用程序已经进入Activity。
3 如果我们想了解一下Activity的启动过程,只有看代码+看log输出了吗?本文可以告诉你:NO!
4 相信大家比较感兴趣的都是代码,这里先把代码再放出来
ZygoteInit.java
[java]
view plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
public static List<String> readCommandOutput(String command) {
Runtime rt =Runtime.getRuntime();
java.lang.Processproc;
try {
proc =rt.exec(command);
if (proc.waitFor() != 0) {
return null;
}
LinkedList<String>list = new LinkedList<String>();
InputStreamReader ir = new InputStreamReader(proc.getInputStream());
BufferedReader in = new BufferedReader(ir);
String line = null;
while ((line = in.readLine()) != null) {
list.add(line);
}
return list;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static String getPackageName(){
String strPid =Integer.toString(android.os.Process.myPid());
String cmd = "ps";
List<String>result = readCommandOutput(cmd);
if(result == null){
return "";
}
for(String info:result){
if(info.contains(strPid)){
int index = info.lastIndexOf(" ");
if(index >=0){
StringsubStr = info.substring(index+1);
Log.i(TAG,subStr);
return subStr;
}
}
}
return "";
}
public static boolean needDebug(String packageName){
String debugProcess = android.os.SystemProperties.get("persist.sys.debug");
Log.i(TAG,debugProcess);
if(debugProcess.equals(packageName)){
return true;
}
return false;
}
public static void main(Stringargv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
registerZygoteSocket();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to cleanup after startup
gc();
// If requested, start system server directlyfrom Zygote
if (argv.length != 2) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
if (argv[1].equals("start-system-server")) {
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
String packageName = getPackageName();
if(needDebug(packageName)){
android.ddm.DdmHandleAppName.setAppName(packageName,UserHandle.myUserId());
android.os.Debug.waitForDebugger();
}
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
5 如果有兴趣,继续往下看!
6 readCommandOutput:用于执行命令并获取命令的输出
7 getPackageName()有于获取当前进程的包名
这里默认进程名称即为包名
获取ps的输出
然后通过pid找到本程序所在的输出行。
提取出本程序所在的输出行包名
8 needDebug()用于判断当前进程是否需要调试,原理是这样的:
使用者通过setprop persist.sys.debug 包名来设置包的名称
needDebug获取 persist.sys.debug
再与本进程的包名进行比较,以判断是否要调试
9 接下来的动作就和《Android实现开机调试system_process》一样了:
设置App在DDM中的名称:
android.ddm.DdmHandleAppName.setAppName(packageName,UserHandle.myUserId());
等待调试器来连接:
android.os.Debug.waitForDebugger();
10 接下来重新编译和烧录,mmm...,一个漫长的过程,但是结果将会证明一确都是值得的。
11 接下来,创建一个伪工程,修改Manifest中的package为需要调试的程序包名
12 再在工程中将需要调试的framework层代码引进来
13 接下来,adb shell连接到android,进行命令行
14 执行命令:
setprop persist.sys.debug 包名
15 在需要调试的代码上设置断点
16 接下来,启动应用程序,注意,是直接启动程序,而不是通过eclipse启动调试!
17 enjoy it!
18 (完)
相关文章推荐
- Android如何完全调试framework层代码
- Android如何完全调试framework层代码
- 如何从C++代码直接访问android framework层的WifiService
- 如何编译android 4.1 的源码并在android的ADT里面调试framework相关的代码
- 【python】如何在电脑上调试android上的python代码
- 没有设备如何调试Android代码,最强Android模拟器 Genymotion: 你可以拥有所有 Android 设备
- Linux/Android内核代码在运行时是如何调试的?
- 如何使用gdb调试android webkit内核代码
- android:如何通过chrome远程调试APP中的webView的h5代码
- android 调试跟踪framework层代码
- Android如何在Framework层使用解锁代码
- 如何使用gdb调试android webkit内核代码
- 如何安全的修改原有代码---android mms player调试总结
- 如何使用arm-eabi-gdb调试android c/c++程序
- 如何编写高效的Android代码
- 如何用 Visual studio 2003/2005 调试 ASP 应用程序、Javascript 代码(转)
- 如何编写高效的Android代码
- IronRuby - 如何在VS2010下调试IronRuby代码
- 如何使用Java API在黑莓手机上记录事件信息做代码调试
- Android下如何调试程序