1. 程式人生 > >android程序保活-前臺server+畫素保活

android程序保活-前臺server+畫素保活

借鑑部分

背景:從產品的角度來說,任何一個應用程式的PM都希望自己的應用程式在使用者手機中的留存率高些些,之前我接觸到的一個業務需求也是如此,要求提升應用程式在國內第三方廠商ROM中的存活率。

如前篇所述踩坑篇,保活策略只在android原生系統中起作用,在國內第三方廠商ROM中是沒有效果的。為了提高app在第三方ROM中的存活率,調研了一些方法,最終選擇某移動社交應用的1畫素保活方案,因為這個方案人家沒有開源,所以只能自己動手。


針對國內第三方廠商ROM在退屏後應用很快被殺的調查發現,原生系統在記憶體充足的情況下,使用者執行熄屏的操作不會立即kill app,但是第三方ROM會,推測是修改了ROM在熄屏時執行了記憶體清理工作,不論此時手機記憶體是否充足都執行清理。對於沒有加入到廠家ROM清理白名單中的app,不可避免的被殺。當然有的人會不同意,說像QQ,微信之類的就沒有在熄屏後被殺,使用者也沒有手動將其加入系統白名單中。這種情況是QQ和微信已經加入到系統的白名單中了,當然不需要使用者手動添加了。不過這已經經
是技術人員可以解決的了,需要雙方的商務洽談了。



我在使用國內第三方ROM MIUI時發現,如果保持當前應用在前臺存活,執行熄屏,分別等待1分鐘,5分鐘,10分鐘後,再次開啟螢幕時,app會存活,即使被殺掉也會重新啟動。基與此並結合1畫素保活方案,我在應用程式啟動時註冊一個監聽器監聽螢幕亮屏熄屏,當用戶啟動我的應用程式時,並沒有按退出的應用程式,切換到其他應用程式使我的應用程式進入後臺待機模式,只要我方應用沒有被殺死,當用戶熄屏時,會啟動OnepxActivity,這樣人為的製造了一個系統欺騙,告訴ROM,使用者執行熄屏時,當前UI是我的應用程式。這樣,當用戶亮屏時,因為有監聽,OnepxActivity也會銷燬,達到一個使用者無感知同時又提高了我方的應用在第三方ROM中的存活率。

原創部分:

(1)前臺伺服器建立:

1,在前臺伺服器的建立(server.class):在類中,我建立了一個執行緒,是因為在像伺服器做得到請求的時候,需要將程式放到執行緒中實現在onStartCommand函式中呼叫畫素的廣播。

包com.example.administrator.qshAndroid.web;


