利用shell命令實(shí)現(xiàn)Eeclipse對Android的遠(yuǎn)程調(diào)試

這篇文章主要講如何自己來做一個(gè)apk實(shí)現(xiàn)遠(yuǎn)程調(diào)試,也就是說我們先自己寫一個(gè)apk來控制是否啟用遠(yuǎn)程調(diào)試的功能,然后通過這個(gè)apk來啟用遠(yuǎn)程調(diào)試,接著基于遠(yuǎn)程adb的方式來調(diào)試以后的程序。聽起來真TM繞口。沒關(guān)系,跟著看就行了。實(shí)現(xiàn)這個(gè)目標(biāo)分為3步。

1.了解shell命令
2.如何在android上執(zhí)行shell
3.pc端的命令

1.了解shell命令

好吧,這個(gè)逼格的東西并不需要你多么的了解,我們只需要知道幾條基本的命令。
設(shè)置adb的調(diào)試端口,當(dāng)端口>-1的時(shí)候,adb是wifi調(diào)試,我們默認(rèn)的一般將端口設(shè)置為5555
setprop service.adb.tcp.port 5555
對應(yīng)的將端口設(shè)置為-1或者更小的數(shù)值,則將調(diào)試方式變?yōu)榱藆sb調(diào)試
setprop service.adb.tcp.port -1
關(guān)閉adb
stop adbd
打開adb
start adbd
好了有了這幾個(gè)命令的基礎(chǔ),就可以實(shí)現(xiàn)usb和wifi調(diào)試方式的轉(zhuǎn)換了

2.如何在android上執(zhí)行shell

怎么執(zhí)行,鬼才管呢。我又不是搞底層的。對于執(zhí)行shell命令,自有高手早已寫好的工具類,這里將源碼貼上

public class ShellUtils {

    public static final String COMMAND_SU = "su";
    public static final String COMMAND_SH = "sh";
    public static final String COMMAND_EXIT = "exit\n";
    public static final String COMMAND_LINE_END = "\n";

    private ShellUtils() {
        throw new AssertionError();
    }

    /**
     * check whether has root permission
     * 
     * @return
     */
    public static boolean checkRootPermission() {
        return execCommand("echo root", true, false).result == 0;
    }

    /**
     * execute shell command, default return result msg
     * 
     * @param command
     *            command
     * @param isRoot
     *            whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot) {
        return execCommand(new String[] { command }, isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     * 
     * @param commands
     *            command list
     * @param isRoot
     *            whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(List<String> commands,
            boolean isRoot) {
        return execCommand(
                commands == null ? null : commands.toArray(new String[] {}),
                isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     * 
     * @param commands
     *            command array
     * @param isRoot
     *            whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot) {
        return execCommand(commands, isRoot, true);
    }

    /**
     * execute shell command
     * 
     * @param command
     *            command
     * @param isRoot
     *            whether need to run with root
     * @param isNeedResultMsg
     *            whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot,
            boolean isNeedResultMsg) {
        return execCommand(new String[] { command }, isRoot, isNeedResultMsg);
    }

    /**
     * execute shell commands
     * 
     * @param commands
     *            command list
     * @param isRoot
     *            whether need to run with root
     * @param isNeedResultMsg
     *            whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(List<String> commands,
            boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(
                commands == null ? null : commands.toArray(new String[] {}),
                isRoot, isNeedResultMsg);
    }

    /**
     * execute shell commands
     * 
     * @param commands
     *            command array
     * @param isRoot
     *            whether need to run with root
     * @param isNeedResultMsg
     *            whether need result msg
     * @return <ul>
     *         <li>if isNeedResultMsg is false, {@link CommandResult#successMsg}
     *         is null and {@link CommandResult#errorMsg} is null.</li>
     *         <li>if {@link CommandResult#result} is -1, there maybe some
     *         excepiton.</li>
     *         </ul>
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot,
            boolean isNeedResultMsg) {
        int result = -1;
        if (commands == null || commands.length == 0) {
            return new CommandResult(result, null, null);
        }

        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;

        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec(
                    isRoot ? COMMAND_SU : COMMAND_SH);
            os = new DataOutputStream(process.getOutputStream());
            for (String command : commands) {
                if (command == null) {
                    continue;
                }

                // donnot use os.writeBytes(commmand), avoid chinese charset
                // error
                os.write(command.getBytes());
                os.writeBytes(COMMAND_LINE_END);
                os.flush();
            }
            os.writeBytes(COMMAND_EXIT);
            os.flush();

            result = process.waitFor();
            // get command result
            if (isNeedResultMsg) {
                successMsg = new StringBuilder();
                errorMsg = new StringBuilder();
                successResult = new BufferedReader(new InputStreamReader(
                        process.getInputStream()));
                errorResult = new BufferedReader(new InputStreamReader(
                        process.getErrorStream()));
                String s;
                while ((s = successResult.readLine()) != null) {
                    successMsg.append(s);
                }
                while ((s = errorResult.readLine()) != null) {
                    errorMsg.append(s);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (process != null) {
                process.destroy();
            }
        }
        return new CommandResult(result, successMsg == null ? null
                : successMsg.toString(), errorMsg == null ? null
                : errorMsg.toString());
    }

    /**
     * result of command
     * <ul>
     * <li>{@link CommandResult#result} means result of command, 0 means normal,
     * else means error, same to excute in linux shell</li>
     * <li>{@link CommandResult#successMsg} means success message of command
     * result</li>
     * <li>{@link CommandResult#errorMsg} means error message of command result</li>
     * </ul>
     * 
     * @author <a  target="_blank">Trinea</a>
     *         2013-5-16
     */
    public static class CommandResult {

