編輯:關於Android編程
1 之前寫過一篇文章:《Android實現開機調試system_process》
2 google的eclipse插件ADT的已經能夠很方便的調試Android的apk了,但是調試的時候應用程序已經進入Activity。
3 如果我們想了解一下Activity的啟動過程,只有看代碼+看log輸出了嗎?本文可以告訴你:NO!
4 相信大家比較感興趣的都是代碼,這裡先把代碼再放出來
ZygoteInit.java
public static List
Runtime rt =Runtime.getRuntime();
java.lang.Processproc;
try {
proc =rt.exec(command);
if (proc.waitFor() != 0) {
return null;
}
LinkedList
InputStreamReaderir = new InputStreamReader(proc.getInputStream());
BufferedReaderin = new BufferedReader(ir);
Stringline = 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
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){
StringdebugProcess = 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》一樣了:
設置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 (完)
寫代碼的時候過度依賴鼠標可能會遇到比低效率更嚴重的問題。這裡的技巧幫助你寫更少的代碼,充分發揮鍵盤的功能,因此你可以避免發生這樣的情況:hanks Obama.這裡的絕大
手機qq安裝失敗怎麼辦?手機qq安裝後打不開是什麼原因?下面我們一起看看解決方法吧!手機安裝失敗原因及解決方法1、證書過期(或者未生效): 下載安裝前將手
(一)概述學完上一節,相信你已經知道如何去使用系統提供的ContentProvider或者自定義ContentProvider了, 已經基本滿足日常開發的需求了,有趣的是
本文實例為大家分享了Andriod滑動布局的具體代碼,供大家參考,具體內容如下MainActivity.java代碼:package siso.swipelayoutde