Androidベースのまとめ-プロセスの優先度と優先度を上げる方法(Serviceはできるだけ死なない方法)

10978 ワード

プロセスのライフサイクル
Androidシステムは、できるだけ長い間アプリケーションプロセスを継続しますが、メモリが低すぎる場合は、古いプロセスを削除する必要があります.どのプロセスが残るか、どのプロセスが殺されるかを決定するために、システムは、プロセスで実行されているコンポーネントおよびコンポーネントの状態に基づいて、各プロセスに優先度レベルを割り当てます.優先度が最も低いプロセスはまず殺される.このプロセスの重要性の階層は主に5つの等級がある.Androidは1つのプロセスのレベルをできるだけ高く評価します.たとえば、プロセスには、サービスプロセスではなく可視プロセスとみなされるactivityとサービスがあります.
1つのプロセスのレベルは、他のプロセスがそれに依存して上昇する可能性があります.他のプロセスにサービスを提供するプロセスレベルは、そのサービスを使用するプロセスよりも常に高いです.例えば、AプロセスのコンテンツプロバイダがプロセスBのクライアントにサービスを提供する場合、またはプロセスAのサービスがプロセスBのコンポーネントにバインドされている場合、AプロセスはプロセスBのレベル以上である.  
プロセスの5つの共通レベル:
一.フォアグラウンドプロセス(Foreground process)フォアグラウンドプロセスは、ユーザが現在していることに必要なプロセスであり、以下の様々な状況の1つを満たす場合、1つのプロセスはフォアグラウンドであると考えられる.
  • プロセスは、ユーザと対話中のActivityを持つ.
  • プロセスは、1サービスがユーザーと対話しているActivityにバインドされているサービスを持っています.②サービスはフロントで実行され、startForeground()が呼び出されます.③サービスは、ライフサイクルコールバック関数(onCreate()、onStart()、or onDestroy()を実行しています.
  • プロセスは、onReceive()メソッドを実行しているBroadcastReceiverを持っています.

  • フロントプロセスを殺すには、フロントプロセスの優先度が最も高いため、ユーザーのインタラクションが必要です.
    二.可視プロセス(Visible process)は、1つのプロセスにフロントのコンポーネントが含まれていない場合でも、画面上でユーザーに見られることができる.次のいずれかの条件を満たすと、プロセスは表示されます.
  • プロセスは、フロントにいないActivityを持っていますが、onPause()呼び出し後にonStop()が呼び出されていない状態がユーザーに表示されます.たとえば、フロントのactivityがダイアログボックスを開き、activityが後で表示されます.
  • プロセスは、可視(またはフロント)Activityにバインドされたサービスを有します.

  • 可視プロセスも重要とされ、すべてのフロントプロセスの実行を保証するために可視プロセスを殺さざるを得ない場合を除き、一般的には破棄されません.
    三.サービスプロセス(Service process)あるプロセスでサービスが実行されている場合、このサービスはstartService()によって開かれ、上記の2つの優先度に属さない場合、このプロセスはサービスプロセスである.
    サービスプロセスは、ユーザが見ることができるものにバインドされていないが、バックグラウンドで音楽を再生したり、バックグラウンドでデータをダウンロードしたりするなど、ユーザが関心を持っていることが一般的である.したがって、フロントプロセスと可視プロセスの実行を維持するためにシステムメモリが不足していない限り、システムはできるだけ実行を維持します.
    四.バックグラウンドプロセス(Background process)は、プロセスが上記の3つの状況に属していないが、プロセスがユーザに見えないactivity(activityのonStop()が呼び出されているが、onDestroy()が呼び出されていない状態)を持っている場合、プロセスはバックグラウンドプロセスであるとみなす.
    バックグラウンドプロセスはユーザー体験に直接影響を与えず、フロントプロセス、可視プロセス、サービスプロセスのためにバックグラウンドプロセスを任意に殺す.
    通常、多くのバックグラウンドプロセスが存在し、LRU(least recently used)リストに保存されます.これにより、ユーザーが最近使用したactivityが最後に破棄されることを保証します.つまり、最初に破棄する時間が最も遠いactivityです.
    5.空のプロセスアクティブなアプリケーションコンポーネントが1つのプロセスに含まれていない場合は、空のプロセスとみなされます.たとえば、1つのプロセスではデータが実行されていませんが、メモリにはこのアプリケーションのプロセススペースが1つ存在します.このプロセスを保存する唯一の理由は、キャッシュの必要性のために、次回このプロセスのコンポーネントを起動するときの起動時間を短縮するためです.システムは、プロセスキャッシュと最下位カーネルキャッシュのリソースをバランスさせるために、空のプロセスを殺すことがよくあります.
    Serviceでの新規スレッドと直接新規スレッドの違い
    (1)Activityに直接スレッドを新規作成して時間のかかる操作を行うと,そのActivityがデスクトップまたは他の状況に終了するとバックグラウンドプロセスとなる.
    (2)サービスでスレッドを新規に起動すると,Androidはプロセスにおける現在アクティブなコンポーネントの重要度に応じてサービスプロセスと判断し,(1)より優先度が高い.
    サービス・プロセスの優先度はバックグラウンド・プロセスの優先度よりも高いため、長時間の操作を開始する必要があるactivityでは、作業スレッドを作成するよりもserviceを開くほうがよく、特に操作がactivityの持続時間を超える可能性が高い場合に便利です.
    例えば、画像ファイルをアップロードするには、ユーザーがactivityを離れたときも作業が進行するようにサービスを開いてアップロード作業を行う必要があります.サービスを使用すると、少なくともサービス・プロセスの優先度が操作に保証されます.
    できるだけサービスが不死身であることを保証するためのテクニックのまとめ
    1、AndroidManifest.xmlファイルではintent-filterについてandroid:priority=「1000」という属性で最高優先度を設定できます.1000は最高値で、数字が小さいほど優先度が低くなり、ブロードキャストにも役立ちます.
    <service android:name="com.dbjtech.acbxt.waiqin.UploadService" android:enabled="true" >  
         <intent-filter android:priority="1000" >  
             <action android:name="com.dbjtech.myservice" />  
         </intent-filter>  
    </service> 

    2、onStartCommandでstartForeground()メソッドを呼び出してServiceをフロントプロセスレベルに引き上げ、onDestroyでstopForeground()メソッドを呼び出すことを覚えておいてください.
    3、onStartCommandメソッド、START_に戻るSTICKY. 手動でSTART_に戻るSTICKY,親測serviceがメモリ不足でkillされ、メモリがある場合、serviceが再作成されたほうがいいが、プロセスが乾くなど、どんな場合でも再構築される保証はない.
    public int onStartCommand(Intent intent, int flags, int startId) {  
         flags = START_STICKY;  
         return super.onStartCommand(intent, flags, startId);  
    } 
    

    補足:onStartCommand()メソッドは、int整形を返します.この整形には以下の4つの値があります:1):START_STICKY:サービスプロセスがkillによって削除された場合、サービスを保持する状態は開始状態ですが、送信されたintentオブジェクトは保持されません.その後、サービスステータスが開始状態であるため、サービスを作成すると必ずonStartCommand(Intent,int,int)メソッドが呼び出されます.その間にサービスに起動コマンドが渡されない場合、パラメータIntentはnullになります.2):START_NOT_STICKY:「非粘性」.この戻り値を使用すると、onStartCommandの実行後に異常killでサービスが停止した場合、自動的にサービスが再起動されません3):START_REDELIVER_INTENT:Intentを再送します.この戻り値を使用すると、onStartCommandの実行後にサービスが異常killによって削除されると、自動的にサービスが再起動され、Intentの値が入力されます.4):START_STICKY_COMPATIBILITY:START_STICKYの互換バージョンですが、サービスがkillされた後に必ず再起動できる保証はありません.
    4、onDestroyメソッドで放送してサービスを再起動する.サービス+broadcast方式は、サービスがondestoryを歩くと、カスタムブロードキャストが送信され、ブロードキャストが受信されると、サービスが再起動される.(サードパーティアプリケーションやsettingで-アプリケーション-強制停止した場合、APPプロセスはそのまま終了し、onDestroyメソッドが入らないため、実行する保証はありません)
            <receiver android:name="com.dbjtech.acbxt.waiqin.BootReceiver" >
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="com.dbjtech.waiqin.destroy" />//        action
                </intent-filter>
            </receiver>

    onDestroyの場合:
        @Override
        public void onDestroy() {
            stopForeground(true);
            Intent intent = new Intent("com.dbjtech.waiqin.destroy");
            sendBroadcast(intent);
            super.onDestroy();
        }

    BootReceiverで:
    public class BootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("com.dbjtech.waiqin.destroy")) {
                //TODO
                //        service     
                    startUploadService(context);
            }
        }
    }

    5、傍受システム放送はサービス状態を判断する.携帯電話の再起動、インタフェースの起動、アプリケーションのステータスの変更など、システムのいくつかの放送を通じて傍受され、キャプチャされ、私たちのサービスがまだ生存しているかどうかを判断します.
            <receiver android:name="com.dbjtech.acbxt.waiqin.BootReceiver" >
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.intent.action.PACKAGE_RESTARTED" />
                    <action android:name="com.dbjtech.waiqin.destroy" />
                </intent-filter>
            </receiver>

    BroadcastReceiver:
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
                System.out.println("     ....");
                startUploadService(context);
            }
            if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
                    startUploadService(context);
            }
        }

    6、アプリケーションにPersistent属性を加える.Androidのドキュメントを見ると、プロセスが長期にわたって活動していないか、システムがリソースを必要としている場合、自動的にポータルを整理し、サービスや非表示のActivityなどのプロセスを殺すことがわかります.しかし、データ・キャッシュ・プロセス、ステータス・モニタリング・プロセス、リモート・サービス・プロセスなどのプロセスが殺されたくない場合は、プロセスが殺されないようにするにはどうすればいいですか.
    add android:persistent=”true” into the section in your AndroidManifest.xml
    以上の属性を加えると、プロセスを常駐メモリプロセスに設定することになります.これは乱用できないことを覚えておいてください.一般的には/system/appの下に置かれているappにしか適用されません.システムではこれのサービスを使っています.appが多ければ、システム全体が崩壊する可能性があります.例えばシステムphoneにandroid:persistent="true"属性が配置され、Phone.apkは/system/app/ディレクトリにインストールされているので、起動時にPhoneAppクラスが自動的に起動します.
    参照先:http://blog.csdn.net/mad1989/article/details/22492519#