(4)パートIIの消費電力を最適化するために、パフォーマンスの最適化手順

アリP7モバイルインターネットの建築家、無料の学習のための高度なビデオ(毎日更新)、クリックしてください:https://space.bilibili.com/474380680

この記事では、以下の2つの側面の消費電力を最適化するために、最後にご紹介します。

  • 【】ジョブスケジューラ
  • 【ワークマネージャ】

まず、詳細なjobschedulerのAPIの使用方法

1.1はじめに

jobschedulerのAPIは、Android5.0、いくつかの使用シナリオの最初にある:時間または特定の条件が満たされたときにタスクを実行する必要があります(電話機がアイドル状態であるかどうかを、電源、ネットワークステータスの変更を接続)で、いくつかの後の時点で。

1.2 APIの機能

開発者は、主に3つのクラスJobServiceとjobschedulerの、JOBINFOを通じてJobSchedule APIを使用します

そして、あなたは一つのことを知っている必要があり、タスクを開くコマンドたら、彼らは条件を満たしていることは、タスクを実行するように設定されているような、タスクを開始していきます、死の適用がない限り、タスクを実行します

jobschedulerのがスケジュールされたタスクを達成するため、次の相関関数

/*返回值:1表示执行成功,0代表失败*/
public abstract int schedule(JobInfo job);
/**通过指定的jobId取消Job任务*/
public abstract void cancel(int jobId);
 
/**取消所有的Job任务*/
public abstract void cancelAll();
 
/**获取所有的未执行的Job任务*/
public abstract @NonNull List<JobInfo> getAllPendingJobs();
 
/**获取指定的Job未执行的任务*/
public abstract @Nullable JobInfo getPendingJob(int jobId);

JobServiceは、抽象クラスを継承されるクラスのサービス、我々はタスクの開始と停止の実行を完了するために、二つの機能を実現する必要があります

/*开启任务*/
public abstract boolean onStartJob(JobParameters params);
/*停止任务方法*/
public abstract boolean onStopJob(JobParameters params);

タスクのルールにJOBINFOはjobschedulerののBuilderパターンでルールを設定するために始めました

// jobId每个Job任务的id
int jobId = 1;
// 指定你需要执行的JobService
ComponentName name = new ComponentName(getPackageName(), MyJobService.class.getName()));
JobInfo.Builder builder = new JobInfo.Bulider(jobId, name);
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE); //设置需要的网络条件,默认NETWORK_TYPE_NONE
builder.setPeriodic(3000);//设置间隔时间,不断的触发任务的启动
builder.setMinimumLatency(3000);// 设置任务运行最少延迟时间,与setPeriodic相似,只是间隔时间不确定,不能与setPeriodic一起使用,
builder.setOverrideDeadline(50000);// 设置deadline,若到期还没有达到规定的条件则会开始执行  
builder.setRequiresCharging(true);// 设置是否充电的条件,默认false
builder.setRequiresDeviceIdle(false);// 设置手机是否空闲的条件,默认false
builder.setPersisted(true);//设备重启之后你的任务是否还要继续执行
JobInfo info = builder.build();

1.3の様々なを使用してください

(1)基礎となるコード
まず、私はほとんど変化が来るのコードのこの部分を通ってテストされたコードの背後にあるコードを使用して基本的なJobShedulerのAPIを掲示し、我々はブログに目を向けることができ、自分のコードの効果を試してみてください

MyJobServiceは、シーンの多くを使用し、ハンドラがついに実現し、それはあなたがすべての後に、時間のかかる作業を真似したいので、これはバックグラウンドサービスである理由で、トーストを示すことであった時間のかかる作業です。

