這個長螢幕擷取功能是我做的。我來講講其技術實作吧。
簡單來講,就是我讓app裏面的裝內容的可捲動控制項一邊捲動,一邊螢幕擷取,最後拼接起來。
下面我來幾個自問自答。
我為什麽能捲動第三方app裏的控制項?
Android裏有個ApplicationThread,系統對Activity的控制如resume/pause等都是透過它來做跨行程呼叫,我們也可以透過擴充套件它,實作從系統呼叫到app裏。不過事實上由於我們自己有另外一個類似的介面,我使用的是我們自己的那個。
我怎麽知道第三方app中哪個控制項裏面裝的是使用者想捲動的內容?
我會從頂層的View從上往下遍歷,直到找到符合我設定條件的View為止。我設定的條件大概是:能向下捲動、View在螢幕內的可見大小大於半個螢幕的大小。
實際使用發現這個簡單的規則就夠了。
為什麽點選「長螢幕擷取」按鈕後圖片就無縫的自然變長,中間也不停頓,螢幕擷取究竟是在什麽時候截的呢?
其實真實的app內容捲動與「螢幕擷取」這個動作是發生在當前視窗背後的,由於當前視窗完全不透明,所以擋住了背後發生的事情,我們完全看不到。
點選「長螢幕擷取」按鈕之後,大概會發生下面的事情:
-
找到當前前台Activity,然後透過上面說的遠端呼叫,呼叫過去。
-
在前台Activity裏執行的程式碼收到呼叫後,找到使用者要捲動的View,並捲動一定距離。然後停止捲動並透過Broadcast通知螢幕擷取視窗,包括View的位置及捲動的距離資訊。
- 螢幕擷取視窗截取一張螢幕,當然,不包含自己這個視窗,只截Activity。然後根據傳遞過來的資訊決定怎麽裁剪,怎麽拼接。
- 螢幕擷取視窗螢幕擷取之後告訴前台Activity已經截完屏了,可以繼續捲動了。
- 註意,進行前面這些步驟的時候由於螢幕擷取app的視窗擋在上面,我們是完全看不到的。當捲動了一屏後的螢幕擷取內容得到後,那麽我們已經有了不止當前螢幕的內容,還有了下一屏的內容,於是我們在界面上從原本的一張靜態螢幕擷取圖片,無縫的切換成由多張螢幕擷取拼接成的圖片,然後開始做捲動動畫(我自己感覺有種魔法般的感覺)。所以我們看到的內容捲動是滯後於真正的「螢幕擷取」動作的。
- 如此迴圈,直到點選了「結束」或到底。
大致就是這些。還有很多細節就不展開了。
值得一提的是,捲動的過程中,可以透過手指觸摸切換成手動模式,這樣我們可以精準的控制截到哪裏。挺實用的。