<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    1、引言

    對于移動端IM應用和消息推送應用的開發者來說,Android后臺保活這件事是再熟悉不過了。

    自從Android P(即Android 8.0)出現以后,Android已經從系統層面將后臺保活這條路給堵死了(詳見:《Android P正式版即將到來:后臺應用保活、消息推送的真正噩夢》),曾今那些層出不窮的保活黑科技能用的也越來越少了(詳見:《全面盤點當前Android后臺保活方案的真實運行效果(截止2019年前)》。雖然可以自已對接廠商的ROOM級推送通道,但一方面各廠商的推送接口都不一樣(而且同一廠商不同的系統版本間也存在推送接口的兼容性問題),很不方便。另一方面要一家家引入各自的推送服務SDK包會讓APP變的很大,這讓APP的下載變的很不友好。

    總之,Android應用的后臺保活在某些場景下,還是有持續的需求。除了之前那些耳熟能詳的保活黑科技以外,在Android 9.0(甚至Android 10)時代,我們還有哪些保活方法可以用?那么,請跟著本文作者的思路,看看更優雅的后臺保活實現方法吧。

    (本文同步發布于:http://www.52im.net/thread-2881-1-1.html

     

    2、關于作者

    網名NanBox:畢業于華中科技大學,現為"悅跑圈APP”高級Android開發工程師。主要負責公司 Android 項目,核心模塊的開發。涉及 GPS 定位、地圖、圖片編輯等功能。獨立開發了手表應用項目。 在項目中應入了 Flutter 跨平臺開發技術,實現了原生和 Flutter 的混合開發。

    本文作者樂于分享,平時會寫技術文章并分享在多個平臺,是掘金專欄作者的一員,文章總閱讀量超過 10 萬。在 GitHub 上有多個開源項目,多次在團隊內部進行技術分享。是 Android 和 Flutter 官方中文文檔譯者。

    3、相關文章

    如果你想詳細了解目前Android平臺上后臺保活技術的挑戰,請閱讀:

    Android P正式版即將到來:后臺應用保活、消息推送的真正噩夢》。

    如果你想回顧那些曾今出現的Android保活黑科技,以下文章值得好好讀讀:

    全面盤點當前Android后臺保活方案的真實運行效果(截止2019年前)

    應用保活終極總結(一):Android6.0以下的雙進程守護保活實踐

    應用保活終極總結(二):Android6.0及以上的保活實踐(進程防殺篇)

    應用保活終極總結(三):Android6.0及以上的保活實踐(被殺復活篇)

    Android進程保活詳解:一篇文章解決你的所有疑問

    Android端消息推送總結:實現原理、心跳保活、遇到的問題等

    深入的聊聊Android消息推送這件小事

    為何基于TCP協議的移動端IM仍然需要心跳保活機制?

    微信團隊原創分享:Android版微信后臺保活實戰分享(進程保活篇)

    融云技術分享:融云安卓端IM產品的網絡鏈路保活技術實踐

    4、Android保活現狀

    我們知道,Android 系統會存在殺后臺進程的情況,并且隨著系統版本的更新,殺進程的力度還有越來越大的趨勢(見:《Android P正式版即將到來:后臺應用保活、消息推送的真正噩夢》)。

    系統這種做法本身出發點是好的,因為可以節省內存,降低功耗,也避免了一些流氓行為。

    但有一部分應用,應用本身的使用場景就需要在后臺運行,用戶也是愿意讓它在后臺運行的,比如跑步類應用、一些懶得對接廠商推送通道的IM應用、消息推送資訊類應用等。

    一方面流氓軟件用各種流氓手段進行保活,另一方面系統加大殺后臺的力度,導致我們一些真正需要在后臺運行的應用被誤殺,苦不堪言。

    5、優雅的保活?

    為了做到保活,出現了不少「黑科技」,比如 1 個像素的 Activity,播放無聲音頻,雙進程互相守護等(可以讀讀這個系列:《應用保活終極總結(一):Android6.0以下的雙進程守護保活實踐》、《應用保活終極總結(二):Android6.0及以上的保活實踐(進程防殺篇)》、《應用保活終極總結(三):Android6.0及以上的保活實踐(被殺復活篇)》)。

    這些做法可以說是很流氓了,甚至破壞了 Android 的生態,好在隨著 Android 系統版本的更新,這些非常規的保活手段很多都已失效了。

    對于那些確實需要在后臺運行的應用,我們如何做到優雅的保活呢?

    6、加入后臺運行白名單,可以優雅的實現保活

    從 Android 6.0 開始,系統為了省電增加了休眠模式,系統待機一段時間后,會殺死后臺正在運行的進程。但系統會有一個后臺運行白名單,白名單里的應用將不會受到影響,在原生系統下,通過:「設置」 - 「電池」 - 「電池優化」 - 「未優化應用」,可以看到這個白名單。

    通常會看到下面這兩位: 

    下次被產品說「 XXX 都可以保活,為什么我們不行!」的時候,你就知道怎么懟回去了。大廠通過和手機廠商的合作,將自己的應用默認加入到白名單中。如果你在一個能談成這種合作的大廠,也就不用往下看了。

    好在系統還沒有拋棄我們,允許我們申請把應用加入白名單。

    首先,在 AndroidManifest.xml 文件中配置一下權限:

    <uses-permissionandroid:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

    可以通過以下方法,判斷我們的應用是否在白名單中:

    @RequiresApi(api = Build.VERSION_CODES.M)

    private boolean isIgnoringBatteryOptimizations() {

        boolean isIgnoring = false;

        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);

        if(powerManager != null) {

            isIgnoring = powerManager.isIgnoringBatteryOptimizations(getPackageName());

        }

        return isIgnoring;

    }

    如果不在白名單中,可以通過以下代碼申請加入白名單:

    @RequiresApi(api = Build.VERSION_CODES.M)

    public void requestIgnoreBatteryOptimizations() {

        try{

            Intent intent = newIntent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);

            intent.setData(Uri.parse("package:"+ getPackageName()));

            startActivity(intent);

        } catch(Exception e) {

            e.printStackTrace();

        }

    }

    申請時,應用上會出現這樣一個窗口:

    可以看到,這個系統彈窗會有影響電池續航的提醒,所以如果想讓用戶點允許,必須要有相關的說明。如果要判斷用戶是否點擊了允許,可以在申請的時候調用 startActivityForResult,在 onActivityResult 里再判斷一次是否在白名單中。

    7、加入后臺運行白名單的多廠商適配方法

    7.1 基本說明

    Android 開發的一個難點在于,各大手機廠商對原生系統進行了不同的定制,導致我們需要進行不同的適配,后臺管理就是一個很好的體現。幾乎各個廠商都有自己的后臺管理,就算應用加入了后臺運行白名單,仍然可能會被廠商自己的后臺管理干掉。

    如果能把應用加入廠商系統的后臺管理白名單,可以進一步降低進程被殺的概率。不同的廠商在不同的地方進行設置,一般是在各自的「手機管家」,但更難的是,就算同一個廠商的系統,不同的版本也可能是在不同地方設置。

    最理想的做法是,我們根據不同手機,甚至是不同的系統版本,給用戶呈現一個圖文操作步驟,并且提供一個按鈕,直接跳轉到指定頁面進行設置。但需要對每個廠商每個版本進行適配,工作量是比較大的。我使用真機測試了大部分主流 Android 廠商的手機后,整理出了部分手機的相關資料。

    首先我們可以定義這樣兩個方法:

    /**

     * 跳轉到指定應用的首頁

     */

    private void showActivity(@NonNull String packageName) {

        Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);

        startActivity(intent);

    }

     

    /**

     * 跳轉到指定應用的指定頁面

     */

    private void showActivity(@NonNull String packageName, @NonNull String activityDir) {

        Intent intent = new Intent();

        intent.setComponent(newComponentName(packageName, activityDir));

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        startActivity(intent);

    }

    以下是部分手機的廠商判斷,跳轉方法及對應設置步驟,跳轉方法不保證在所有版本上都能成功跳轉,都需要加 try catch。

    7.2 華為

    廠商判斷:

    public boolean isHuawei() {

        if(Build.BRAND == null) {

            return false;

        } else{

            return Build.BRAND.toLowerCase().equals("huawei") || Build.BRAND.toLowerCase().equals("honor");

        }

    }

    跳轉華為手機管家的啟動管理頁:

    private void goHuaweiSetting() {

        try{

            showActivity("com.huawei.systemmanager",

                "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");

        } catch(Exception e) {

            showActivity("com.huawei.systemmanager",

                "com.huawei.systemmanager.optimize.bootstart.BootStartActivity");

        }

    }

    操作步驟:應用啟動管理 -> 關閉應用開關 -> 打開允許自啟動

    7.3 小米

    廠商判斷:

    public static boolean isXiaomi() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("xiaomi");

    }

    跳轉小米安全中心的自啟動管理頁面:

    private void goXiaomiSetting() {

        showActivity("com.miui.securitycenter",

            "com.miui.permcenter.autostart.AutoStartManagementActivity");

    }

    操作步驟:授權管理 -> 自啟動管理 -> 允許應用自啟動

    7.4 OPPO

    廠商判斷:

    public static boolean isOPPO() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("oppo");

    }

    跳轉 OPPO 手機管家:

    private void goOPPOSetting() {

        try{

            showActivity("com.coloros.phonemanager");

        } catch(Exception e1) {

            try{

                showActivity("com.oppo.safe");

            } catch(Exception e2) {

                try{

                    showActivity("com.coloros.oppoguardelf");

                } catch(Exception e3) {

                    showActivity("com.coloros.safecenter");

                }

            }

        }

    }

    操作步驟:權限隱私 -> 自啟動管理 -> 允許應用自啟動

    7.5 VIVO

    廠商判斷:

    public static boolean isVIVO() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("vivo");

    }

    跳轉 VIVO 手機管家:

    private void goVIVOSetting() {

        showActivity("com.iqoo.secure");

    }

    操作步驟:權限管理 -> 自啟動 -> 允許應用自啟動

    7.6 魅族

    廠商判斷:

    public static boolean isMeizu() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("meizu");

    }

    跳轉魅族手機管家:

    private void goMeizuSetting() {

        showActivity("com.meizu.safe");

    }

    操作步驟:權限管理 -> 后臺管理 -> 點擊應用 -> 允許后臺運行

    7.7 三星

    廠商判斷:

    public static boolean isSamsung() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("samsung");

    }

    跳轉三星智能管理器:

    private void goSamsungSetting() {

        try{

            showActivity("com.samsung.android.sm_cn");

        } catch(Exception e) {

            showActivity("com.samsung.android.sm");

        }

    }

    操作步驟:自動運行應用程序 -> 打開應用開關 -> 電池管理 -> 未監視的應用程序 -> 添加應用

    7.8 樂視

    廠商判斷:

    public static boolean isLeTV() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("letv");

    }

    跳轉樂視手機管家:

    private void goLetvSetting() {

        showActivity("com.letv.android.letvsafe",

            "com.letv.android.letvsafe.AutobootManageActivity");

    }

    操作步驟:自啟動管理 -> 允許應用自啟動

    7.9 錘子

    廠商判斷:

    public static boolean isSmartisan() {

        return Build.BRAND != null&& Build.BRAND.toLowerCase().equals("smartisan");

    }

    跳轉手機管理:

    private void goSmartisanSetting() {

        showActivity("com.smartisanos.security");

    }

    操作步驟:權限管理 -> 自啟動權限管理 -> 點擊應用 -> 允許被系統啟動。

    8、友商致敬?

    在之前做的跑步應用中,我在設置里增加了一個權限設置頁面,將上面提到的設置放在這里面。

    最近發現友商某咚也跟進了,圖 1 是我們做的,圖 2 是某咚做的: 

    某咚從設計、從我寫的不夠好的文案,甚至是我從十幾臺手機上一張一張截下來的圖,進行了全方位的致敬。感謝某咚的認可,但最近在某個發布會上聽到這么一句話:在致敬的同時,能不能說一句謝謝?

    某咚的致敬,一方面說明了目前確實存在進程容易被殺,保活難度大的問題,另一方面也說明了這種引導用戶進行白名單設置的手段是有效的。

    附錄:更多相關技術文章

    應用保活終極總結(一):Android6.0以下的雙進程守護保活實踐

    應用保活終極總結(二):Android6.0及以上的保活實踐(進程防殺篇)

    應用保活終極總結(三):Android6.0及以上的保活實踐(被殺復活篇)

    Android進程保活詳解:一篇文章解決你的所有疑問

    Android端消息推送總結:實現原理、心跳保活、遇到的問題等

    深入的聊聊Android消息推送這件小事

    為何基于TCP協議的移動端IM仍然需要心跳保活機制?

    微信團隊原創分享:Android版微信后臺保活實戰分享(進程保活篇)

    微信團隊原創分享:Android版微信后臺保活實戰分享(網絡保活篇)

    移動端IM實踐:實現Android版微信的智能心跳機制

    移動端IM實踐:WhatsApp、Line、微信的心跳策略分析

    Android P正式版即將到來:后臺應用保活、消息推送的真正噩夢

    全面盤點當前Android后臺保活方案的真實運行效果(截止2019年前)

    一文讀懂即時通訊應用中的網絡心跳包機制:作用、原理、實現思路等

    融云技術分享:融云安卓端IM產品的網絡鏈路保活技術實踐

    正確理解IM長連接的心跳及重連機制,并動手實現(有完整IM源碼)

    2020年了,Android后臺保活還有戲嗎?看我如何優雅的實現!

    >> 更多同類文章 ……

    (本文同步發布于:http://www.52im.net/thread-2881-1-1.html



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 久久国产成人亚洲精品影院| 免费a级毛片无码a∨免费软件| 玖玖在线免费视频| 久久99国产综合精品免费| 亚洲免费观看网站| 日亚毛片免费乱码不卡一区| 久久免费视频精品| 在线观看亚洲成人| 国产亚洲成在线播放va| 成年在线观看网站免费| 亚洲欧洲日产国产最新| 精品国产污污免费网站| 亚洲一级片免费看| 香港经典a毛片免费观看看| 久久aⅴ免费观看| 亚洲片国产一区一级在线观看| 四虎必出精品亚洲高清| 亚洲伊人久久综合中文成人网| 91亚洲自偷在线观看国产馆| 永久免费A∨片在线观看| 国产自偷亚洲精品页65页| 一个人看的www视频免费在线观看 一个人看的免费观看日本视频www | 人成午夜免费大片在线观看| 国产免费牲交视频| 亚洲AV无码之国产精品| 最好免费观看韩国+日本| 亚洲人av高清无码| 国产美女精品久久久久久久免费 | 高清国语自产拍免费视频国产| 亚洲天堂2016| aa级一级天堂片免费观看| 亚洲剧情在线观看| 成人毛片免费网站| 亚洲精品伦理熟女国产一区二区| 久久国产免费福利永久| xxxx日本在线播放免费不卡| 日韩亚洲国产二区| 亚洲国产成人精品无码区在线观看| 亚洲免费在线播放| 亚洲色大成网站www| 亚洲一区二区三区偷拍女厕 |