あなたがいない時間のかかる作業をシミュレートする場合は、falseに続いonStartJob戻り値をハンドラを削除し、。終了し、彼は次のタスクを実行する準備ができてカウントを開始しますあなたのタスクに代わって、リターンはfalseをonStartJobで実行されているので、それがtrueを返した場合、まだ実行されているタスクに代わって、私たちはJobServiceを伝えるために、自分のjobFinished(パラメータ、真)関数を呼び出す必要がありますタスクの実行を完了

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)//API需要在21及以上
public class MyJobService extends JobService {
 
    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            Toast.makeText(MyJobService.this, "MyJobService", Toast.LENGTH_SHORT).show();
            JobParameters param = (JobParameters) msg.obj;
            jobFinished(param, true);
 
            return true;
        }
    });
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }
 
    @Override
    public boolean onStartJob(JobParameters params) {
        Message m = Message.obtain();
        m.obj = params;
        handler.sendMessageDelayed(m, 2000);
        return true;
    }
 
    @Override
    public boolean onStopJob(JobParameters params) {
        handler.removeCallbacksAndMessages(null);
        return false;
    }
}

サービスもAndroidManifestに登録する必要がありますので、あなたは特別な登録権限Shihaiを設定する必要があります

        <service
            android:name=".MyJobService"
            android:permission="android.permission.BIND_JOB_SERVICE"></service>

活動は、オープンスケジュールのタスクをトリガするためにクリックするボタンを設定することです

public class MainActivity extends AppCompatActivity {
 
    Button btn;
    private JobScheduler mJobScheduler;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        btn = (Button) findViewById(R.id.btn);
        mJobScheduler = (JobScheduler) getSystemService( Context.JOB_SCHEDULER_SERVICE );
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    JobInfo.Builder builder = new JobInfo.Builder( 1,
                            new ComponentName( getPackageName(), MyJobService.class.getName() ) );
                    builder.setMinimumLatency(2000);
                    if( mJobScheduler.schedule( builder.build() ) <= 0 ) {
                        //If something goes wrong
                    }
                }
            }
        });
    }
}

(2)の種々の使用
setMinimumLatencyの
少なくともsetMinimumLatencyによって遅延タスクの実行を設定するベースコード(2000)、前記遅延が、私のテストでは、遅延時間が2秒で開始することができ、時には比較的ランダムであり、ことを見出しましたタスクが、ほとんどのミッションを開始するには7-8秒です。タスクの実行が完了した後、彼らは、遅延時間を初期化開始時間、準備中のタスクを実行することになります。

setPeriodic
コードに基づいて、私は(2000)setPeriodicにsetMinimumLatency(2000)のコードを入れて

ここでは、彼らがタスクを起動関連の特性の設定期間を持っているので、私が思うに、文句を言うでしょう、setMinimumLatencyとsetPeriodicが一緒に設定することはできません注意する必要があります。

私は、コードを実行されますが、2秒のサイクルタイムでアプリケーションタスクをトリガし、その後、私は、コンソールログに次のを見ていなかった場合には

 W/JobInfo: Specified interval for 1 is +2s0ms. Clamped to +15m0s0ms
 W/JobInfo: Specified flex for 1 is +2s0ms. Clamped to +5m0s0ms

この手段は、あなたが少なくとも15分の間隔でなければならないことを、この規定は、あなたがまだ完全に使用setMinimumLatencyに必要な、より頻繁に呼び出しタスクを必要とするのであれば、そこを開始Android7.0です。
setRequireNetworkType
I setRequireNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)がsetMinimumLatency(2000)に交換した場合、プログラムはエラーを実行します

java.lang.IllegalArgumentException: You're trying to build a job with no constraints, this is not allowed.

私はsetRequireNetworkTypeは、まあ、私は再び実行し、setMinimumLatency(2000000)を追加setMinimumLatency主要な制約のようにハングアップに似メイン制約、ではないと結論付け、遅延の理由は、最小限の時間設定が長いためなどとして、とても大きいです条件のセットの1つは、タスクを開始します。
ネットワークのいくつかの種類があるので、その後、我々の接続WIFI、それはタスク、通知バーの広告市場ネットワークの多くの種類をトリガーするプログラムを実行することは、このタイプのトリガーを使用することで、所定の、私がしようとしない、あなたは試して所有することができますJOBINFOテスト

    public static final int NETWORK_TYPE_ANY = 1;
    public static final int NETWORK_TYPE_METERED = 4;
    public static final int NETWORK_TYPE_NONE = 0;
    public static final int NETWORK_TYPE_NOT_ROAMING = 3;
    public static final int NETWORK_TYPE_UNMETERED = 2;

