0

I am new to java and android. I have the following function running in a service in the main UI thread.

public void startSession() {
    Log.d(TAG, "startSession()");
    sessionStartRequestCompleted = false;
    int c =0;
    do {
        Log.d(TAG, "startSession() - Tyring again #" + c);
        writeCharacteristic(
                characteristicMap.get(ShsServiceConstants.SH_GATT_SVC_SESSION_TOGGLER_CHARACTERISTIC_UUID),
                ShsServiceConstants.SESSION_TOGGLER_CHAR_SESSION_START_OPCODE);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
           e.printStackTrace();
        }
        int timeout = 0;
        sessionStartStatus = false;
        checkSessionStatus();
        while (!sessionStartStatus && timeout < 10) {
            timeout++;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (timeout >= 10) {
            Log.d(TAG, "StatusCheckTask Timed Out waiting for result");
            //fireNextShsGattRequest();
        }
        c++;
    } while (!sessionStartRequestCompleted);
}

But calling this function is blocking the UI thread. How can I write this function so that it doesn't block the UI thread but does the checking for the flags.

The flags are being set inside onCharacteristicRead.

  • 1
    Use AsyncTask or make a new Thread() in the code – yash sachdeva Jun 23 '16 at 09:48
  • [Android Developer](https://developer.android.com/training/index.html) website dedicates a [great article](https://developer.android.com/guide/components/processes-and-threads.html#WorkerThreads) on how to do that. Sidenote: You should really document why you call "Thread.sleep". – Fildor Jun 23 '16 at 09:52
  • Whenever you have long-running code in the UI thread that may be noticeable to the user (the UI is non-responsive, “locked-up”), then the only answer is to (a) make the code faster (do less work), or (b) **move that workload to another thread**. There are various ways to move work to another thread, some of which are discussed in the answers below. – Basil Bourque Jun 23 '16 at 21:51

6 Answers6

0

Use handler thread to perform operation in service.

Ankit Gupta
  • 674
  • 1
  • 6
  • 17
0

Wrap the loop inside a

new AsyncTask<Void, Void, Void>(){
  protected Void doInBackground(){
    //your while loop
    return null;
  }

  protected void onPostExecute(){
    //here goes what you need to update when task end
  }
}
Luca Nicoletti
  • 2,265
  • 2
  • 18
  • 32
0

I would recommend checking out RxJava. On android you will end up using it anyway, it's one of the best asynchronous approaches on android.

Jakoss
  • 4,647
  • 2
  • 26
  • 40
0

Use Thread.yield() method regularly inside the loop. Since the loop has no blocking state, it is better to yield, so that other threads get the CPU time. However, modern Java compilers automatically yield regularly to avoid only one thread taking all the time.

Nagabhushan Baddi
  • 1,164
  • 10
  • 18
  • Good answer but to a different question. This Question here has code running in the main (UI) thread. Calling `yield` will not help here, will not make the UI responsive. The `yield` method should be called in a *separate* thread that may be in a tight loop and hogging too much of the CPU. – Basil Bourque Jun 23 '16 at 21:48
0

You can use IntentService instead, because it runs on a new background thread. Another solution- use RxJava Library for cuncurrency. In RxJava use Schedulers.computation() scheduler

Alex Shutov
  • 3,217
  • 2
  • 13
  • 11
0

The documentations says that the easiest way to do it is by using AsyncTask

There is a lot of information here: Handler vs AsyncTask vs Thread

https://developer.android.com/reference/android/os/AsyncTask.html

Community
  • 1
  • 1
gpolic
  • 16
  • 3