不兼容的ClassChangeError Android Studio
更新构建工具和SDK后,我的应用程序在我的支付片段中崩溃,只要我想添加一张新卡 我以前在使用Stripe时遇到过这个问题,因为我使用的是'com.Stripe:Stripe android:+' 然后我切换到稳定的版本1.0.1,它运行良好 一旦我更新到BuildTools 25.0.1和Stripe 2.0.2,它就会崩溃,出现不兼容的ClassChange错误,如果它碰巧切换回BuildTools 23和Stripe 1.0.1,我也会遇到同样的问题 请查看LogCat的屏幕截图 CardEditFragment.java不兼容的ClassChangeError Android Studio,android,android-studio,android-fragments,stripe-payments,Android,Android Studio,Android Fragments,Stripe Payments,更新构建工具和SDK后,我的应用程序在我的支付片段中崩溃,只要我想添加一张新卡 我以前在使用Stripe时遇到过这个问题,因为我使用的是'com.Stripe:Stripe android:+' 然后我切换到稳定的版本1.0.1,它运行良好 一旦我更新到BuildTools 25.0.1和Stripe 2.0.2,它就会崩溃,出现不兼容的ClassChange错误,如果它碰巧切换回BuildTools 23和Stripe 1.0.1,我也会遇到同样的问题 请查看LogCat的屏幕截图 Card
package com.cooltechworks.creditcarddesign;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.text.InputFilter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.cooltechworks.creditcarddesign.pager.AddCardTkn;
import com.cooltechworks.creditcarddesign.pager.CardCVVFragment;
import com.cooltechworks.creditcarddesign.pager.CardFragmentAdapter;
import com.cooltechworks.creditcarddesign.pager.CardFragmentAdapter.ICardEntryCompleteListener;
import com.stripe.android.Stripe;
import com.stripe.android.TokenCallback;
import com.stripe.android.model.Card;
import com.stripe.android.model.Token;
import static com.cooltechworks.creditcarddesign.CreditCardUtils.EXTRA_CARD_CVV;
import static com.cooltechworks.creditcarddesign.CreditCardUtils.EXTRA_CARD_EXPIRY;
import static com.cooltechworks.creditcarddesign.CreditCardUtils.EXTRA_CARD_HOLDER_NAME;
import static com.cooltechworks.creditcarddesign.CreditCardUtils.*;
public class CardEditFragment extends Fragment {
//public static final String STRIPE_PUBLISHABLE_KEY = "pk_live_xxxxxxxxxxx";
public static String STRIPE_PUBLISHABLE_KEY = "pk_test_xxxxxxxxxxx";
private TextView tvNext;
private TextView tvPrevious;
int mLastPageSelected = 0;
private CreditCardView mCreditCardView;
private ViewPager pager;
private String mCardNumber;
private String mCVV;
private String mCardHolderName;
private String mExpiry;
private String mPostcode;
private CardFragmentAdapter mCardAdapter;
private AddCardTkn tknHandlerDelegate;
private View editCardView;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final View editCardView = inflater.inflate(R.layout.activity_card_edit, container, false);
this.editCardView = editCardView;
tknHandlerDelegate = getActivity().getIntent().getParcelableExtra("interface");
tvNext = (TextView) editCardView.findViewById(R.id.next);
tvPrevious = (TextView) editCardView.findViewById(R.id.previous);
tvNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pager = (ViewPager) editCardView.findViewById(R.id.card_field_container_pager);
int max = pager.getAdapter().getCount();
if (pager.getCurrentItem() == max - 1) {
// if last card.
onDoneTapped();
} else {
showNext();
}
}
});
tvPrevious.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showPrevious();
}
});
setKeyboardVisibility(true);
mCreditCardView = (CreditCardView) editCardView.findViewById(R.id.credit_card_view);
if (savedInstanceState != null) {
checkParams(savedInstanceState);
} else {
checkParams(getActivity().getIntent().getExtras());
}
loadPager();
return editCardView;
}
private void checkParams(Bundle bundle) {
if (bundle == null) {
return;
}
mCardHolderName = bundle.getString(EXTRA_CARD_HOLDER_NAME);
mCVV = bundle.getString(EXTRA_CARD_CVV);
mExpiry = bundle.getString(EXTRA_CARD_EXPIRY);
mCardNumber = bundle.getString(EXTRA_CARD_NUMBER);
mCreditCardView.setCVV(mCVV);
mCreditCardView.setCardHolderName(mCardHolderName);
mCreditCardView.setCardExpiry(mExpiry);
mCreditCardView.setCardNumber(mCardNumber);
if (mCardAdapter != null) {
mCardAdapter.notifyDataSetChanged();
}
}
public void refreshNextButton() {
ViewPager pager = (ViewPager) editCardView.findViewById(R.id.card_field_container_pager);
int max = pager.getAdapter().getCount();
int text = R.string.next;
if (pager.getCurrentItem() == max - 1) {
text = R.string.done;
}
((TextView) editCardView.findViewById(R.id.next)).setText(text);
}
public void loadPager() {
ViewPager pager;
pager = (ViewPager) editCardView.findViewById(R.id.card_field_container_pager);
if (pager != null) {
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
CardCVVFragment cvvFrag = (CardCVVFragment) mCardAdapter.getItem(2);
int maxLength = 3;
if (mCardNumber.length() == 15) {
cvvFrag.isAmex = true;
maxLength = 4;
} else {
cvvFrag.isAmex = false;
}
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(maxLength);
cvvFrag.getCardCVVView().setFilters(fArray);
mCardAdapter.focus(position);
if (position == 2 && !cvvFrag.isAmex) {
mCreditCardView.showBack();
} else if ((position == 1 && mLastPageSelected == 2) || (position == 3 && !cvvFrag.isAmex)) {
mCreditCardView.showFront();
}
mLastPageSelected = position;
refreshNextButton();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
pager.setOffscreenPageLimit(5);
}
mCardAdapter = new CardFragmentAdapter(getActivity().getSupportFragmentManager(), getActivity().getIntent().getExtras());
mCardAdapter.setOnCardEntryCompleteListener(new ICardEntryCompleteListener() {
@Override
public void onCardEntryComplete(int currentIndex) {
showNext();
}
@Override
public void onCardEntryEdit(int currentIndex, String entryValue) {
switch (currentIndex) {
case 0:
mCardNumber = entryValue.replace(CreditCardUtils.SPACE_SEPERATOR, "");
mCreditCardView.setCardNumber(mCardNumber);
break;
case 1:
mExpiry = entryValue;
mCreditCardView.setCardExpiry(entryValue);
break;
case 2:
mCVV = entryValue;
mCreditCardView.setCVV(entryValue);
break;
case 3:
mCardHolderName = entryValue;
mCreditCardView.setCardHolderName(entryValue);
break;
case 4:
mPostcode = entryValue;
mCreditCardView.setCardPostcode(entryValue);
break;
}
}
});
pager.setAdapter(mCardAdapter);
}
public void onSaveInstanceState(Bundle outState) {
outState.putString(EXTRA_CARD_CVV, mCVV);
outState.putString(EXTRA_CARD_HOLDER_NAME, mCardHolderName);
outState.putString(EXTRA_CARD_EXPIRY, mExpiry);
outState.putString(EXTRA_CARD_NUMBER, mCardNumber);
outState.putString(EXTRA_REGISTERED_POSTCODE, mPostcode);
super.onSaveInstanceState(outState);
}
public void showPrevious() {
final ViewPager pager = (ViewPager) editCardView.findViewById(R.id.card_field_container_pager);
int currentIndex = pager.getCurrentItem();
if (currentIndex - 1 >= 0) {
pager.setCurrentItem(currentIndex - 1);
}
refreshNextButton();
}
public void showNext() {
final ViewPager pager = (ViewPager) editCardView.findViewById(R.id.card_field_container_pager);
CardFragmentAdapter adapter = (CardFragmentAdapter) pager.getAdapter();
int max = adapter.getCount();
int currentIndex = pager.getCurrentItem();
if (currentIndex + 1 < max) {
pager.setCurrentItem(currentIndex + 1);
} else {
// completed the card entry.
setKeyboardVisibility(false);
}
refreshNextButton();
}
private void onDoneTapped() {
if (mCardHolderName == null || mCardHolderName.equals(""))
{
handleError("Please enter the cardholders name");
return;
}
if (mPostcode == null || mPostcode.equals(""))
{
handleError("Please enter the cardholders postcode");
return;
}
if (mExpiry == null || mExpiry.length() != 5) {
handleError("The expiration date that you entered is invalid");
return;
}
String month = mExpiry.substring(0, 2);
String year = mExpiry.substring(3);
Card card = new Card(mCardNumber,
Integer.parseInt(month),
Integer.parseInt(year),
mCVV,
mCardHolderName,
"",
"",
"",
"",
mPostcode,
"",
"");
boolean validation = card.validateCard();
if (validation) {
startProgress();
new Stripe().createToken(
card,
STRIPE_PUBLISHABLE_KEY,
new TokenCallback() {
public void onSuccess(Token token) {
//Send to server
Log.d("Stripe Token", token.toString());
//For purpose of booking while Not registered yet
Bundle appointmentInfo = getActivity().getIntent().getExtras();
tknHandlerDelegate.addCard(token.getId(), getActivity(), appointmentInfo);
}
public void onError(Exception error) {
handleError(error.getLocalizedMessage());
finishProgress();
}
});
} else if (!card.validateNumber()) {
handleError("The card number that you entered is invalid");
} else if (!card.validateExpiryDate()) {
handleError("The expiration date that you entered is invalid");
} else if (!card.validateCVC()) {
handleError("The CVC code that you entered is invalid");
} else {
handleError("The card details that you entered are invalid");
}
}
private void startProgress() {
tknHandlerDelegate.showProgress(getActivity());
}
private void finishProgress() {
tknHandlerDelegate.hideProgress(getActivity());
}
private void handleError(String error) {
tknHandlerDelegate.handleError(error, getActivity());
}
// from the link above
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks whether a hardware keyboard is available
if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
LinearLayout parent = (LinearLayout) editCardView.findViewById(R.id.parent);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) parent.getLayoutParams();
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, 0);
parent.setLayoutParams(layoutParams);
}
}
private void setKeyboardVisibility(boolean visible) {
final EditText editText = (EditText) editCardView.findViewById(R.id.card_number_field);
if (!visible) {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
} else {
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
}
我还检查了StackOverflow上关于不兼容ClassChangeErrors的更多帖子,但没有帮助我解决这个问题
此应用程序的APKs的早期版本工作正常,所以我很清楚为什么会出现这种情况!非常感谢您的帮助。您介意在存储库中打开一个关于此的问题吗@Ywain感谢您回到我身边,我现在将打开一个问题。@Ywain问题已打开。@Ywain,请关闭Github中的线程,因为我已找到解决方案。此消息来自我使用过时的构建工具和条带版本的一个库。我已经更新了代码,一切都按照它的预期运行!谢谢你抽出时间!
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'com.google.gms.google-services'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.1"
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
defaultConfig {
applicationId "com.pushdr.application"
minSdkVersion 17
targetSdkVersion 17
ndk {
moduleName "ndkVidyoSample"
}
}
repositories {
jcenter()
maven { url "https://jitpack.io" }
mavenCentral()
maven { url 'https://github.com/FireZenk/maven-repo/raw/master/' }
}
allprojects {
repositories {
mavenCentral()
}
}
buildTypes {
release {
shrinkResources false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
armv7a
{
ndk
{
abiFilter "armeabi-v7a"
}
}
fat ///This build contain multi architecture binary
}
}
dependencies {
//facebook SDK
//Used for Signal R + Chat
compile files('libs/signalr-client-sdk-android.jar')
compile files('libs/signalr-client-sdk.jar')
compile files('libs/signalr-client-sdk.jar')
//Used for PIN entry
compile project(':pinentry')
//Menu Drawer
compile project(':materialTabs')
//Credit Card Payment Libraries
compile project(':creditcarddesign')
//Audio waves
compile project(':audiowaves')
compile('com.crashlytics.sdk.android:crashlytics:2.6.4@aar') {
transitive = true;
}
compile 'com.facebook.android:facebook-android-sdk:[4,5)'
compile 'com.google.firebase:firebase-core:9.2.0'
compile 'com.roger.gifloadinglibrary:gifloadinglibrary:1.0.0'
compile 'com.wdullaer:materialdatetimepicker:2.5.0'
compile 'com.synnapps:carouselview:0.0.9'
compile 'com.ragnarok.rxcamera:lib:0.0.4'
compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.17'
compile 'com.stripe:stripe-android:2.0.2'
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:design:25.1.0'
compile 'com.android.support:support-v4:25.1.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.github.2359media:EasyAndroidAnimations:0.8'
compile 'com.mikepenz:crossfader:1.3.7@aar'
compile 'com.mikepenz:crossfadedrawerlayout:0.3.4@aar'
compile 'com.mikepenz:itemanimators:0.2.4@aar'
compile 'com.mikepenz:google-material-typeface:2.2.0.1@aar'
compile 'com.mikepenz:fontawesome-typeface:4.4.0.1@aar'
compile 'com.mikepenz:octicons-typeface:3.0.0.1@aar'
compile 'com.github.amlcurran.showcaseview:library:5.4.3'
compile 'com.jzxiang.pickerview:TimePickerDialog:1.0.1'
compile 'com.google.code.gson:gson:2.4'
}