5

I am using the Sumup SDK to create a bridge to React Native. Most of the hard work is done but I am trying to call a specific function to wake up the card reader before a transaction is processed.

The original code I had was this:

@ReactMethod
    public void prepareCardTerminal() {
        SumUpAPI.prepareForCheckout();
    }
}

The RN bridge then calls this function like this:

static prepareCardTerminal() {
    NativeRNSumup.prepareCardTerminal();
}

How ever this gives me a React Native error of:

Must be called on main thread

I read that this could mean it needs to be run on the UI thread so I rewrote the function to be:

@ReactMethod
public void prepareCardTerminal() {
    new Thread(new Runnable() {
        public void run() {
    SumUpAPI.prepareForCheckout();
        }
    });
}

However this doesn't have the intended results (even though it doesn't show any errors).

Any tips would be much appreciated.

Edit: I found a solution to this issue. I used UiThreadUtil:

import com.facebook.react.bridge.UiThreadUtil;
...
    @ReactMethod
public void prepareCardTerminal() {
    UiThreadUtil.runOnUiThread(new Runnable() {
        @Override
        public void run() {
    SumUpAPI.prepareForCheckout();
        }
    });
}
James
  • 51
  • 1
  • 5

2 Answers2

6

You can do something like this:

@ReactMethod
public void prepareCardTerminal() {

    // Get a handler that can be used to post to the main thread
    Handler mainHandler = new Handler(context.getMainLooper());

    Runnable myRunnable = new Runnable() {
        @Override 
        public void run() {
            SumUpAPI.prepareForCheckout();
        }
    };

    mainHandler.post(myRunnable);

}


Or even simpler:

new Handler(Looper.getMainLooper()).post(new Runnable() {
       @Override
       public void run() {
           SumUpAPI.prepareForCheckout();
       }
});
Waqar UlHaq
  • 6,144
  • 2
  • 34
  • 42
3

The answer posted as an edit to the question is correct. The answer by @waquar-ulhaq is technically correct but using UiThreadUtil is way simpler and internally does use a Handler

import com.facebook.react.bridge.UiThreadUtil;
...
    @ReactMethod
public void prepareCardTerminal() {
    UiThreadUtil.runOnUiThread(new Runnable() {
        @Override
        public void run() {
    SumUpAPI.prepareForCheckout();
        }
    });
}
unify
  • 6,161
  • 4
  • 33
  • 34