简体   繁体   中英

Context Error in Creating Dialog Box in Android Studio

when a product is sold, I want to make a Dialog box with a case, but while running the Dialog code in an activity without any problems, I cannot run it in this file. Context always shows as null or I get "android.content.Context.getTheme" error. How can I run the dialog box below? Thank you

My Source: https://github.com/android/play-billing-samples/tree/main/TrivialDriveJava

Regards

public class TrivialDriveRepository {
    final static public int GAS_TANK_MIN = 0;
    final static public int GAS_TANK_MAX = 4;
    final static public int GAS_TANK_INFINITE = 5;
    static final public String SKU_PREMIUM = "premium";
    static final public String SKU_GAS = "gas";
    static final public String SKU_INFINITE_GAS_MONTHLY = "infinite_gas_monthly";
    static final public String SKU_INFINITE_GAS_YEARLY = "infinite_gas_yearly";
    static final String TAG = "TrivialDrive:" + TrivialDriveRepository.class.getSimpleName();
    static final String[] INAPP_SKUS = new String[]{SKU_PREMIUM, SKU_GAS};
    static final String[] SUBSCRIPTION_SKUS = new String[]{SKU_INFINITE_GAS_MONTHLY,
            SKU_INFINITE_GAS_YEARLY};
    static final String[] AUTO_CONSUME_SKUS = new String[]{SKU_GAS};

    final BillingDataSource billingDataSource;
    final GameStateModel gameStateModel;
    final SingleMediatorLiveEvent<Integer> gameMessages;
    final SingleMediatorLiveEvent<Integer> allMessages = new SingleMediatorLiveEvent<>();
    final ExecutorService driveExecutor = Executors.newSingleThreadExecutor();

    public TrivialDriveRepository(BillingDataSource billingDataSource,
            GameStateModel gameStateModel) {
        this.billingDataSource = billingDataSource;
        this.gameStateModel = gameStateModel;

        gameMessages = new SingleMediatorLiveEvent<>();
        setupMessagesSingleMediatorLiveEvent();

        billingDataSource.observeConsumedPurchases().observeForever(skuList -> {
            for ( String sku: skuList ) {
                if (sku.equals(SKU_GAS)) {
                    gameStateModel.incrementGas(GAS_TANK_MAX);
                }
            }
        });
    }

  
    void setupMessagesSingleMediatorLiveEvent() {
        final LiveData<List<String>> billingMessages = billingDataSource.observeNewPurchases();
        allMessages.addSource(gameMessages, allMessages::setValue);
        allMessages.addSource(billingMessages,
                stringList -> {
            // TODO: Handle multi-line purchases better
            for (String s: stringList) {
                    switch (s) {
                        case SKU_GAS:
                            allMessages.setValue(R.string.message_more_gas_acquired);
                            break;
                        case SKU_PREMIUM:
                            allMessages.setValue(R.string.message_premium);
                            break;
                        case SKU_INFINITE_GAS_MONTHLY:
                          final Dialog dialog = new Dialog(MyApplication.getInstance());
                                    dialog.setContentView(R.layout.activity_info);
                                    dialog.setCancelable(false);
                                    TextView text = (TextView) dialog.findViewById(R.id.text);
                                    text.setText(R.string.premium_activity_page_premium_membership_title);
                                    TextView yorum = (TextView) dialog.findViewById(R.id.yorumsatiri);
                                    yorum.setText(R.string.premium_activity_page_show_dialog_congrats_message_text);
                                    ImageView image = (ImageView) dialog.findViewById(R.id.img);
                                    Button yes = (Button) dialog.findViewById(R.id.yes);
                                    yes.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {


                                        }

                                    });
                                    dialog.show();
                                    break;
                                }

                    }
                });
                        case SKU_INFINITE_GAS_YEARLY:
                            // this makes sure that upgraded and downgraded subscriptions are
                            // reflected correctly in the app UI
                            billingDataSource.refreshPurchasesAsync();
                            allMessages.setValue(R.string.message_subscribed);
                            break;
                    }
                }
        });
    }

    public void drive() {
         final LiveData<Integer> gasTankLevelLiveData = gasTankLevel();
        gasTankLevelLiveData.observeForever(
                new Observer<Integer>() {
            @Override
            public void onChanged(Integer gasLevel) {
                if ( null == gasLevel ) return;
                switch (gasLevel) {
                    case TrivialDriveRepository.GAS_TANK_INFINITE:
                        // We never use gas in the tank if we have a subscription
                        sendMessage(R.string.message_infinite_drive);
                        break;
                    case TrivialDriveRepository.GAS_TANK_MIN:
                        sendMessage(R.string.message_out_of_gas);
                        break;
                    case TrivialDriveRepository.GAS_TANK_MIN + 1:
                        gameStateModel.decrementGas(GAS_TANK_MIN);
                        sendMessage(R.string.message_out_of_gas);
                        break;
                    default:
                        gameStateModel.decrementGas(GAS_TANK_MIN);
                        sendMessage(R.string.message_you_drove);
                        break;
                }
                gasTankLevelLiveData.removeObserver(this);
            }
        });
    }

    /**
     * Automatic support for upgrading/downgrading subscription.
     *
     * @param activity Needed by billing library to start the Google Play billing activity
     * @param sku the product ID to purchase
     */
    public void buySku(Activity activity, String sku) {
        String oldSku = null;
        switch (sku) {
            case SKU_INFINITE_GAS_MONTHLY:
                oldSku = SKU_INFINITE_GAS_YEARLY;
                break;
            case SKU_INFINITE_GAS_YEARLY:
                oldSku = SKU_INFINITE_GAS_MONTHLY;
                break;
        }
        if ( null != oldSku ) {
            billingDataSource.launchBillingFlow(activity, sku, oldSku);
        } else {
            billingDataSource.launchBillingFlow(activity, sku);
        }
    }



}

use final Dialog dialog = new Dialog(TrivialDriveRepository.this); instead of final Dialog dialog = new Dialog(MyApplication.getInstance());

Answer : You need to pass activity context to this class through a constructor from your desired activity and use that to initialize the dialogBox.

 public class TrivialDriveRepository{

 // variable to hold context
   private Context context;

  //save the context received via constructor in a local variable
public TrivialDriveRepository(Context context){
this.context=context;
 }

 void setupMessagesSingleMediatorLiveEvent() {
    final Dialog dialog = new Dialog(context); <-- use context here
  }
 
}

Best practice tip: its recommended not to open a dialog box in a non activity , this will cause memory leaks because you need a activity context,instead you should build them in your activity or fragment.

提供上下文作为getApplicationContext()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM