java.lang.NoClassDefFoundError retrofit2.Utils

后端 未结 11 1384
梦毁少年i
梦毁少年i 2020-12-30 10:40

I\'m using Retrofit to handle the Serverside Data from Mobile. After Implementing retrofit, I am Getting the below Exception.

What am I doing wrong?

相关标签:
11条回答
  • 2020-12-30 11:12

    I was facing this error below lollipop devices.

    I was using multiDexEnabled true.

    After adding this code to the class extending Application class my issue solved.

    @Override
    protected void attachBaseContext(Context context) {
        super.attachBaseContext(context);
        MultiDex.install(this);
    }
    

    reference: https://stackoverflow.com/a/39968486/4777524

    0 讨论(0)
  • 2020-12-30 11:12

    I ran into similar issues like this, it's probably a dependency issue

    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    

    already includes okhttp as seen here https://github.com/square/retrofit/blob/d04f3a50e41ca01d22f370ac4f332f6ddf4ba9fe/pom.xml, therefore remove the okhttp from the dependency list then sync and try again.

    0 讨论(0)
  • 2020-12-30 11:14

    I encountered with this error. And after many search, found that I forget add Internet Permission to manifest.

    After adding this permission, my error, resolved.

    0 讨论(0)
  • 2020-12-30 11:18

    You should make Utils class like this:

    public class AppUtil{
    public static Retrofit getRetrofitInstance(){
            HttpLoggingInterceptor logging=new HttpLoggingInterceptor();
            if(isEnableLogging)
                logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            else
                logging.setLevel(HttpLoggingInterceptor.Level.NONE);
            Gson gson = new GsonBuilder()
                    .setExclusionStrategies(new ExclusionStrategy() {
                        @Override
                        public boolean shouldSkipField(FieldAttributes f) {
                            return f.getDeclaringClass().equals(RealmObject.class);
                        }
    
                        @Override
                        public boolean shouldSkipClass(Class<?> clazz) {
                            return false;
                        }
                    })
                    .create();
            OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
            httpClient.addInterceptor(logging);
    
            return new Retrofit.Builder()
                    .baseUrl(Constants.URL_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .client(httpClient.build())
                    .build();
    
        }
    
    
    
    }
    

    Create an interface like this for the http methods:

    public interface EndPointInterface{
     @FormUrlEncoded
        @POST(Constants.URL_LOGON)
        Call<Doctor> login(@Field(Constants.EMAIL) String email,
                           @Field(Constants.PASSWORD) String password);
    } 
    

    In your activity where you are calling the webservices,please proceed like this:

     @OnClick(R.id.btn_login)
        public void onLoginButtonClick() {
            String emailString = edtEmail.getText().toString().trim();
            String passwordString = edtPassword.getText().toString().trim();
    
            if (emailString.length() == 0) {
                emailWrapper.setError("Please enter E-Mail ID");
            } else if (!AppUtil.isEmailValid(emailString)) {
                emailWrapper.setError("Please enter valid E-Mail ID");
            } else if (passwordString.length() == 0) {
                passwordWrapper.setError("Please enter password");
            } else if (AppUtil.isNetworkConnectionAvailable(this, true)) {
                login(emailString,passwordString);
            }
        }
    
     private void login(String email, String pwd) {
            final MaterialDialog dialog = AppUtil.showIndeterminateProgressDialog(this,getString(R.string.please_wait));
            EndPointInterface apiService = AppUtil.getRetrofitInstance().create(EndPointInterface.class);
            Call<Doctor> call = apiService.login(email, pwd);
            call.enqueue(new Callback<Doctor>() {
                @Override
                public void onResponse(Call<Doctor> call, Response<Doctor> response) {
                    dialog.dismiss();
                    if (response.code() == 200) {
                        Doctor doctor = response.body();
                        if (doctor == null) {
                            AppUtil.showSimpleDialog(LoginActivity.this, getString(R.string.userid_pwd_mismatched),
                                    getString(R.string.login_credential_mismatch));
                        } else {
                            SharedPreferences.Editor editor = mAppPreferences.edit();
                            editor.putString(Constants.SETTINGS_OBJ_DOCTOR, new Gson().toJson(doctor));
                            editor.putBoolean(Constants.SETTINGS_IS_LOGGED_IN, true);
                            editor.commit();
    
                            startActivity(new Intent(LoginActivity.this, PatientSummaryInfoActivity.class));
                            finish();
                        }
                    } else {
                        dialog.dismiss();
                        AppUtil.showSimpleDialog(LoginActivity.this, getString(R.string.server_error),
                                getString(R.string.could_not_connect_to_server));
                    }
    
                }
    
                @Override
                public void onFailure(Call<Doctor> call, Throwable t) {
                    dialog.dismiss();
                    AppUtil.showSimpleDialog(LoginActivity.this,getString(R.string.server_error), t.getMessage());
                }
    
            });
        }
    
    0 讨论(0)
  • 2020-12-30 11:21

    This error will come because of MultiDexApplication .I have face this kind of issue with some other library not same library but some other library.It will error of the retrofit library because its initialization of app start up where dex(in which your retrofit library code is converted to dex) file is not to set(install).

    To resolve that you need to handle Multiple Dex file. with the help of application build.gradle & Application class

    below changes which is required in build.gradle file

    dexOptions {
            incremental true
            // here heap size give 4g i got this thing from https://groups.google.com/forum/#!topic/adt-dev/P_TLBTyFWVY
    
            javaMaxHeapSize "4g"
        }
    
    
    dependencies {
         compile 'com.android.support:multidex:1.0.1'
        //    your dependencies which you are using.
    
    }
    

    entire build.gradle

    android {
        signingConfigs {
            /*
            releasebuild {
                keyAlias 'hellotest'
                keyPassword 'hellotest'
                storeFile file('path to keystore')
                storePassword 'hellotest'
            }
            */
        }
        compileSdkVersion 'Google Inc.:Google APIs:22'
        buildToolsVersion '23.0.0'
        /* if you got error regarding duplicate file of  META-INF/LICENSE.txt from jar file
        packagingOptions {
            exclude 'META-INF/LICENSE.txt'
        }
        */
        dexOptions {
            jumboMode = true
            incremental true
            // here heap size give 4g i got this thing from https://groups.google.com/forum/#!topic/adt-dev/P_TLBTyFWVY
    
            javaMaxHeapSize "4g"
        }
        defaultConfig {
            multiDexEnabled true
            applicationId "com.myapp.packagenme"
            minSdkVersion 17
            targetSdkVersion 22
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                signingConfig signingConfigs.releasebuild
            }
            debug {
                signingConfig signingConfigs.releasebuild
            }
        }
    }
    
    dependencies {
         compile 'com.android.support:multidex:1.0.1'
        //    your dependencies which you are using.
    
    }
    

    If your app uses extends the Applicationclass, you can override the attachBaseContext() method and call MultiDex.install(this) to enable multidex. To install multipledex file context using Applicaiton class which should extends [MultiDexApplication][2]

    public class MyAppClass extends MultiDexApplication{
    @Override
        protected void attachBaseContext(Context newBase) {
            MultiDex.install(newBase);
            super.attachBaseContext(newBase);
        }
    }
    

    Suggestion

    Selectively compiling APIs into your executable

    Don't use entire google play service use only required library.From version 6.5, you can instead selectively compile Google Play service APIs into your app. For example, to include only the Google Fit and Android Wear APIs, replace the following line in your build.gradle file:

    compile 'com.google.android.gms:play-services:8.4.0'
    

    with these lines:

    compile 'com.google.android.gms:play-services-fitness:8.4.0'
    compile 'com.google.android.gms:play-services-wearable:8.4.0'
    

    With the reference of my answer https://stackoverflow.com/a/34948154/1140237

    0 讨论(0)
  • 2020-12-30 11:22

    I fix this problem by changing retrofit gradle version 2.7.0 to 2.5.0

    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    
    implementation 'com.squareup.retrofit2:converter-scalars:2.5.0' 
    
    0 讨论(0)
提交回复
热议问题