Android-job: Cancel job not working especially asyc job

Created on 8 Dec 2016  路  16Comments  路  Source: evernote/android-job

Hello

i need a way to stop an async job, using your code:

public class AsyncJob extends Job {

@NonNull
@Override
protected Result onRunJob(Params params) {
    final CountDownLatch countDownLatch = new CountDownLatch(1);

    new Thread() {
        @Override
        public void run() {
            // do async operation here

            SystemClock.sleep(3_000L);
            countDownLatch.countDown();
        }
    }.start();

    try {
        countDownLatch.await();
    } catch (InterruptedException ignored) {
    }

    return Result.SUCCESS;
}

}

calling: JobManager.instance().cancelAll();
not stopping the current job for example

actually even if a job was scheduled but did not start to work, calling cancel, is not cancelling it's future work.

is there a better way to cancel it ?

Thanks

help wanted

Most helpful comment

Sorry, no serious coder here.

All 16 comments

@vRallev any idea ?

this is the jobrequest i'm using:

int jobId = new JobRequest.Builder(jobTag)
.setExecutionWindow(startMs, endMs)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
.setRequirementsEnforced(true)
.setUpdateCurrent(updateCurrent)
.build()
.schedule();

That's weird and I've tested it multiple times and it should work. If you cancel a not running job, then it shouldn't run anymore. If you cancel a job while it's running, then the you can call isCanceled() inside your job to check if it was canceled.

Please attach a log or a sample project. Otherwise it's hard for me to tell what's going on.

so this is my abstract class:

public abstract class AbstractAsyncJob extends Job {

protected String jobDescription;

protected Integer jobId;

@NonNull
@Override
protected Result onRunJob(Params params) {
    final CountDownLatch countDownLatch = new CountDownLatch(1);

    Utils.makeToastText(getContext(),jobDescription + ": Started");

    new Thread() {
        @Override
        public void run() {
            // do async operation here
            startJob();

            Utils.makeToastText(getContext(),jobDescription + ": Completed");

            SystemClock.sleep(10_000L);
            countDownLatch.countDown();
        }
    }.start();

    try {
        countDownLatch.await();
    } catch (InterruptedException ignored) {
        jobInterruptedException();
    }

    return Result.SUCCESS;
}

protected static ArrayList<Long> getStartAndEndForEvery24Hours(){
    //Calendar calendar = Calendar.getInstance();

    //
    long startMs = 1_000L;
    long endMs = startMs + TimeUnit.HOURS.toMillis(24);

    ArrayList<Long> values = new ArrayList<>();
    values.add(startMs);
    values.add(endMs);

    return values;
}

public static int scheduleEvery24Hours(String TAG, boolean updateCurrent) {

    ArrayList<Long> values = getStartAndEndForEvery24Hours();
    Long startMs = values.get(0);
    Long endMs = values.get(1);

    int jobId = createScheduledJob(
            TAG,
            updateCurrent,
            startMs,
            endMs
    );

    return jobId;
}

// .setRequiresDeviceIdle(true) // this not working for some reason, so i decided to manage the idle mode
// by code
protected static int createScheduledJob(String jobTag, boolean updateCurrent, Long startMs, Long endMs){
    int jobId = new JobRequest.Builder(jobTag)
            .setExecutionWindow(startMs, endMs)
            //.setBackoffCriteria(5_000L, JobRequest.BackoffPolicy.EXPONENTIAL)
            //.setRequiresDeviceIdle(true)
            .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
            .setRequirementsEnforced(true)
            //.setPersisted(true)
            .setUpdateCurrent(updateCurrent)
            .build()
            .schedule();

    return jobId;
}

// to override
protected void startJob() {

}

protected void jobInterruptedException(){

}


public interface JobResult {
    void onJobStart();

    void onJobComplete();
}

}

You misunderstood what was meant with async operation. onRunJob(params) is already called on a background thread. It's not necessary to create another thread.

what do you mean by that ? i can take off the thread use ? this is actually a code from the FAQ page
actually the job i'm processing is async operation related to firebase query

so it can not return success until it finishes right ?

what do you advice me to make it work better ?

this is the change i've made right now:

new Thread() {
@Override
public void run() {
// do async operation here
startJob(new JobResult() {
@Override
public void onJobStart() {

                }

                @Override
                public void onJobComplete() {
                    Utils.makeToastText(getContext(),jobDescription + ": Completed");
                    countDownLatch.countDown();
                }
            });
        }
    }.start();

but still not working

even if i'm not using anymore the Thread object this still not working ....

@NonNull
@Override
protected Result onRunJob(Params params) {
    doHeavyWork();
    return Result.SUCCESS;
}

Please attach logs or a sample project.

this is the code i'm using now:

public abstract class AbstractAsyncJob extends Job {

protected String jobDescription;

protected Integer jobId;

@NonNull
@Override
protected Result onRunJob(Params params) {

    Utils.makeToastText(getContext(), jobDescription + ": Started");

    startJob(new JobResult() {
        @Override
        public void onJobStart() {

        }

        @Override
        public void onJobComplete() {
            Utils.makeToastText(getContext(), jobDescription + ": Completed");
            //countDownLatch.countDown();
        }
    });

    return Result.SUCCESS;
}

protected static ArrayList<Long> getStartAndEndForEvery24Hours() {
    //Calendar calendar = Calendar.getInstance();

    //
    long startMs = 1_000L;
    long endMs = startMs + TimeUnit.HOURS.toMillis(24);

    ArrayList<Long> values = new ArrayList<>();
    values.add(startMs);
    values.add(endMs);

    return values;
}

public static int scheduleEvery24Hours(String TAG, boolean updateCurrent) {

    ArrayList<Long> values = getStartAndEndForEvery24Hours();
    Long startMs = values.get(0);
    Long endMs = values.get(1);

    int jobId = createScheduledJob(
            TAG,
            updateCurrent,
            startMs,
            endMs
    );

    return jobId;
}

// .setRequiresDeviceIdle(true) // this not working for some reason, so i decided to manage the idle mode
// by code
protected static int createScheduledJob(String jobTag, boolean updateCurrent, Long startMs, Long endMs) {
    int jobId = new JobRequest.Builder(jobTag)
            .setExecutionWindow(startMs, endMs)
            //.setBackoffCriteria(5_000L, JobRequest.BackoffPolicy.EXPONENTIAL)
            //.setRequiresDeviceIdle(true)
            .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
            .setRequirementsEnforced(true)
            //.setPersisted(true)
            .setUpdateCurrent(updateCurrent)
            .build()
            .schedule();

    return jobId;
}

// to override
protected void startJob(final JobResult result) {

}

protected void jobInterruptedException() {

}


public interface JobResult {
    void onJobStart();

    void onJobComplete();
}

}

but still not working

the test i'm doing is:

  1. run the app
  2. click home button, i'm detecting it inside my code => run BackgroundJobAllPersons.scheduleJob();
    BackgroundJobAllPersons inherit from my abstract class, as i sait the job i'm doing is accessing asynchronously firebase entity
  3. when i have a toast that said job started i'm going back to the app which my code detects it and i stop all current jobs using:

JobManager jobManager = JobManager.instance();
jobManager.cancelAll();

this is a simple flow i'm doing to test the cancel functionality

Then everything works as expected. It's not possible to destroy a thread and stop its work in Java. You need to check isCanceled(). Sorry, but that's not part of this library and you should ask such questions elsewhere like Stackoverflow.

i know, but i've been following your documentation, so it's not enough clear people.

again, while testing your library i see:

job start and job completed all the time even if i'm stopping jobs, this means that something not working properly

Prove it and attach logs.

@vRallev i'm telling you the issue i'm not here to wast my time and even yours, i need to make it work as soon as possible, if you do not want to do your work it's ok.

is there a serious coder that can help me out ?

@vRallev is there a test case where your library is starting jobs when the home button is clicked then when comming back it's stopping all the current jobs ? it's an important usecase make one and you will see that this is not working.

Prove it and attach logs. ; )

Sorry, no serious coder here.

you have just proved it about you : )

Was this page helpful?
0 / 5 - 0 ratings

Related issues

judemanutd picture judemanutd  路  4Comments

deviant-studio picture deviant-studio  路  5Comments

krokyze picture krokyze  路  3Comments

v4-adi picture v4-adi  路  3Comments

mohamadk picture mohamadk  路  6Comments