        /** result of command **/
        public int result;
        /** success message of command result **/
        public String successMsg;
        /** error message of command result **/
        public String errorMsg;

        public CommandResult(int result) {
            this.result = result;
        }

        public CommandResult(int result, String successMsg, String errorMsg) {
            this.result = result;
            this.successMsg = successMsg;
            this.errorMsg = errorMsg;
        }
    }
}

我們需要用到的方法是

    public static CommandResult execCommand(String[] commands, boolean isRoot,
            boolean isNeedResultMsg) {

解釋下三個(gè)參數(shù)的意思
參數(shù)1:需要執(zhí)行的命令數(shù)組
參數(shù)2:是否已經(jīng)root過。oh天,忘了說,你的手機(jī)必須要先root才能來做這件事情,至于root的方式,太多了,什么root大師,xx大師。
參數(shù)3:是否需要返回結(jié)果,這個(gè)可有可無,如果你選擇返回結(jié)果,我想多半是你想知道這些命令有沒有執(zhí)行成功,你只需要判斷
CommandResult .result
的值是否為0,對的,linux就是這樣,等于0就是成功了的意思
ok,剩下的活你應(yīng)該會(huì)做了,寫一個(gè)button控件,監(jiān)聽點(diǎn)擊事件,在事件中調(diào)用這個(gè)方法。至于參數(shù)一怎么寫,當(dāng)需要打開wifi調(diào)試的時(shí)候就這樣寫

String[] commands = {
setprop service.adb.tcp.port 5555,
stop adbd,
start adbd
}

當(dāng)需要關(guān)閉wifi調(diào)試的時(shí)候,只需要將5555改為-1就行

3.pc端的命令

好的,現(xiàn)在你可以將apk編譯到你的手機(jī)上,并且打開wifi調(diào)試,接著在如下目錄

sdk\platform-tools

你可以通過 shift+右鍵 的方式有個(gè)“在此處打開命令行”。然后輸入
adb connect xxxx
xxxx 是你的手機(jī)ip,端口不用輸,默認(rèn)就是5555,手機(jī)ip你可以在設(shè)置-關(guān)于手機(jī)-手機(jī)狀態(tài) 中找到
于是“噌”的一下,你的eclipse里的device窗口就顯示你的破手機(jī)已經(jīng)連接上了,現(xiàn)在你可以丟掉數(shù)據(jù)線,靜靜的裝逼了。真是有逼格的燒連啊。
斷開連接,你可以在手機(jī)上斷開,也可以在pc上通過

adb disconnect xxxx

來斷開,當(dāng)然在手機(jī)上斷開保險(xiǎn)一點(diǎn)。

好的,有問題的同學(xué)可以留言,啊哈哈哈哈哈,這都不會(huì),你好笨啊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • android開發(fā)環(huán)境中,ADB是我們進(jìn)行android開發(fā)經(jīng)常要用的調(diào)試工具,它的使用當(dāng)然是我們Android開...
    Memebox閱讀 6,384評論 0 32
  • 昨晚,看到了自己這樣的信念:我是一個(gè)有罪的該受懲罰的生命。幾乎所有的人生經(jīng)驗(yàn)都證明了,我就是這個(gè)樣子,非常認(rèn)同。 ...
    張力平閱讀 366評論 0 0
  • 這個(gè)社會(huì)總會(huì)遇到一些令人添堵的人或事,但是請不要在意這些,它們不過是你人生的過客而已,不!或許連過客還算不上,只是...
    太陽的星1閱讀 140評論 0 0
  • 1第一部手機(jī)叫虛偽 十年前,我考上了大學(xué),離開那個(gè)土里土氣的村落,去了遙遠(yuǎn)而美麗的海濱城市。作為獎(jiǎng)勵(lì),也為了方便和...
    沖浪小魚兒閱讀 883評論 8 13
  • 時(shí)間是向前奔流的河流,絲毫不會(huì)停歇,過去未來,都只是不斷前進(jìn),即便會(huì)被幾塊礁石或是幾片綠洲所阻擋,仍然無非是多出幾...
    歌聲楚楚閱讀 777評論 0 3

友情鏈接更多精彩內(nèi)容