최적화로 성능 최적화 절차 (4 개) 파트 II의 전력 소비

알리 P7 모바일 인터넷 건축가, 무료 학습을위한 고급 비디오 (매일 갱신)를 클릭하십시오 : https://space.bilibili.com/474380680

이 문서에서는 다음과 같은 두 가지 측면의 전력 소비를 최적화하기 위해 마지막을 소개합니다 :

  • 【】 작업 스케줄러
  • 【WorkManager】

첫째, 자세한 JobScheduler API의 사용

1.1 소개

JobScheduler API는 Android5.0 일부 사용 시나리오의 시작 부분에 : 시간 또는 특정 조건이 충족 될 때 작업을 수행하기 위해 필요 (전화가 유휴 상태인지, 전원, 네트워크 상태 변화를 연결)의 일부 나중에에서.

1.2 API 함수

개발자는 주로 세 가지 클래스 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의 빌더 패턴 규칙을 설정하기 시작

// 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 반환 값을 핸들러를 제거합니다. onStartJob 완료에 작업을 대신 반환 거짓이 실행되기 때문에, 그는 우리가 JobService에게 (PARAM, TRUE) 함수를 자신의 jobFinished 호출 할 필요가있다 여전히 실행중인 작업 대신에, true를 돌려주는 경우, 다음 작업을 수행 할 준비가 카운트가 시작됩니다 작업 실행을 완료

@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는 불평 함께 설정할 수 없습니다.

내가 다음 코드를 실행하지만, 이초주기 시간의 응용 프로그램 작업을 실행하지 않았고, 언제는 콘솔 로그에 다음을 보았다

 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
만약 내가 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 주요 제약 글쎄처럼 걸어와 유사한 주요 제약, 다시 실행, 지연의 이유 최소 시간 설정이 너무 커서됩니다 아니다 결론 작업을 시작합니다 설정 한 조건 중 하나.
그런 다음 프로그램을 실행 우리가 연결 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입니다, 그래서 거짓을 듣지 경우, 모니터 충전을 말한다

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
코드가있을 때와 같은 JobInfo는 다음이 아닌 기본 제약 조건을 setPersisted

                    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);
                }
            }
        });
 
    }
 
 
}

첫 번째 단추를 클릭하여 프로그램을 실행 한 다음 두 번째 버튼, 작업이 시작되지 않은 것을 확인을 클릭는 캐시 cancelAll 효과로 기능을 취소 할 수 있습니다.
사실,이 같은 getPendingJob 등의 작업을 수행 할 볼 수있는 기능의 함수가 아니다, 그러나 이것은 Android7.0 이상 전화 시스템이 필요합니다.

두, WorkManager 사용 및 장점

commonj.work.WorkManager

2.1 설명 :

작업 관리자 인터페이스 (commonj.work) API는 응용 프로그램이 동시에 용기에 작업 항목의 복수를 실행 할 수 있도록 제공됩니다.

사실,이 API는 java.lang.Thread의 컨테이너 관리 API에 대한 대안입니다. 그러나 java.lang.Thread의 API는 Java EE 환경에서 수행 관리되는 응용 프로그램을 사용할 수 없습니다. 이러한 환경에서, WorkManager의 더 나은, 그것은 용기 전체보기를 할 수 있습니다 및 실행의 모든 스레드를 제어하기 때문이다.
참고 :
작업 관리자 API는 장애 조치를 제공하고 지속성 메커니즘되지 않습니다. 관리 서버 환경 또는 근처에 실패 할 경우, 현재의 모든 작업은 손실됩니다.

2.2 장점 :

  1. 그것은 컨테이너 스레드에 의해 관리 할 수 ​​있습니다
  2. 우리는 여러 스레드를 조정하기 위해 함께 일할 수

인터페이스 :
WorkManager는 - 스케줄링 작업을 수행 할 수 있도록이 인터페이스는 스케줄링 방법의 집합을 제공합니다.
시스템 관리자는 서버 수준에서 WorkManager를 정의 할 수 있습니다. 얻기 위해 JNDI 룩업을 수행함으로써 WorkManager 인스턴스. 관리되는 환경은 여러 WorkManager 인스턴스를 지원할 수 있습니다. 자세한 내용은 "웹 로직 JNDI는 프로그래밍." 당신은 배포 WorkManager 자원-REF 중에 구성됩니다. .
작업 -이 인터페이스를 통해 비동기 애플리케이션 코드를 실행할 수 있습니다. 클래스를 작성하여 구현이 인터페이스는, 당신은 간격 또는 특정 시간에 정의 된 코드 블록을 실행하여 일정을 만들 수 있습니다. 즉,이에서 작업 관리자 API에서 처리 "일."
WorkItem에서이 - 작업 인스턴스가 WorkManager에 제출 한 후, WorkManager는 작업 항목을 반환합니다. 이는 전체 WorkItem에서 작업 인스턴스의 상태를 결정하는 데 사용됩니다.
WorkListener - WorkListener 인터페이스는 작업 인스턴스에 정의 된 예약 된 작업 WorkManager 사이의 통신을 설정하는 콜백 인터페이스입니다.

WorkItem에서 항목 = WorkManager.schedule (작업 일, WorkListener의 WL);

WorkListener는 작업 항목의 현재 상태를 확인하는 데 사용할 수 있습니다.
참고 :
항상 처음에 일의 일정으로 같은 JVM 스레드 WorkManager에서 수행 WorkListener 인스턴스입니다.

web.xml에 :
<리소스 REF>
<입술-REF 이름> WM / ThreadsWorkManager </ 입술-REF 이름>
<입술 형> commonj.work.WorkManager </ 입술 형>
<입술 - 인증> 컨테이너 < / 입술 - 인증>
<입술 공유 스코프> 공유 가능 </ 입술 공유 스코프>
</ 자원 REF>

** 자바 코드 : **
WorkManager 리스너 나 서블릿에서 다음 코드를 사용하여 얻을 수 있습니다.
WM = WorkManager합니다 (WorkManager) ic.lookup ( "자바 : 광고 /를 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