setRequiresChargin
setRequiresCharginない主な制約、setRequiresChargin(真)またはsetRequireNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)、プログラムを実行します。
setRequiresChargin(真)デフォルトはfalseですので、falseに耳を傾けていない場合は、モニターの充電を指し、

setOverrideDeadline
JOBINFOは、以下のように設定がある場合

                    JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(getPackageName(), MyJobService.class.getName()))
                            .setPeriodic(2000)
                            .setOverrideDeadline(10000)
                            .build();

文句を言うでしょうプログラムを実行します。

java.lang.IllegalArgumentException: Can't call setOverrideDeadline() on a periodic job.
如果我去掉setPeriodic(2000)这行代码,在运行程序,我发现点击一次按钮就会立即启动任务,也就是弹出Toast,但是后面会继续启动任务,只是间隔时间比10秒时间要长得多

今、私JOBINFOコードは次のように書かれています

                    JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(getPackageName(), MyJobService.class.getName()))
                            .setOverrideDeadline(5000)
                            .setMinimumLatency(3000)
                            .build();

期待に沿った通常の操作手順、
setPersisted
主要制約はないsetPersisted、JOBINFOは次のようにコードであります

                    JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(getPackageName(), MyJobService.class.getName()))
                            //.setMinimumLatency(10000)
                            .setPersisted(true)
                            .build();

ボタンを押し、その後は無駄に、携帯電話を再起動してください。

setRequiresDeviceIdle
次のようにコードがあります

                    JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(getPackageName(), MyJobService.class.getName()))
                            .setRequiresDeviceIdle(true)
                            .build();

量、携帯電話のアイドルプログラムは明らかに他の電話ある撤退、半日待つことができません、

タスクスケジューリング(3)JobSheduler
私たちは、次のコードで基本コードを見る前に、タスクが成功を作成するかどうかを判断することであるが、これはタスクのスケジューリングの対象ではありません

                    if( mJobScheduler.schedule( builder.build() ) <= 0 ) {
                        //If something goes wrong
                    }

まず、機能を解除トリガするために、機能、リガのコード活動ボタンを、キャンセル効果を見て

public class MainActivity extends AppCompatActivity {
 
 
    Button btn, btn_pause;
    private JobScheduler mJobScheduler;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        btn = (Button) findViewById(R.id.btn);
        btn_pause = (Button) findViewById(R.id.btn_pause) ;
        mJobScheduler = (JobScheduler) getSystemService( Context.JOB_SCHEDULER_SERVICE );
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    JobInfo.Builder builder = new JobInfo.Builder( 1,
                            new ComponentName( getPackageName(), MyJobService.class.getName() ) );
                    builder.setMinimumLatency(20000);
                    if( mJobScheduler.schedule( builder.build() ) <= 0 ) {
                        //If something goes wrong
                    }
                }
            }
        });
        btn_pause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    mJobScheduler.cancel(1);
                }
            }
        });
 
    }
 
 
}

プログラムを実行し、最初のボタンをクリックし、2番目のボタンをクリックし、タスクが開始されていないことを確認して、キャッシュcancelAll効果としての機能を解除してください。
実際には、そこなgetPendingJobなどのタスクを実行するために見ることができる機能の関数ではないが、これはAndroid7.0以上である電話システムが必要です。

二、ワークマネージャの使用と利点

commonj.work.WorkManager

2.1説明:

ワークマネージャインタフェース(commonj.work)APIは、アプリケーションが同時に容器内の作業項目の複数の実行を可能にするために設けられています。

