Java遠(yuǎn)程調(diào)試

集群前后臺(tái)協(xié)議需要做一些修改一睁,我負(fù)責(zé)jdbc這邊的修改厅翔。按照協(xié)議內(nèi)容修改完代碼之后卻面臨一個(gè)測(cè)試的問題:修改后的后臺(tái)又部署在北京呢簸,但北京并不是所有的機(jī)器都對(duì)天津這邊開放兽泄,只給提供一臺(tái)機(jī)器A漓概,就是集群的服務(wù)器。
這樣的話,就無法創(chuàng)建節(jié)點(diǎn)的連接病梢,測(cè)試沒有辦法進(jìn)行胃珍。

一開始用了最簡(jiǎn)單的辦法,把打好的jar包通過遠(yuǎn)程ssh放到A上面蜓陌,再通過ssh去跑用例觅彰,打印結(jié)果看看正確與否。但是這樣的效率真的太低了钮热,每做一次修改都要打包填抬、部署、運(yùn)行隧期、分析log飒责。于是借這個(gè)機(jī)會(huì)學(xué)習(xí)一下java程序的遠(yuǎn)程調(diào)試。以下為總結(jié)仆潮。

一些概念

JDPA: java平臺(tái)調(diào)試架構(gòu)

JVMTI: JVM端調(diào)試接口

JDI: java端調(diào)試接口

JDWP: java調(diào)試網(wǎng)絡(luò)協(xié)議

image.png

JPDA 定義了一套如何開發(fā)調(diào)試工具的接口和規(guī)范宏蛉。

JPDA 由三個(gè)獨(dú)立的模塊 JVMTI、JDWP性置、JDI 組成拾并。

調(diào)試者通過 JDI 發(fā)送接受調(diào)試命令。

JDWP 定義調(diào)試者和被調(diào)試者交流數(shù)據(jù)的格式鹏浅。

JVMTI 可以控制當(dāng)前虛擬機(jī)運(yùn)行狀態(tài)辟灰。

上圖中的前端工具就是我們要用到的調(diào)試工具。如JDB篡石、Eclipse等等。這些工具實(shí)現(xiàn)了JDI接口西采,通過這些工具我們可以達(dá)到在命令行或者圖形界面下調(diào)試的目的凰萨。

關(guān)于這部分,只是簡(jiǎn)單的了解一下概念,更多的關(guān)于JDPA的介紹:JDPA體系

使用JDB進(jìn)行本地調(diào)試

JDB 是jdk自帶的一個(gè)調(diào)試工具胖眷,用于命令行下調(diào)試java程序

jdb.exe就位于jdk安裝目錄的bin目錄下武通,安裝好jdk并設(shè)置好環(huán)境變量之后就可以愉快的使用jdb了。

C:\Users\kyu>jdb -help
用法: jdb <options> <class> <arguments>

其中, 選項(xiàng)包括:
    -help             輸出此消息并退出
    -sourcepath <由 ";" 分隔的目錄>
                      要在其中查找源文件的目錄
    -attach <address>
                      使用標(biāo)準(zhǔn)連接器附加到指定地址處正在運(yùn)行的 VM
    -listen <address>
                      等待正在運(yùn)行的 VM 使用標(biāo)準(zhǔn)連接器在指定地址處連接
    -listenany
                      等待正在運(yùn)行的 VM 使用標(biāo)準(zhǔn)連接器在任何可用地址處連接
    -launch
                      立即啟動(dòng) VM 而不是等待 'run' 命令
    -listconnectors   列出此 VM 中的可用連接器
    -connect <connector-name>:<name1>=<value1>,...
                      使用所列參數(shù)值通過指定的連接器連接到目標(biāo) VM
    -dbgtrace [flags] 輸出信息供調(diào)試jdb
    -tclient          在 HotSpot(TM) 客戶機(jī)編譯器中運(yùn)行應(yīng)用程序
    -tserver          在 HotSpot(TM) 服務(wù)器編譯器中運(yùn)行應(yīng)用程序

轉(zhuǎn)發(fā)到被調(diào)試進(jìn)程的選項(xiàng):
    -v -verbose[:class|gc|jni]
                      啟用詳細(xì)模式
    -D<name>=<value>  設(shè)置系統(tǒng)屬性
    -classpath <由 ";" 分隔的目錄>
                      列出要在其中查找類的目錄
    -X<option>        非標(biāo)準(zhǔn)目標(biāo) VM 選項(xiàng)

