0

I need to implement some works after X seconds and I don't want make it related with UI thread. So I create Thread as below. Specifically, I wanna my doWork1() working every 10s. And imgUpload() do not disurb my thread

private int cntUpdate; //count time to update work1
private int cntUpload; //count time to upload to server
private int cntlosing; //count time losing gps
private void creatThread(){
    Thread myThread = new Thread(){
        @Override
        public void run(){
            try{
                while (!isInterrupted()){
                    Thread.sleep(1000);//1s
                    cntUpdate ++;
                    if(cntUpdate >= 10){ //10s
                        doWork1(); //AsyncTask
                        cntUpdate = 0;
                    }
                    
                    cntUpload ++;
                    if(cntUpload > 100){//100s
                        imgUpload(); //AsyncTask
                        cntUpload = 0;
                    }
                    if(isGpsLosing()){ //checking every sec
                        cntlosing ++;
                        if(cntlosing > 500){
                            doSomething();
                            cntlosing = 0;
                        }
                    }
                            
                }
            }catch (InterruptedException e) {
                Log.d(TAG, "Interruped : " + e);
            }
        }
    };
    myThread.start();
}

When start doWork1() worked every 10s. But when imgUpload() work then doWork1() stopped. But time count still exactly. After imgUpload() finished then doWork1() sending consecutive in 1-2s. Normal: doWork1() - 10s - doWork1() - 10s - dowork1()...10s... When imgUpload doWork1() - 10s - doWork1() - 10s - imgUpload() - time to waiting upload finish (example 30s) - after 30s - doWord1() - 1s - doWork1() -1s -doWork1() - 10s - doWork1() - 10s... come back to normal work

private void doWork1(){
    AsyncWork1 asyncWork1 = new AsyncWork1();
    asyncWork1.execute();
}

public class AsyncWork1 extends AsyncTask<Void, Void, Void>{
    @Override
        protected Void doInBackground(Void... voids) {
            databaseWork(); // get data from table, some calculates...
            return null;
        }
}

private void imgUpload(){
    UpLoadImg upload = new UpLoadImg();
    upload.execute();
}

public class UpLoadImg extends AsyncTask<Void, Void, Void>{
    @Override
        protected Void doInBackground(Void... voids) {
            sendImgtoServer(); // 
            return null;
        }
}

I try use timer for doWork1() but nothing change in my result

private void useTimerWork1(){
    new Timer().scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run(){
            doWork1
        }
    }, 0, 10*1000); //every 10s
}

I am googling and read some topics about thread in SO but all make me confused. I don't know where i missed. I am change from C embed to android. So it is make me stupid and unintelligible Edit me if my explain too complicated

Jamebes
  • 96
  • 8
  • Could you tell more about your expected result and how it differs from observed result? – MJG Dec 07 '22 at 10:08
  • @MJG I want to doWork1() working every 10s. But observed result is more or less than 10s. I see reason seem as imgUpload(). But I don't know how exactly it work. How to make it working async – Jamebes Dec 07 '22 at 10:31
  • How about using a ScheduledExecutorService instead? – MJG Dec 07 '22 at 10:38
  • @MJG Do ScheduledExecutorService make disturb other thread ? I am not see different ScheduledExecutorService vs Thread.sleep – Jamebes Dec 07 '22 at 10:56
  • To implement a timer using sleep is maybe not as accurate as needed. The Timer or the ScheduledExecutorService approach should work exactly as needed. No need to start any additional Thread, just replace creatThread code with the useTimerWork1 (it is designed for working async). – MJG Dec 07 '22 at 12:20
  • 1
    `doWork1()` executes periodically at every 10 sec. BUT when the `imgUpload()` has invoked, the `doWork1()` thread has to wait until completion of `imgUpload()` process. So the `doWork()` executes at every 10 seconds unless it invokes the `imgUpload()`. And if it is invoked then it has to be wait until completion. Do I understand your goal correctly? – Kozmotronik Dec 07 '22 at 12:24
  • Keep in mind that Google discourages the usage of [`AsyncTask`](https://developer.android.com/reference/android/os/AsyncTask) API. But no harm done if your project is for practice or educational purposes. – Kozmotronik Dec 07 '22 at 12:26

1 Answers1

1

As you do not seem interested in the background (image sending) result, you could just fire up the task in a new Thread and all the uploading will not block and run in parallel if needed, w/o adding delay.

If it works, perhaps you should consider to improve from here..

private void imgUpload(){
    new Thread(()-> sendImgtoServer()).start();
}
private void doWork1(){
    new Thread(()-> databaseWork()).start();
}

MJG
  • 355
  • 1
  • 9
  • Your answer worked smoothly. Can u explain me, what happen if sendImgtoServer() still not finish yet and a new once started. Can I have to set timeout or something like that to manage thread. – Jamebes Dec 13 '22 at 10:40
  • 1
    If a new one is started, in this example, it will just start another upload in parallel. To refine it, you could use `Future` or `ScheduledFuture` and obtain its state and returned value, and you can also cancel it. It could be returned from the method as well for further use. For instance if your upload is still running, perhaps you want to cancel the job before submitting the next one. – MJG Dec 13 '22 at 12:31