匯入android.annotation.TargetApi;
匯入android.app.Notification;
匯入android.app.NotificationManager;
匯入android.app.Service;
匯入android.content.Context;
匯入android.content.Intent; 匯入android.content.IntentFilter; 匯入android.os。*; 匯入android.widget.Toast; import com.example.administrator.demo.R; import com.example.administrator.qshAndroid.utils.OnePixelReceiver; import org.json.JSONException; import org.json.JSONObject; / ** *由管理員在2017年12月27日建立。 * / 公共類伺服器擴充套件服務{ 公共靜態最終詮釋NOTIFICATION_ID = 0x11; 私人靜態PowerManager.WakeLock mWakeLock; private String memberLoginBM =“”; private String getCode =“”; private OnePixelReceiver mOnepxReceiver; String infoBack =“”; int dataBack = 0; 公共伺服器(){ } //必須實現的,繫結改服務時回撥該方法 @覆蓋 公共IBinder onBind(意圖意圖){ 丟擲新的UnsupportedOperationException(“尚未實現”); } //伺服器被建立時回撥 @覆蓋 public void onCreate(){ // acquireWakeLock(本); super.onCreate(); } //伺服器斷開連線時回撥 @覆蓋 public boolean onUnbind(Intent intent){ Toast.makeText(server.this,“onUnbind!”,Toast.LENGTH_SHORT).show(); 返回true; } //伺服器被關閉前回調 @覆蓋 public void onDestroy(){ stopForeground(true); //停止前臺服務 - 引數:表示是否移除之前的通知 Toast.makeText(server.this,“destory!”,Toast.LENGTH_SHORT).show(); 意圖localIntent =新的意圖(); localIntent.setClass(this,server.class); //銷燬時重新啟動服務 this.startService(localIntent); } @覆蓋 public void onRebind(Intent intent){ Toast.makeText(server.this,“onRebind!”,Toast.LENGTH_SHORT).show(); super.onRebind(意向); } @覆蓋 公共int onStartCommand(意圖intent,詮釋標誌,詮釋startId){ //註冊監聽螢幕的廣播,啟動畫素保活 mOnepxReceiver = new OnePixelReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction( “android.intent.action.SCREEN_OFF”); intentFilter.addAction( “android.intent.action.SCREEN_ON”); intentFilter.addAction( “android.intent.action.USER_PRESENT”); registerReceiver(mOnepxReceiver,intentFilter); memberLoginBM = intent.getStringExtra(“allMessage”); getCode = intent.getStringExtra(“code”); new Thread(new MyThread2())。start(); 返回START_STICKY; } 公共靜態類InnerService延伸服務{ @覆蓋 公共IBinder onBind(意圖意圖){ 返回null; } @覆蓋 public void onCreate(){ super.onCreate(); //傳送與KeepLiveService中ID相同的通知,然後將其取消並取消自己的前臺顯示 Notification.Builder builder = new Notification.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setContentTitle(“Foreground Service2”); builder.setContentText( “----------------------------”); startForeground(NOTIFICATION_ID,builder.build()); new Handler()。postDelayed(new Runnable(){ @覆蓋 public void run(){ stopForeground(真); NotificationManager manager =(NotificationManager)getSystemService(NOTIFICATION_SERVICE); manager.cancel(NOTIFICATION_ID); stopSelf(); } },100); } @覆蓋 公共int onStartCommand(意圖intent,詮釋標誌,詮釋startId){ //標記(TAG,“VMDaemonService-> onStartCommand”); / ** *這裡返回值是使用系統服務的機制自動重新啟動,不過這種方式以下兩種方式不適用: * 1.服務第一次被異常殺死後會在5秒內重啟,第二次被殺死會在10秒內重啟,第三次會在20秒內重啟,一旦在短時間內服務被殺死達到5次,則系統不再拉起。 * 2.程序被取得Root許可權的管理工具或系統工具通過forestop停止掉,無法重啟。 * 3.一些定製化比較高的第三方系統也不適用 * / 返回START_STICKY; } } //子執行緒接收資料,主執行緒修改資料 公共類MyThread2實現了Runnable { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @覆蓋 public void run(){ infoBack = serverPick.executeHttpGet(memberLoginBM,getCode); JSONObject jsonObject = null; 嘗試{ jsonObject = new JSONObject(infoBack); dataBack = jsonObject.getInt(“success”); Notification.Builder builder = new Notification.Builder(server.this); 引用程式碼= “1”; if(dataBack == 1){ if(Build.VERSION.SDK_INT <18){ startForeground(NOTIFICATION_ID,new Notification()); // API <18,此方法能有效隱藏Notification上的圖示 } else { // API 18以上,傳送通知並將其置為前臺後,啟動InnerService builder.setSmallIcon(R.mipmap.ic_launcher); //builder.setTicker("Foreground Service Start“); builder.setContentTitle( “企商匯”); builder.setContentText( “你有新的業務資訊沒有讀取!”); builder.setDefaults(Notification.DEFAULT_SOUND); startForeground(NOTIFICATION_ID,builder.build()); startService(new Intent(server.this,InnerService.class)); 了Thread.sleep(10000); 跑(); //繼續; } } else if(dataBack == 2){ if(Build.VERSION.SDK_INT <18){ startForeground(NOTIFICATION_ID,new Notification()); // API <18,此方法能有效隱藏Notification上的圖示 } else { //Notification.Builder builder = new Notification.Builder(server.this); builder.setSmallIcon(R.mipmap.ic_launcher); //builder.setTicker("Foreground Service Start“); builder.setContentTitle( “企商匯”); builder.setContentText( “你暫時沒有新的業務資訊!”); //builder.setDefaults(Notification.DEFAULT_SOUND); startForeground(NOTIFICATION_ID,builder.build()); startService(new Intent(server.this,InnerService.class)); 了Thread.sleep(10000); 跑(); // Toast.makeText(server.this,“你暫時沒有新的業務資訊!”,Toast.LENGTH_SHORT).show(); } } else { if(Build.VERSION.SDK_INT <18){ startForeground(NOTIFICATION_ID,new Notification()); // API <18,此方法能有效隱藏Notification上的圖示 } else { builder.setSmallIcon(R.mipmap.ic_launcher); //builder.setTicker("Foreground Service Start“); builder.setContentTitle( “企商匯”); builder.setContentText( “伺服器,通訊錯誤,請重啟應用程式!”); //builder.setDefaults(Notification.DEFAULT_SOUND); startForeground(NOTIFICATION_ID,builder.build()); startService(new Intent(server.this,InnerService.class)); 了Thread.sleep(10000); 跑(); } } catch(JSONException e){ e.printStackTrace(); catch(InterruptedException e){ e.printStackTrace(); } } } }
2,在前臺AndroidMainfest.xml檔案中註冊伺服器
<service android:name =“com.example.administrator.qshAndroid.web.server”>
            <意圖濾波器>
                <action android:name =“com.example.administrator.qshAndroid.web.server”/>
            </意圖濾波器>
</服務>
3,在另一個活動中啟動伺服器
Intent intent2 = new Intent(menu.this,server.class);
intent2.putExtra( “allMessage”,allMessage);
intent2.putExtra( “程式碼”, “2”);
startService(intent2);
如圖4所示,在1中建立的畫素BroadcastReceiver.java
包com.example.administrator.qshAndroid.utils;

匯入android.content.BroadcastReceiver;
匯入android.content.Context;
匯入android.content.Intent;
匯入android.content.IntentFilter;

/ **
 *由管理員於2018-1-9建立。
 * /
公共類OnePixelReceiver擴充套件BroadcastReceiver {
    私人靜態OnePixelReceiver接收器;
    @覆蓋
    public void onReceive(Context context,Intent intent){
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {    //螢幕關閉啟動1畫素Activity
            Intent it = new Intent(context, OnePiexlActivity.class);
            it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(it);
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {   //螢幕開啟 結束1畫素
            context.sendBroadcast(new Intent("finish activity"));
        }
    }
    public static void register1pxReceiver(Context context) {
        if (receiver == null) {
            receiver = new OnePixelReceiver();
        }
        context.registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
        context.registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
    }

    public static void unregister1pxReceiver(Context context) {
        context.unregisterReceiver(receiver);
    }
}
5,畫素的活性(OnePiexActivity.java)
包com.example.administrator.qshAndroid.utils;

匯入android.app.Activity;
匯入android.content.BroadcastReceiver;
匯入android.content.Context;
匯入android.content.Intent;
匯入android.content.IntentFilter;
匯入android.os.Bundle;
匯入android.os.PowerManager;
匯入android.view.Gravity;
匯入android.view.Window;
匯入android.view.WindowManager;

/ **
 *由管理員於2018-1-9建立。
 * /
公共類OnePiexlActivity擴充套件活動{
    私人BroadcastReceiver endReceiver;

    @覆蓋
    保護無效的onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //設定1個畫素
        視窗視窗= getWindow();
        window.setGravity(Gravity.LEFT | Gravity.TOP);
        WindowManager.LayoutParams params = window.getAttributes();
        params.x = 0;
        params.y = 0;
        params.height = 1;
        params.width = 1;
        window.setAttributes(PARAMS);

        //結束該頁面的廣播
        endReceiver = new BroadcastReceiver(){
            @覆蓋
            public void onReceive(Context context,Intent intent){
                完();
            }
        };
        registerReceiver(endReceiver,new IntentFilter(“finish”));
        //檢查螢幕狀態
        checkScreen();
    }

    @覆蓋
    保護無效onResume(){
        super.onResume();
        checkScreen();
    }

    / **
     *檢查螢幕狀態isScreenOn為true螢幕“亮”結束該活動
     * /
    private void checkScreen(){
        PowerManager pm =(PowerManager)OnePiexlActivity.this.getSystemService(Context.POWER_SERVICE);
        boolean isScreenOn = pm.isScreenOn();
        if(isScreenOn){
            完();
        }
    }
}
如圖6所示,設定畫素為透明:
<style name =“OnePixelActivity”parent =“android:Theme.Holo.Light.NoActionBar”> //無標題
        <item name =“android:windowIsTranslucent”> true </ item> //透明
如圖7所示,在XML註冊中OnePiexActivity.java
<activity android:name =“com.example.administrator.qshAndroid.utils.OnePiexlActivity”
                   機器人:screenOrientation = “畫像”
                   機器人:主題= “@風格/ OnePixelActivity”> </活動>
邏輯流程:在主活動中,呼叫我們的前臺伺服器,在前臺伺服器中呼叫畫素廣播,畫素廣播呼叫畫素的活動,這樣在鎖屏的時候,呼叫活動,開啟的時候關閉即可就這樣,恭喜。你,你的Android的被保活了。

相關推薦

android程序-前臺server+

借鑑部分 背景:從產品的角度來說,任何一個應用程式的PM都希望自己的應用程式在使用者手機中的留存率高些些,之前我接觸到的一個業務需求也是如此,要求提升應用程式在國內第三方廠商ROM中的存活率。 如前篇所述踩坑篇,保活策略只在android原生系統中起作用,在國內第三方廠商R

Android 程序--1

在Android開發中,必定有一些應用是需要常駐後臺執行的,比如長期對某個事物的監聽或者長期掃描等等。如果Android手機鎖屏了,就有一定機率會給手機廠商的OS系統給殺死。所以,為了在手機鎖屏之後避免應用給殺死,我們可以選擇提高程序的優先順序,所以使用1畫素A

Android開發 螢幕適配之密度適配

由於市場上採用Android系統的裝置種類繁多,迫使Andriod開發人員不得不做煩人的適配工作。 適配工作包括對安裝不同Android版本的裝置進行適配,對不同螢幕的裝置進行適配等。 而螢幕適配又包括: 螢幕尺寸(small,normal,large,xlarge , 這

android-getTextSize返回值是以(px)為單位的,setTextSize()以sp為單位

使用如下程式碼時,發現字號不會變大,反而會變小: size = (int) mText.getTextSize() + 1; mText.setTextSize(size); 後來發現getTextSize返回值是以畫素(px)為單位的,而setTextSize()是以sp為單位的,兩者單位不一致才造成這樣的

Android菜鳥筆記-獲取攝像頭

前言: 獲取攝像頭的畫素值,通過獲取相機設定中支援拍照的最大寬度和最大高度就可算到攝像頭的畫素值了,當然跟手機廠商標稱的還是有差別的。比如標稱200W的通過計算1200*1600=1920000=192W≈200W。 定義CameraUtils類: import java.

Android遊戲Graphics繪圖之影象操作

  我們在玩遊戲時經常會看到一些影象的特效,比如半透明等效果。要實現這些效果並不難,只需要對影象本身的畫素執行操作。Android中的 Bitmap同樣提供了操作畫素的方法,可以通過getPixels方法來獲得該影象的畫素並放到一個數組中,我們處理這個畫素陣列就可以了,最後

Android之D面試題②程序的一般套路(1Activity/賬號同步/Jobscheduler/系統服務捆綁)

       讀到這裡,你或許有一個疑問,假設現在記憶體不足,空程序都被殺光了,現在要殺後臺程序,但是手機中後臺程序很多,難道要一次性全部都清理掉?當然不是的,程序是有它的優先順序的,這個優先順序通過程序的adj值來反映,它是linux核心分配給每個系統程序的一個值,代表程序的優先順序,程序回收機制就是根據這

android程序兩年實戰經驗(已經上線使用)

程序保活參考: https://www.jianshu.com/p/53c4d8303e19 https://github.com/08carmelo/android-keeplive 以上地址這個我是通過鴻洋的公眾號看到的,我們公司做的是VPN撥號必須要求app保持後臺執行,上面連

Android程序相關實踐

最近測試APP時接到個需求:1畫素保活 打眼一看,應該跟安卓程序有關係,索性找點詳細的資料來了解下: 系統什麼時候殺掉一個程序?為什麼殺掉這個程序?怎樣最大程度保活一個程序?詳細的講解可以參考這個連結------https://www.cnblogs.com/Doing-what-I-love/p/553

Android 程序資料

現在發現App在後臺執行越來越難了。App在華為手機後臺死的非常快,之前看網上說華為有白名單,網上也通過改包名的方式來驗證了。但是半信半疑的,直到諮詢了華為的客服給了一個郵箱 [email protected],回覆的資料 應用加白名單簡化流程v0.1

【騰訊Bugly乾貨分享】Android程序招式大全

【騰訊Bugly乾貨分享】Android程序保活招式大全 本文來自於騰訊bugly開發者社群,非經作者同意,請勿轉載,原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 作者:騰訊——張興華 目前市面上的應用,貌似除了微信和手Q都會

Android程序招數概覽

Android中的程序保活應該分為兩個方面: 提高程序的優先順序,減少被系統殺死的可能性 在程序已經被殺死的情況下,通過一些手段來重新啟動應用程序 本文針對這兩方面來程序闡述,並給出相應的示例。其實主要也是在前人的基礎上做了一個總結,並進行了一些實踐。 閱讀本

android程序實戰(已經上線使用)

https://github.com/08carmelo/android-keeplive 這個我是通過鴻洋的公眾號看到的,我們公司做的是vpn撥號必須要求app保持後臺執行,上面介紹的很詳細,我用的github中使用的程式碼 這個具體需要你自己看 我使用後其實還是有

Android程序招式大全

作者:騰訊——張興華目前市面上的應用,貌似除了微信和手Q都會比較擔心被使用者或者系統(廠商)殺死問題。本文對 Android 程序拉活進行一個總結。Android 程序拉活包括兩個層面:A. 提供程序優先順序,降低程序被殺死的概率B. 在程序被殺死後,進行拉活本文下面就從這兩

android程序實踐(根據鴻洋大神彙總,本人忘性大備份下)

前言程序保活的關鍵點有兩個,一個是程序優先順序的理解,優先順序越高存活機率越大。二是弄清楚哪些場景會導致程序會kill,然後採取下面的策略對各種場景進行優化:提高程序的優先順序在程序被kill之後能夠喚醒程序優先順序Android一般的程序優先順序劃分:1.前臺程序 (Foreground process)2

Android 程序資料彙總與華為白名單那些事

現在發現App在後臺執行越來越難了。App在華為手機後臺死的非常快,之前看網上說華為有白名單,網上也通過改包名的方式來驗證了。但是半信半疑的,直到諮詢了華為的客服給了一個郵箱 [email protected],回覆的資料 應用加白名單簡化流程v0.1

Android程序回收機制和方案

1 Low Memory Killer機制 在Android系統中,程序的生命週期都是由系統來控制的。出於體驗和效能上的考慮,即使對一個App進行Home鍵還是Back鍵退出的操作,系統並不會真正殺掉該App的程序,它的程序依然存在於記憶體之中。因為這樣在下次要啟動這個App時就能更加快速。

Android程序(常駐記憶體)

Android將程序分為6個等級,它們按優先順序順序由高到低依次是:  1.前臺程序( FOREGROUND_APP);  2.可視程序(VISIBLE_APP );  3. 次要服務程序(SECONDARY_SERVER );  4.後臺程序 (HIDDEN_APP);  

Android程序精煉詳解

一、前期基礎知識儲備在之前的文章《如何保證Service在後臺不被殺死?》中,筆者分析了為什麼要保活Service、Service的幾種保活方法和Service保活的意義。今天的這篇文章就更進一步,講解程序保活的方法和意義。(1)什麼是程序保活?拿我們的手機應用程式QQ來說,

Android程序(最新)帶你淺析這幾種可行性的方案

1.概述   據前人驗證,在沒有白名單的情況下,安卓系統要做一個任何情況下都不被殺死的應用是基本不可能的,但是我們可以做到應用基本不被殺死,如果殺死可以立即復活.經過上網查詢,程序常駐的方案眾說紛紜,但是很多的方案都是不靠譜的或不是最好的,結合很多資料,今天總結一下And