<class> 是要開始調(diào)試的類的名稱
<arguments> 是傳遞到 <class> 的 main() 方法的參數(shù)

要獲得命令的幫助, 請(qǐng)?jiān)趈db提示下鍵入 'help'

上面是啟動(dòng)JDB的語法說明珊搀。

現(xiàn)假設(shè)運(yùn)行程序的工程目錄如下:

JDBTest
  |----bin(編譯生成的class文件)
  |     |----*.class
  |----src(源文件)
  |     |----*.java
  |----lib(依賴的第三方j(luò)ar)
  |     |----*.jar

開始啟動(dòng)JDB調(diào)試:

Y:\project\JavaProject\JDBTest>jdb -classpath ./bin/;./lib/* -sourcepath ./src/ test.JDBTest

注意冶忱,如果有多個(gè)文件,windows下使用 ";" 分隔每個(gè)文件或目錄境析,Linux下使用 ":" 分隔每個(gè)文件或目錄

-classpath 指定了類路徑囚枪,-sourcepath 指定了源文件的路徑

回車,出現(xiàn)如下信息:

Y:\project\JavaProject\JDBTest>jdb -classpath ./bin/;./lib/* -sourcepath ./src/ test.JDBTest
正在初始化jdb...
> 

此時(shí)劳淆,JDB調(diào)試器等待用戶的輸入链沼,輸入help,出現(xiàn)如下信息:

Y:\project\JavaProject\JDBTest>jdb -classpath ./bin/;./lib/* -sourcepath ./src/ test.JDBTest
正在初始化jdb...
> help
** 命令列表 **
connectors                -- 列出此 VM 中可用的連接器和傳輸

run [class [args]]        -- 開始執(zhí)行應(yīng)用程序的主類

threads [threadgroup]     -- 列出線程
thread <thread id>        -- 設(shè)置默認(rèn)線程
suspend [thread id(s)]    -- 掛起線程 (默認(rèn)值: all)
resume [thread id(s)]     -- 恢復(fù)線程 (默認(rèn)值: all)
where [<thread id> | all] -- 轉(zhuǎn)儲(chǔ)線程的堆棧
wherei [<thread id> | all]-- 轉(zhuǎn)儲(chǔ)線程的堆棧, 以及 pc 信息
up [n frames]             -- 上移線程的堆棧
down [n frames]           -- 下移線程的堆棧
kill <thread id> <expr>   -- 終止具有給定的異常錯(cuò)誤對(duì)象的線程
interrupt <thread id>     -- 中斷線程

print <expr>              -- 輸出表達(dá)式的值
dump <expr>               -- 輸出所有對(duì)象信息
eval <expr>               -- 對(duì)表達(dá)式求值 (與 print 相同)
set <lvalue> = <expr>     -- 向字段/變量/數(shù)組元素分配新值
locals                    -- 輸出當(dāng)前堆棧幀中的所有本地變量

classes                   -- 列出當(dāng)前已知的類
class <class id>          -- 顯示已命名類的詳細(xì)資料
methods <class id>        -- 列出類的方法
fields <class id>         -- 列出類的字段

threadgroups              -- 列出線程組
threadgroup <name>        -- 設(shè)置當(dāng)前線程組

stop in <class id>.<method>[(argument_type,...)]
                          -- 在方法中設(shè)置斷點(diǎn)
stop at <class id>:<line> -- 在行中設(shè)置斷點(diǎn)
clear <class id>.<method>[(argument_type,...)]
                          -- 清除方法中的斷點(diǎn)
clear <class id>:<line>   -- 清除行中的斷點(diǎn)
clear                     -- 列出斷點(diǎn)
catch [uncaught|caught|all] <class id>|<class pattern>
                          -- 出現(xiàn)指定的異常錯(cuò)誤時(shí)中斷
ignore [uncaught|caught|all] <class id>|<class pattern>
                          -- 對(duì)于指定的異常錯(cuò)誤, 取消 'catch'
watch [access|all] <class id>.<field name>
                          -- 監(jiān)視對(duì)字段的訪問/修改
unwatch [access|all] <class id>.<field name>
                          -- 停止監(jiān)視對(duì)字段的訪問/修改
trace [go] methods [thread]
                          -- 跟蹤方法進(jìn)入和退出沛鸵。
                          -- 除非指定 'go', 否則掛起所有線程
trace [go] method exit | exits [thread]
                          -- 跟蹤當(dāng)前方法的退出, 或者所有方法的退出
                          -- 除非指定 'go', 否則掛起所有線程
untrace [methods]         -- 停止跟蹤方法進(jìn)入和/或退出
step                      -- 執(zhí)行當(dāng)前行
step up                   -- 一直執(zhí)行, 直到當(dāng)前方法返回到其調(diào)用方
stepi                     -- 執(zhí)行當(dāng)前指令
next                      -- 步進(jìn)一行 (步過調(diào)用)
cont                      -- 從斷點(diǎn)處繼續(xù)執(zhí)行

list [line number|method] -- 輸出源代碼
use (或 sourcepath) [source file path]
                          -- 顯示或更改源路徑
exclude [<class pattern>, ... | "none"]
                          -- 對(duì)于指定的類, 不報(bào)告步驟或方法事件
classpath                 -- 從目標(biāo) VM 輸出類路徑信息

monitor <command>         -- 每次程序停止時(shí)執(zhí)行命令
monitor                   -- 列出監(jiān)視器
unmonitor <monitor#>      -- 刪除監(jiān)視器
read <filename>           -- 讀取并執(zhí)行命令文件

lock <expr>               -- 輸出對(duì)象的鎖信息
threadlocks [thread id]   -- 輸出線程的鎖信息

pop                       -- 通過當(dāng)前幀出棧, 且包含當(dāng)前幀
reenter                   -- 與 pop 相同, 但重新進(jìn)入當(dāng)前幀
redefine <class id> <class file name>
                          -- 重新定義類的代碼

disablegc <expr>          -- 禁止對(duì)象的垃圾收集
enablegc <expr>           -- 允許對(duì)象的垃圾收集

!!                        -- 重復(fù)執(zhí)行最后一個(gè)命令
<n> <command>             -- 將命令重復(fù)執(zhí)行 n 次
# <command>               -- 放棄 (無操作)
help (或 ?)               -- 列出命令
version                   -- 輸出版本信息
exit (或 quit)            -- 退出調(diào)試器

<class id>: 帶有程序包限定符的完整類名
<class pattern>: 帶有前導(dǎo)或尾隨通配符 ('*') 的類名
<thread id>: 'threads' 命令中報(bào)告的線程編號(hào)
<expr>: Java(TM) 編程語言表達(dá)式括勺。
支持大多數(shù)常見語法。

可以將啟動(dòng)命令置于 "jdb.ini" 或 ".jdbrc" 中
位于 user.home 或 user.dir 中
>

上面的幫助信息說明了如何進(jìn)行JDB調(diào)試曲掰,解釋一下其中的幾個(gè):

step: -- 執(zhí)行當(dāng)前行 相當(dāng)于Eclipse中的F5

step up: -- 一直執(zhí)行, 直到當(dāng)前方法返回到其調(diào)用方 相當(dāng)于Eclipse中的F7

next: -- 步進(jìn)一行 (步過調(diào)用) 相當(dāng)于Eclipse中的F6

cont: -- 從斷點(diǎn)處繼續(xù)執(zhí)行 相當(dāng)于Eclipse中的F8

此時(shí)疾捍,繼續(xù)輸入:

> stop at test.JDBTest:7
正在延遲斷點(diǎn)test.JDBTest:7。
將在加載類后設(shè)置栏妖。
> run
運(yùn)行test.JDBTest
設(shè)置未捕獲的java.lang.Throwable
設(shè)置延遲的未捕獲的java.lang.Throwable
>
VM 已啟動(dòng): 設(shè)置延遲的斷點(diǎn)test.JDBTest:7

斷點(diǎn)命中: "線程=main", test.JDBTest.main(), 行=7 bci=0
7               JDBTest jdbTest = new JDBTest();

main[1]

stop at test.JDBTest:7 表示在這個(gè)類文件的第7行處打一個(gè)斷點(diǎn)

接著乱豆,輸入run,就開始進(jìn)入調(diào)試步驟了〉赘纾現(xiàn)在可以輸入上面幫助中的語法來了解當(dāng)前程序的執(zhí)行情況了咙鞍。一試便知

注意, 若想要在調(diào)試時(shí)能夠正常輸出調(diào)試信息如變量值等等,需要在編譯java文件時(shí)指定 -g 參數(shù)趾徽,否則無法獲得其運(yùn)行時(shí)的調(diào)試信息

另外续滋,使用list可以打印當(dāng)前斷點(diǎn)處的源代碼,如果沒有在啟動(dòng)JDB時(shí)指定源代碼路徑 -sourcepath ./src/ 孵奶,那么會(huì)提示沒有源代碼信息疲酌,無法輸出。此時(shí)可以使用命令 use ./src/ 來指定源代碼路徑了袁,再使用list命令時(shí)可以正常打印了朗恳。

以上就是使用JDB調(diào)試本地程序的方法,具體的使用可根據(jù)實(shí)際情況參照語法說明去執(zhí)行载绿。

使用JDB進(jìn)行遠(yuǎn)程調(diào)試

如果程序不是運(yùn)行在本機(jī)粥诫,而是在其他機(jī)器或者現(xiàn)場(chǎng)的時(shí)候,可以使用java提供的遠(yuǎn)程調(diào)試功能崭庸。

假設(shè)程序現(xiàn)運(yùn)行在主機(jī) 192.168.101.72 這臺(tái)機(jī)器上怀浆,該機(jī)器為linux環(huán)境谊囚,且只可以通過ssh作為一個(gè)普通用戶連接。我們想要在自己的機(jī)器上調(diào)試運(yùn)行在192.168.101.72這臺(tái)機(jī)器上的程序执赡。

啟動(dòng)要調(diào)試的程序

在192.168.101.72這臺(tái)主機(jī)上以下面的方式啟動(dòng)java程序:還是以JDBTest為例

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8899 -classpath ./bin/:./lib/* test.JDBTest

此時(shí)镰踏,命令行輸出

Listening for transport dt_socket at address: 8899

并處于等待狀態(tài)

下面是幾個(gè)參數(shù)的解釋:

-Xdebug 啟用調(diào)試特性。

-Xrunjdwp:<sub-options> 在目標(biāo) VM 中加載 JDWP 實(shí)現(xiàn)沙合。它通過傳輸和 JDWP 協(xié)議與獨(dú)立的調(diào)試器應(yīng)用程序通信奠伪。下面介紹一些特定的子選項(xiàng)。
從 Java V5 開始首懈,您可以使用 -agentlib:jdwp 選項(xiàng)绊率,而不是 -Xdebug 和 -Xrunjdwp。但如果連接到 V5 以前的 VM猜拾,只能選擇 -Xdebug 和 -Xrunjdwp即舌。下面簡(jiǎn)單描述 -Xrunjdwp 子選項(xiàng)。

transport 這里通常使用套接字傳輸挎袜。但是在 Windows 平臺(tái)上也可以使用共享內(nèi)存?zhèn)鬏敗?/p>

server 如果值為 y顽聂,目標(biāo)應(yīng)用程序監(jiān)聽將要連接的調(diào)試器應(yīng)用程序。否則盯仪,它將連接到特定地址上的調(diào)試器應(yīng)用程序紊搪。

address 這是連接的傳輸?shù)刂贰H绻?wù)器為 n全景,將嘗試連接到該地址上的調(diào)試器應(yīng)用程序耀石。否則,將在這個(gè)端口監(jiān)聽連接爸黄。

suspend 如果值為 y滞伟,目標(biāo) VM 將暫停,直到調(diào)試器應(yīng)用程序進(jìn)行連接炕贵。

本機(jī)連接遠(yuǎn)程程序并啟動(dòng)調(diào)試

在本機(jī)上命令行下輸入:

jdb -connect com.sun.jdi.SocketAttach:hostname=192.168.101.72,port=8899

然后就進(jìn)入了調(diào)試界面梆奈,你可以像調(diào)試本機(jī)程序那樣使用JDB的一些命令來調(diào)試了。當(dāng)退出調(diào)試程序時(shí)称开,遠(yuǎn)程主機(jī)上的程序也就退出了亩钟。

使用Eclipse進(jìn)行遠(yuǎn)程調(diào)試

可以使用Eclipse進(jìn)行遠(yuǎn)程調(diào)試,就上上面使用JDB一樣鳖轰。

啟動(dòng)要調(diào)試的程序

與JDB遠(yuǎn)程調(diào)試一樣清酥,啟動(dòng)遠(yuǎn)程主機(jī)上的程序:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8899 -classpath ./bin/:./lib/* test.JDBTest

本機(jī)啟動(dòng)Eclipse進(jìn)行調(diào)試

首先要右鍵工程->java compiler

image.png

上圖中的幾個(gè)選項(xiàng)最好全部打勾,否則調(diào)試時(shí)會(huì)出現(xiàn)無法打斷點(diǎn)或者獲取不到行號(hào)等問題(關(guān)于這幾個(gè)選項(xiàng)的含義在之前的總結(jié)中有提到)

接著蕴侣,右鍵工程->Debug As->Run Configurations, 在出現(xiàn)的對(duì)話框中選擇Remote Java Application, 右鍵->New, 出現(xiàn)如下界面:

image.png

在Connect頁中焰轻,選擇對(duì)應(yīng)的java 工程,Connection Type選擇 Socket Attach昆雀,然后填寫遠(yuǎn)程主機(jī)的ip和端口鹦马,這里應(yīng)該填寫192.168.101.72和8899胧谈。
在Source頁中可以添加源代碼,如用到的第三方j(luò)ar的源代碼或者引用的工程荸频,調(diào)試時(shí)就可以進(jìn)入到這部分代碼查看。在Common頁可以設(shè)置編碼的配置客冈。

接下來點(diǎn)擊Debug按鈕旭从,就可以愉快的在本機(jī)調(diào)試遠(yuǎn)程程序了,就像調(diào)試本地程序那樣场仲。只不過可能有一點(diǎn)一點(diǎn)慢和悦,不過比打Log的方式要好很多了。

參考

使用 Eclipse 遠(yuǎn)程調(diào)試 Java 應(yīng)用程序

JDB的簡(jiǎn)單使用

深入 Java 調(diào)試體系: 第 1 部分渠缕,JPDA 體系概覽

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸽素,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子亦鳞,更是在濱河造成了極大的恐慌馍忽,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燕差,死亡現(xiàn)場(chǎng)離奇詭異遭笋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)徒探,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門瓦呼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人测暗,你說我怎么就攤上這事央串。” “怎么了碗啄?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵质和,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我挫掏,道長(zhǎng)侦另,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任尉共,我火速辦了婚禮褒傅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘袄友。我一直安慰自己殿托,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布剧蚣。 她就那樣靜靜地躺著支竹,像睡著了一般旋廷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上礼搁,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天饶碘,我揣著相機(jī)與錄音,去河邊找鬼馒吴。 笑死扎运,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饮戳。 我是一名探鬼主播豪治,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼扯罐!你這毒婦竟也來了负拟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤歹河,失蹤者是張志新(化名)和其女友劉穎掩浙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體启泣,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涣脚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寥茫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遣蚀。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖纱耻,靈堂內(nèi)的尸體忽然破棺而出芭梯,到底是詐尸還是另有隱情,我是刑警寧澤弄喘,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布玖喘,位于F島的核電站,受9級(jí)特大地震影響蘑志,放射性物質(zhì)發(fā)生泄漏累奈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一急但、第九天 我趴在偏房一處隱蔽的房頂上張望澎媒。 院中可真熱鬧,春花似錦波桩、人聲如沸戒努。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽储玫。三九已至侍筛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撒穷,已是汗流浹背匣椰。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桥滨,地道東北人窝爪。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像齐媒,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纷跛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 簡(jiǎn)介 用log來做調(diào)試的方法低效茫目 遠(yuǎn)程調(diào)試是jdk自帶的一個(gè)有利調(diào)試工具喻括,可以快速定位問題 在工作機(jī)上使用ec...
    AGIHunt閱讀 4,965評(píng)論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)贫奠,斷路器唬血,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 本文主要基于一篇英文原作翻譯而成,刪減部分無用文字唤崭,添加了必要的注解和補(bǔ)充拷恨。 *英文原文是一篇對(duì)遠(yuǎn)程調(diào)試講解很通俗...
    曲水流觴TechRill閱讀 51,610評(píng)論 6 45
  • 在學(xué)習(xí)微信公眾號(hào)開發(fā)這種需要第三方回調(diào)的時(shí)候,需要將程序運(yùn)行在公網(wǎng)可訪問的服務(wù)器上谢肾,而這種服務(wù)器一般不會(huì)是自己的開...
    JerryL_閱讀 10,486評(píng)論 0 7
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,509評(píng)論 25 707