sumup / sumup-android-sdk

Sample App for the SumUp Android SDK
Other
100 stars 29 forks source link

Has your library a "race condition" bug? #130

Closed jayjupdhig closed 4 years ago

jayjupdhig commented 4 years ago

1.) When i use SumUpState.init(mActivity); in the main class, it works:

@Override
    protected void onCreate(Bundle savedInstanceState) {

        // Init SumUp engine {
        SumUpState.init(mActivity);
        // } Init SumUp engine

...
...
...

@Override
    public void update(final Observable o, final Object arg) {
        if(o == cmMyObservable) {

            final Boolean clDlgRet = ((Boolean)cmMyObservable.get()).booleanValue();

            if(clDlgRet == null)
            {
                return;
            }

            if(clDlgRet.booleanValue())
            {
                SumUpProxy.setMainActivity(this); // -> !!! HERE !!!
                final String clSumupLoginRetStr = SumUpProxy.login("[AFFILIATE_KEY_REMOVED]", SumUpProxy.REQUEST_CODE_LOGIN);
                Dialog.showAlertDialog("xxx", clSumupLoginRetStr, this);
            }
            else
            {
                ((EditText) findViewById(R.id.textfieldCarNumber)).setText(null);
            }
        }
    }
  1. When i use SumUpState.init(mActivity); in my SumUp library "proxy"-class (there is all static, because it don't think that is a real problem...(?)), it crashes, i will be asked for an application restart on my tablet and on the virtual device of Android Studio.

So, this is my proxy class and i initialize it in the static constructor:

package com.example.myapplication;

import com.sumup.merchant.api.SumUpAPI;
import com.sumup.merchant.api.SumUpLogin;
import com.sumup.merchant.api.SumUpState;

public abstract class SumUpProxy {

    public static final int REQUEST_CODE_LOGIN = 1;
    public static final int REQUEST_CODE_PAYMENT = 2;
    public static final int REQUEST_CODE_PAYMENT_SETTINGS = 3;

    private static MainActivity mMainActivity = null;

    private SumUpProxy()
    {
        super();
    }

    static
    {
        SumUpState.init(mMainActivity);
    }

    public static void setMainActivity(final MainActivity caMainActivity)
    {
        mMainActivity = caMainActivity;
    }

    public static String login(final String caAffiliateKey, final int caRequestCodeLogin)
    {
        try {
            final SumUpLogin clSumUpLogin = SumUpLogin.builder(caAffiliateKey).build();
            SumUpAPI.openLoginActivity(SumUpProxy.mMainActivity, clSumUpLogin, caRequestCodeLogin);
            return clSumUpLogin.getAccessToken();

        }
        catch(final Exception caException)
        {
            return caException.getMessage();
        }
    }

    public static MerchantDataBean showLoggedInMerchantData()
    {
        final MerchantDataBean clMerchantDataBean = MerchantDataBean.createInstance();

        String lResultCode = null;
        String lResultMessage = null;

        if(!SumUpAPI.isLoggedIn())
        {
            lResultCode = "Result code: " + SumUpAPI.Response.ResultCode.ERROR_NOT_LOGGED_IN;
            lResultMessage = "Message: Not logged in";

            clMerchantDataBean.setResultCode(lResultCode);
            clMerchantDataBean.setResultMessage(lResultMessage);
        }
        else
        {
            lResultCode = "Result code: " + SumUpAPI.Response.ResultCode.SUCCESSFUL;

            final String clCurrencyISOCode = SumUpAPI.getCurrentMerchant().getCurrency().getIsoCode();
            final String clMerchantCode = SumUpAPI.getCurrentMerchant().getMerchantCode();

            clMerchantDataBean.setResultCode(lResultCode);
            clMerchantDataBean.setCurrencyISOCode(clCurrencyISOCode);
            clMerchantDataBean.setMerchantCode(clMerchantCode);

            lResultMessage = String.format("Currency: %s, Merchant Code: %s", clMerchantDataBean.getCurrencyISOCode() , clMerchantDataBean.getMerchantCode());

            clMerchantDataBean.setResultMessage(lResultMessage);
        }

        return clMerchantDataBean;
    }
}

I think (at least) the static constructor will be called before the class will be "touched" in EVERY way: static AND / OR as an object...?

So the static constructor should be called BEFORE calling SumUpProxy.setMainActivity(this); in the update(...) -/ observer-function from the main class. (The line is commented with -> !!! HERE !!! on the source code fragment on top.

Thank you for your feedback.

Best regards, Jan

jayjupdhig commented 3 years ago

Problem solved - no race condition - so "mea culpa"... ;-)

Regards, Jan