Androidシステムの原生応用解析のデスクトップ目覚まし時計と関連原理応用のクロックタスクの応用(二)

8596 ワード

この文章は主にhttp://android.xsoftlab.net/training/scheduling/alarms.html#tradeoffsのSchenduling Repeating Alarmsの文章を大まかに翻訳します.
Alarms(AlarmManager類に基づく)は、あなたのアプリケーションを正常なライフサイクル以外で時間ベースのタスクを実行させます.例えば、Alarmを使って、毎日一つのサービスを開始して、天気予報をダウンロードしてもいいです.
Alarmsは以下の特徴を持っています.
  • は、固定時間または時間帯にIntentを設定することができます.
  • は、それらと放送を組み合わせてサービスを開始し、他の動作を実行しても良い.
  • それらは、あなたのアプリケーション以外で動作タスクを行うことができますので、あなたのアプリケーションが起動されていないときに、それらを使用してタスクをトリガしたり、タスクを実行したりします.
  • それらは、あなたのアプリケーションリソースの需要を低減するのを助けることができます.タイマーに依存しないでタスクを手配したり、バックグラウンドタスクを連続して実行したりすることができます.
  • トレードオフを理解する:
    比較的限られた応用範囲において、重複タスクを実行できる目覚まし時計は、その原理を比較的簡単に説明できます.これはあなたの応用にとっては、特に良い選択ではないかもしれません.悪い設計は設備の電力消費が速くなり、サーバーが頻繁に負荷状態になることを招く.よくあるトリガタスクのシーンは、あなたがアプリケーションのライフサイクル以外でサーバとデータ同期を行う場合、重複したクロックタスクを使って完成してみたいかもしれませんが、自分のサーバーを持っていれば、GCMとSync Adapterを組み合わせてこのタスクを完成できます.AlarmManagerよりも効果が高いかもしれません.
    トレードオフの練習:
    各クロックベースのタスクの設計は、システムリソースが悪用される可能性があります.例を挙げると、データ同期機能が非常に人気のあるアプリがあります.このデータの同期操作が毎日夜11時に行われると、接続されているサーバに行くのは、ずっと高負荷状態にあるかもしれません.時計の機能を使う時は以下の原則を守ってください.
  • は、クロックタスクのトリガ時間をランダム条件で上下にフロートし、一時的な点に集約しないでください.
  • .クロックタスクがトリガされた時、まずローカルタスクを処理します.ローカルタスクとは、サーバと相互作用しないタスクのことです.
  • .クロックタスクに基づくネットワーク要求は、同じ時間間隔周期に基づいて実行される必要がある.
  • クロックタスクの周波数を最低にすることを保証します.一日に一回がいいです.低いほどいいです
  • は、不必要な状況で設備を起動しないでください.
  • は、自分のクロックタスクマネージャの使用をできるだけ避ける.
  • クロックタスクを設定:
    上記の説明に基づいて、クロックタスクは、規則的にイベントまたはデータクエリを実行することに対して最良の選択であり、クロックタスクは、以下の特性を有する.
  • クロックタイプは、具体的には以下のクロックタイプの選択を参照してください.
  • トリガ時間は、過去の時間を設定すれば、アラームタスクは直ちに実行されます.
  • クロック間隔、例えば毎日、一時間ごとに、5秒ごとに.
  • Pending Intentは、クロックタスクがトリガ時に呼び出されることができます.もし数秒以内に同じPending Intentが設定されたら、前のジョブは後のタスクによって突き落とされます.
  • 選択クロックの種類について
    最初に考えるべきは時計のトリガタイプです.ここには二つの方法があります.一つは相対時間で、一つは真実な時間です.相対時間はシステム起動の時間間隔に基づいています.本当の時間は毎日何時ですか?この意味では、相対時間は過去の時間ベースのタスク(例を挙げて30秒ごとにタスクを実行する)に適しており、タイムゾーンの影響を受けない.実際の時間は、実際の世界時間に基づいた任務を実行するのに適しています.すべての選択が呼び覚まされる機能、つまり、画面が閉じられている状態でCPUを呼び覚まして作業を続けることができます.クロックタスクは設定された時間で実行できるように確保されています.もしあなたのアプリが時間に依存している場合、特に有用です.例を挙げると、小さな窓があります.それでは、すべての時計のタスクはあなたの設備が今度開かれる時に一緒に飛び出します.もしあなたがただ簡単に時間を過ごすごとにクロックタスクを実行するなら、(例えば30分ごとに)相対時間はとてもあなたに似合います.もしあなたが毎日の固定時間にクロックタスクを実行する必要があるなら、実際の時間に基づいたアラームタイプを選択してください.注意してください.いずれにしても、このような方法はいくつかの欠点があります.上記のように、実際の時間を使うと伸縮性が強くないかもしれません.できるだけ相対時間を使うことをお勧めします.
    以下はタイプです.
  • ELLAPSED_REALTIMEは時間量ベースのPending Intentを設定して、この時間量はシステム起動時から計算しますが、設備を起動しません.相対時間はまた設備が睡眠状態にある時間を含みます.
  • ELLAPSED_REALTIME_WAKEUPこれは上とほぼ同じです.起動時間に基づいていますが、時間が来たら設備を起動します.
  • RTCはこれは本当の時間に基づいていますが、デバイス
  • を起動しません.
  • RTC_WAKEUPこれもリアルタイムに基づいていますが、クロックタスクがトリガされた時にデバイスを起動します.
  • 次はELLAPSED_を使います.REALTIME_WAKEUPタイプの例:
    この例は、システムが起動してから30分後にタスクが起動し、その後30分ごとに再起動されます.
    // Hopefully your alarm will have a lower frequency than this!
    alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            AlarmManager.INTERVAL_HALF_HOUR,
            AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);
    この例は、システムが起動してから1分後にクロックタスクを起動し、デバイスを起動しますが、一回だけ実行します.
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    ...
    alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmReceiver.class);
    alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() +
            60 * 1000, alarmIntent);
    次にRTC_を使いますWAKEUPタイプの例:
    毎日午後2時近くに一つのタスクを実行し、設備を起動し、毎日この時間に繰り返し実行します.
    // Set the alarm to start at approximately 2:00 p.m.
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 14);
    // With setInexactRepeating(), you have to use one of the AlarmManager interval
    // constants--in this case, AlarmManager.INTERVAL_DAY.
    alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, alarmIntent);
    この例は毎日8時半に一つのタスクを実行し、デバイスを起動し、その後20分ごとに実行します.
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    ...
    alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmReceiver.class);
    alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    // Set the alarm to start at 8:30 a.m.
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 8);
    calendar.set(Calendar.MINUTE, 30);
    // setRepeating() lets you specify a precise custom interval--in this case,
    // 20 minutes.
    alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            1000 * 60 * 20, alarmIntent);
    クロックタスクをキャンセルする方法の例を以下に示します.
    // If the alarm has been set, cancel it.
    if (alarmMgr!= null) {
        alarmMgr.cancel(alarmIntent);
    }
    以下はシステムが起動する時、クロックタスクをどのように起動するかの方法です.
    デフォルトでは、システムがシャットダウンされた状態ですべてのクロックタスクがキャンセルされて実行されます.このようなことを防ぐために、デバイスが再起動された時に自動的にクロックタスクを再起動するように選択してください.これは、ユーザが手動で起動するアラームタスクを必要としない場合に、AlarmManagerを介してタスクを実行し続けることができます.
    以下は実現ステップです.
  • 1.あなたのプログラムのManifestファイルに起動起動権限RECEIVE_を設定します.BOOT_COMPLETEDは、システム起動が完了したらACTIONを受け入れることができます.BOOT_COMPLETEDの放送は、ユーザが既にあなたのプログラムを起動している場合に限られます.
  • <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  • .ラジオ受信機を実現する:
  • public class SampleBootReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
                // Set the alarm here.
            }
        }
    }
  • .あなたの放送受信機にIntentフィルタを静的に追加する:
  • <receiver android:name=".SampleBootReceiver"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>
    ここで注意したいのは、このブロードキャスト受信機のAndroid:enabled=「false」属性はfalseであり、プログラムが明確に使用可能でない限り、それを起動しないという意味で、不必要なシステム起動ブロードキャストが呼び出されるのを阻止し、次のステップでブロードキャスト受信機を起動することができます.
    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
    このようにして放送が開始されると、いつも利用可能な状態を維持しています.あるいは、ユーザが設備を再起動しても、つまり、あなたのプログラムは自分で消してもいいです.そうしないと、いつも利用可能な状態を維持しています.以下のように消してもいいです.
    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    以上の文章は翻訳済みです.全体的に外国人が書いた文書は本当に責任があります.いくつかの細部について何度も強調します.