実際には、このAPIはjava.lang.Threadのコンテナ管理APIに代わるものです。しかしjava.lang.ThreadのAPIは、Java EE環境で運ばマネージアプリケーションでは使用できません。このような環境では、ワークマネージャのより良い、それはコンテナ全体を表示することができますし、実行のすべてのスレッドを制御しているため。
注:
ワークマネージャAPIは、フェイルオーバーを提供し、永続性のメカニズムはありません。管理サーバー環境に障害が発生したり、近くにいる場合は、現在のすべての作業が失われます。

2.2利点:

  1. これは、コンテナのスレッドによって管理することができます
  2. 私たちは、複数のスレッドを調整するために一緒に作業することができます

インターフェース:
ワークマネージャ-このインタフェースは、実行すべき作業をスケジュールするためのスケジューリング方法のセットを提供します。
システム管理者は、サーバーレベルでワークマネージャを定義することができます。取得するためにJNDIルックアップを実行することにより、ワークマネージャインスタンス。管理された環境では、複数のワークマネージャのインスタンスをサポートすることができます。"WebLogic JNDIのプログラミング"を参照してください。あなたは、展開のWorkManagerのresource-refの間に設定されます。
作業-このインタフェースを介して、あなたは非同期にアプリケーション・コードを実行することができます。クラス以下を実装するこのインタフェースを作成することで、間隔または特定の時刻定義されたコードブロックを実行して、スケジュールを作成することができます。言い換えれば、これはでワークマネージャのAPIで処理され、「仕事。」
作業項目は- Workインスタンスをワークマネージャに提出した後、ワークマネージャは、作業項目を返します。これは、全体の作業項目Workインスタンスの状態を決定するために使用されます。
WorkListenerの- WorkListenerのインタフェースは、作業インスタンスで定義され、そのスケジュールされた作業のワークマネージャとの間の通信を確立する、コールバックインタフェースです。

作業項目の項目= WorkManager.schedule(作業仕事、WorkListenerのWL)。

WorkListenerの作業項目の現在の状態を決定するために用いることができます。
注:
常に、最初は仕事のスケジュールすることで、同じJVMスレッドワークマネージャで実行WorkListenerのインスタンス。

web.xmlの:
の<resource-ref>を
の<res-ref-name> WM / ThreadsWorkManager </ RES-REF-名>
の<res-type>はcommonj.work.WorkManager </ RES型>
の<res-AUTH>コンテナ< / RES-AUTH>
の<res共有スコープ>共有可能</ RES共有スコープ>
</リソース-REF>

** Javaコード:**
ワークマネージャリスナーまたはサーブレットに次のコードを使用して取得することができます。
WM =ワークマネージャ(ワークマネージャ)ic.lookup( "で、java:comp / env / WM / ThreadsWorkManager");
wm.schedule(新新OpenWOWork());

public class OpenWOWork implements Work{ 
private boolean isRun = true; 
public void run() { 
     while(isRun ){ 
     //add code 
     } 
} 

public void release() { 
    isRun = false; // 
} 

  public boolean isDaemon() { 
     return true; 
  } 

} 

ワークマネージャは、二つの比類のない利点があります:

  1. タスクが別のタスクを開始する前に完了している複数の、例えば、リスナーとの間のコラボレーションアップ作業。

  2. アプリケーション・サーバーが停止している場合は管理するサーバーで統一スレッド、それが仕事のすべてをシャットダウンします、もちろん、あなたもシャットダウンしないように選択することができます。しかし、それはこの機能は、ユーザーができなくなります保証を使用することができます提供します複数の展開は、アプリケーションが実行するために複数のスレッドを生成する原因となります。
    参考:https://www.iteye.com/blog/dana-wang-2160023
    https://blog.csdn.net/z979451341/article/details/80608607

アリP7モバイルインターネットの建築家、無料の学習のための高度なビデオ(毎日更新)、クリックしてください:https://space.bilibili.com/474380680

おすすめ

転載: www.cnblogs.com/Android-Alvin/p/11958798.html