1 之前写过一篇文章:《Android实现开机调试system_process》

2 google的eclipse插件ADT的已经能够很方便的调试Android的apk了,但是调试的时候应用程序已经进入Activity。

3 如果我们想了解一下Activity的启动过程,只有看代码+看log输出了吗?本文可以告诉你:NO!

4 相信大家比较感兴趣的都是代码,这里先把代码再放出来

ZygoteInit.java


  public static List readCommandOutput(String command)  {     Runtime rt =Runtime.getRuntime();     java.lang.Processproc;     try {       proc =rt.exec(command);              if (proc.waitFor() != 0) {          return null;       }       LinkedListlist = new LinkedList();             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";          Listresult = 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中如何使用JUnit进行单元测试
  2. Qt on Android:将Qt调试信息输出到logcat中
  3. Android(安卓)文件操作详解及简单实例
  4. android recover 系统代码分析 -- 选择进入
  5. 为Android系统定制重启功能
  6. Android下Entity封装工具类
  7. Android(安卓)WebView 调用React Js 代码
  8. 使用夜神模拟器进行Android开发调试
  9. 在Android上实现HttpServer的示例代码

随机推荐

  1. ubuntu16.04 x86_64下编译ffmpeg-4.0 for
  2. 最新adb下载地址
  3. Visibility属性中invisible和gone 区别
  4. Android官方入门文档[3]构建一个简单的用
  5. Android--通过ContentResolver取得com.an
  6. android 使用Okhttp封装上传JSON格式数据
  7. Android/Java中的常用签名算法
  8. android双击返回键退出程序
  9. 在Android(安卓)studio 项目中使用 9patc
  10. Android全屏设置的两种方式