Slide 1

Slide 1 text

ػցֶशͱ+PC4DIFEVMFSΛ࢖ͬͨϓϩμΫτ։ൃ ٢ాສً LB[Z αʔϏε։ൃ෦

Slide 2

Slide 2 text

ؔΘͬͨϓϩμΫτ ʮྉཧ͖Ζ͘ʯ ྉཧࣸਅ͚ͩ͋ͭΊͯه࿥͢Δ

Slide 3

Slide 3 text

ྉཧ͖Ζ͘ͷ࢓૊Έ $PPLQBEΞϓϦ͸෼ִؒͰ৽نࣸਅΛ୳͢ ৽نࣸਅ͕ݟ͔ͭͬͨ৔߹͸ɺྉཧ൑ఆ͢Δ ྉཧͱ൑ఆ͞ΕͨࣸਅΛΞοϓϩʔυ͢Δ

Slide 4

Slide 4 text

ྉཧ͖Ζ͘ͷٕज़తͳಛ௃ ػցֶशΛར༻ͨ͠ྉཧը૾൑ఆ +PC4DIFEVMFSͷϓϩμΫγϣϯͰͷར༻

Slide 5

Slide 5 text

ػցֶशͱωΠςΟϒΞϓϦ

Slide 6

Slide 6 text

ֶशϞσϧΛͲ͜ʹஔ͔͘ ୺຤಺ʹֶशϞσϧΛ಺ଂ͠ɺΞϓϦ಺Ͱ൑ఆ͢Δ αʔόʔଆʹϞσϧΛஔ͍ͯɺ"1*Ͱ݁ՌΛड͚औΔ

Slide 7

Slide 7 text

୺຤಺ʹֶशϞσϧΛஔ͘৔߹ ྑ͍఺ - ߴ଎ - ઃܭ͕γϯϓϧ - ࢪࡦͷࣗ༝౓͕ߴ͍

Slide 8

Slide 8 text

୺຤಺ʹֶशϞσϧΛஔ͘৔߹ ྑ͘ͳ͍఺ - ֶशϞσϧΛখ͘͢͞Δ౒ྗ͕ඞཁ - Ϟσϧͷվળ͕ΞϓϦͷϦϦʔεαΠΫϧʹґଘ - NDKΛ࢖͏։ൃ͕ආ͚ΒΕͳ͍..?

Slide 9

Slide 9 text

αʔόʔଆʹֶशϞσϧΛஔ͘৔߹ ྑ͍఺ - ϞσϧͷαΠζ͕େ͖ͯ͘΋໰୊ͳ͍ - ॊೈʹϞσϧͷࠩ͠ସ͕͑Մೳ

Slide 10

Slide 10 text

αʔόʔଆʹֶशϞσϧΛஔ͘৔߹ ྑ͘ͳ͍఺ - ൑ఆϑϩʔ͕ෳࡶʹͳΓ͕ͪ - ௨৴ྔ͕ൺֱతଟ͘ͳΔ

Slide 11

Slide 11 text

ΞʔΩςΫνϟͷ࿩

Slide 12

Slide 12 text

εέʔϧ͠ͳ͍ ॳظͷΞʔΩςΫνϟ

Slide 13

Slide 13 text

T

Slide 14

Slide 14 text

ॳظͷΞʔΩςΫνϟͷ໰୊఺ ը૾Ξοϓϩʔυ΍൑ఆͷ*0଴ͪʹΑͬͯ
 "1*αʔόʔͷXPSLFS͕࢖͍੾ͬͯ͠·͏ େྔͷը૾͕DPPLQBEͷ"1*αʔόʔʹૹ৴͞Εɺ
 τϥϑΟοΫ͕૿Ճ͢Δ

Slide 15

Slide 15 text

ݱࡏͷΞʔΩςΫνϟ

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

৽ΞʔΩςΫνϟͰมߋͨ͠఺ ඇಉظ ϙʔϦϯά Ͱ൑ఆ݁ՌΛड͚औΔ ը૾ͷΞοϓϩʔυ͸͢΂ͯ4ʹ௚઀౤͛Δ

Slide 19

Slide 19 text

݁ՌΛඇಉظͰड͚औΔ࢓૊Έ ΞϓϦ͔Βը૾Λ௚઀4ʹΞοϓ͢Δ 4ʹը૾͕Ξοϓ͞ΕΔͱ424ʹΩϡʔ͞ΕΔ ֶशϞσϧ͕ࡌͬͨQZUIPOαʔόʔ͕ը૾Λड͚औΔ ྉཧը૾͔൑ఆͯ͠ɺ%#ʹ݁ՌΛॻ͖ࠐΉ ΞϓϦ͔Β"1*Λ௨ͯ݁͠ՌΛಡΈʹߦ͘

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

ػցֶशͱωΠςΟϒΞϓϦ ϞσϧΛ୺຤಺ʹ͍ΕΔͷ͔ɺ"1*ܦ༝Ͱར༻͢Δ͔ "1*ܦ༝ͷ৔߹ಉظతͳ΍ΓऔΓ͸ݫ͍͠ εέʔϧ͢ΔΞʔΩςΫνϟΛؤு࣮ͬͯ૷͢Δ

Slide 22

Slide 22 text

+PC4DIFEVMFSͷجຊͱUJQT

Slide 23

Slide 23 text

+PC4DIFEVMFS -PMMJQPQͰొ৔ͨ͠ൺֱత৽͍͠"1* 4FSWJDFΛ೚ҙͷλΠϛϯάͰɺىಈ͢Δ͜ͱ͕ग़དྷΔ
 δϣϒεέδϡʔϥʔ DPPLQBEΞϓϦ ྉཧ͖Ζ͘ Ͱ͸+PC4DIFEVMFSΛ࠾༻ͨ͠

Slide 24

Slide 24 text

+PC4DIFEVMFSαϯϓϧ 4FSWJDFଆ public class MyJobService extends JobService {
 
 @Override
 public boolean onStartJob(JobParameters job) { // ͜͜ʹॲཧΛهड़͢Δ
 return false;
 }
 
 @Override
 public boolean onStopJob(JobParameters job) {
 return false;
 }
 }

Slide 25

Slide 25 text

+PC4DIFEVMFSαϯϓϧ 4FSWJDFଆ public class MyJobService extends JobService {
 @Override
 public boolean onStartJob(JobParameters params) { // ͜͜͸ϝΠϯεϨου
 tooHeavyJob()
 .subscribeOn(Schedulers.io())
 .subscribe(result -> {
 // Կ͔ߋ৽ॲཧͳͲΛߦ͏
 jobFinished(params, false);
 // δϣϒ͕ࣦഊͨ͠৔߹͸trueΛ౉͢ͱ࠶εέδϡʔϧ
 });
 // ಉظॲཧͷ৔߹͸false/ඇಉظॲཧͷ৔߹͸trueΛฦ͢
 return true;
 }
 
 @Override
 public boolean onStopJob(JobParameters params) { // δϣϒ͕׬ྃ͢ΔલʹγεςϜ͕Ωϟϯηϧ͢Δͱݺ͹ΕΔ
 return false;
 }
 }

Slide 26

Slide 26 text

+PC4DIFEVMFSαϯϓϧ εέδϡʔϧॲཧ 
 public class MyJobService extends JobService {
 
 private static final int PERIODIC_JOB_ID = 1;
 
 public static void setPeriodicSchedule(Context context) {
 JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
 
 JobInfo jobInfo = new JobInfo.Builder(PERIODIC_JOB_ID,
 new ComponentName(context, MyJobService.class))
 .setPeriodic(TimeUnit.MINUTES.toMillis(30))
 .setPersisted(true)
 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
 .build();
 scheduler.schedule(jobInfo);
 }
 
 public static void cancelPeriodicSchedule(Context context) {
 JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
 scheduler.cancel(PERIODIC_JOB_ID);
 } }

Slide 27

Slide 27 text

+PC4DIFEVMFSͰεέδϡʔϧʹར༻Ͱ͖Δ৚݅ ࠷େకΊ੾Γ࣌ؒ TFU0WFSSJEF%FBEMJOF ࠷௿஗Ԇ࣌ؒ TFU.JOJNVN-BUFODZ όοΫΦϑϦτϥΠํ਑ TFU#BDLPGG$SJUFSJB ௨৴؀ڥͷ੍໿ TFU3FRVJSFE/FUXPSL5ZQF ॆి؀ڥͷ੍໿ TFU3FRVJSFT$IBSHJOH ΞΠυϧঢ়ଶͷ੍໿ TFU3FRVJSFT%FWJDF*EMF ܁Γฦ͠ͷεέδϡʔϦϯά TFU1FSJPEJD ࠶ىಈ࣌ͷӬଓԽ TFU1FSTJTUFE

Slide 28

Slide 28 text

+PC4DIFEVMFSʹύϥϝʔλΛ౉͢ +PC*OGP#VJMEFSTFU&YUSBT 1FSTJTUBCMF#VOEMFFYUSBT 
 PersistableBundle bundle = new PersistableBundle();
 JobInfo jobInfo = new JobInfo.Builder(JOB_TAG,
 new ComponentName(this, MyJobService.class))
 .setExtras(bundle)
 .build(); public class MyJobService extends JobService {
 @Override
 public boolean onStartJob(JobParameters params) {
 PersistableBundle bundle = params.getExtras();
 // PersistableBundle͸εέδϡʔϧ࣌ʹӬଓԽ͞ΕΔͷͰɺ
 // ͜͜Ͱॻ͖׵͑ͯ΋࣍ճͷjobʹ͸൓ө͞Εͳ͍
 return false;
 }
 } +PC1BSBNFUFSTHFU&YUSBT

Slide 29

Slide 29 text

εέδϡʔϧঢ়گΛίʔυͰ֬ೝ͢Δ +PC4DIFEVMFSHFU"MM1FEJOH+PCT εέδϡʔϧ͞Ε͍ͯΔKPC*OGPϦετ͕ड͚औΕΔ εέδϡʔϧͨ͠ࡍʹ౉ͨ͠*%Λൺֱ͢Δ 
 public static boolean isPending(Context context, int serviceId) {
 JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
 List pendingJobList = scheduler.getAllPendingJobs();
 for (JobInfo jobInfo : pendingJobList) {
 if (serviceId == jobInfo.getId()) {
 return true;
 }
 }
 return false;
 }

Slide 30

Slide 30 text

BECίϚϯυͰ+PC4DIFEVMFSͷঢ়ଶΛ֬ೝ͢Δ δϣϒεέδϡʔϥʔʹొ࿥͞ΕͯΔλεΫҰཡ ࣮ߦ଴ͪͷλεΫҰཡ ࣮ߦ͞ΕͨλεΫͷώετϦʔҰཡ 04όʔδϣϯʹΑͬͯද͕ࣔ΍΍ҧ͏ 
 adb shell dumpsys jobscheduler


Slide 31

Slide 31 text

+PC4DIFEVMFS ྑ͍఺ 04ඪ४ͳͷͰ৴པ౓͸ߴ͍ ࡉ͔͍εέδϡʔϧ৚͕݅ࢦఆͰ͖Δ ࠶ىಈͯ͠΋ӬଓԽ͞ΕΔ࢓૊Έ͕͋Δ ϚϧνϢʔβʔʹରԠ ϖϯσΟϯάதͷ+PCҰཡ͕औಘͰ͖Δ

Slide 32

Slide 32 text

+PC4DIFEVMFS ྑ͘ͳ͍఺ ཁٻ͞ΕΔ"QJϨϕϧ Ҏ্ ͕ߴ͍ ϓϩμΫγϣϯͰͷར༻࣮੷͕গͳ͍ σόοά͕ͱʹ͔͘େม

Slide 33

Slide 33 text

+PC4DIEVMFS։ൃͰؾΛ͚͍ͭͨϙΠϯτ

Slide 34

Slide 34 text

ΞϓϦͷߋ৽Ͱεέδϡʔϧ͕ফ͑Δ ݱ৅ ઃఆͨ͠εέδϡʔϧ͕ফ͍͑ͯΔ ࠶ݱ৚݅ ܥͷ୺຤ͰΞϓϦΛߋ৽͢ΔͱϦηοτ͞ΕΔ ରԠࡦ ύοέʔδͷߋ৽Λݕ஌ͯ͠࠶ઃఆ͢Δ

Slide 35

Slide 35 text

ύοέʔδߋ৽ΠϕϯτΛϋϯυϦϯά͢Δ 
 
 
 
 @Override
 public void onReceive(Context context, Intent intent) {
 super.onReceive(context, intent);
 String action = intent.getAction();
 if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(action)) {
 // εέδϡʔϧ͞Ε͍ͯΔ͔֬ೝ͢Δɻ
 }
 }

Slide 36

Slide 36 text

Ұ౓͖Γͷδϣϒ͕ճىಈ͢Δ ݱ৅ Ұ౓͖Γͷεέδϡʔϧͷ͸͕ͣෳ਺ճىಈ͢Δ ࠶ݱ৚݅ /ະຬͷશͯͷ୺຤ +PCͷ࣮ߦ࣌ؒΑΓ%FBEMJOF͕୹͍ͱෳ਺ճىಈ͢Δ ରԠࡦ %FBEMJOFΛ৳͹͢ɺνΣοΫػߏΛ༻ҙ͢Δ IUUQTUBDLPWFSGMPXDPNRVFTUJPOTKPCTDIFEVMFSQPTUJOHKPCTUXJDFOPUFYQFDUFE

Slide 37

Slide 37 text

ະຬʹ΋ରԠ͍ͨ͠

Slide 38

Slide 38 text

࢒Γ͸ɺ TQFBLFSEFDLDPNLB[ZESPJELBJHJ PS͜ͷ͋ͱͷ࠙਌ձͰ