java.lang.NoClassDefFoundError retrofit2.Utils

时间:2016-05-05 08:21:34

标签: android retrofit retrofit2

我使用Retrofit处理来自Mobile的Serverside数据。实施改造后,我得到以下例外。

我做错了什么?

  

com.name.App_idea W / System.err:java.lang.NoClassDefFoundError:   retrofit2.Utils       at retrofit2.Retrofit $ Builder.baseUrl(Retrofit.java:434)       在com.name.App_idea.utils.Idea.onCreate(Idea.java:103)       在android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)       在android.app.ActivityThread.handleBindApplication(ActivityThread.java:4541)       在android.app.ActivityThread.access $ 1500(ActivityThread.java:151)       在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1381)       在android.os.Handler.dispatchMessage(Handler.java:110)       在android.os.Looper.loop(Looper.java:193)       在android.app.ActivityThread.main(ActivityThread.java:5292)       at java.lang.reflect.Method.invokeNative(Native Method)       在java.lang.reflect.Method.invoke(Method.java:515)       在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:824)       在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)       在dalvik.system.NativeStart.main(本地方法)

改造初始

mRetrofit = new Retrofit.Builder()
                    .baseUrl(AppConstance.APP_URL)
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .build();

Gradle文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.3'

    defaultConfig {
        applicationId "com.name.App_idea"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "9"
        multiDexEnabled true


    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-scalars:2.0.0'
    compile 'com.google.code.gson:gson:2.2.4'
    compile 'com.squareup.retrofit2:converter-gson:2.0.0'
    compile 'com.jakewharton:butterknife:7.0.1'
    compile 'com.android.support:design:23.3.0'
    compile 'com.android.support:cardview-v7:23.3.0'
    compile 'com.google.android.gms:play-services:8.4.0'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
    compile 'com.android.support:support-v4:23.3.0'
}

申请类

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.support.multidex.MultiDex;
import android.util.Log;

import java.io.File;
import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


public class Idea extends Application {
    public static Retrofit mRetrofit;
    public static IdeaService Iservice;


    public static LoginResponceModel loinResponce;
    public static SettingsModel settingModel;

    public static LocationModel location = new LocationModel();

    private static SQLiteDatabase dbase;
    private static String FILE_PATH;

    public static SQLiteDatabase getDataBase() {
        return dbase;
    }

    public static String getFilePath() {
        return FILE_PATH;
    }

    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, "App", null, 1);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(AppConstance.DbConstans.tblLogin);
            Log.i("DB", "Created");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            onCreate(db);
        }
    }

    public static void deleteAllTables() {
        getDataBase().execSQL("DELETE FROM login");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        try {
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(AppConstance.APP_URL)
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .build();
            Iservice = mRetrofit.create(IdeaService.class);
            MultiDex.install(this);
            DatabaseHelper dbHelper = new DatabaseHelper(this);
            dbase = dbHelper.getWritableDatabase();

            AppDataService appDataService = new AppDataService();
            loinResponce = appDataService.getLoginDetails();
            settingModel = appDataService.getSettings();

            FILE_PATH = getAppFilePath();
            startService(new Intent(Idea.this, LocationTracker.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String combineFilePath(String path1, String path2) {
        File file1 = new File(path1);
        File file2 = new File(file1, path2);
        return file2.getPath();
    }

    public String getAppFilePath() {

        String dsPath;
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED))
            dsPath = combineFilePath(Environment
                            .getExternalStorageDirectory().getAbsolutePath(),
                    "android/data/Idea/");
        else
            dsPath = this.getDir(
                    this.getPackageName(), 0).getAbsolutePath();

        new File(dsPath).mkdirs();
        return dsPath;
    }

    private OkHttpClient getOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };
            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            OkHttpClient okHttpClient = builder.build();
            return okHttpClient;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

12 个答案:

答案 0 :(得分:12)

这个错误将来自MultiDexApplication。我遇到了这种问题,其他一些库不是同一个库而是其他一些库。它会改造库的错误,因为它的初始化app启动了dex (其中您的改装库代码转换为dex)文件不是设置(安装)。

要解决此问题,您需要处理Multiple Dex文件。在申请build.gradle&的帮助下申请类

以下build.gradle文件中需要的更改

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.

}

整个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.

}

如果您的应用使用了扩展Applicationclass,则可以覆盖attachBaseContext()方法并调用MultiDex.install(this)以启用multidex。使用Applicaiton类的To install multipledex file上下文,它应该扩展[MultiDexApplication][2]

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

<强>建议

Selectively compiling APIs into your executable

请勿使用整个Google Play服务仅使用所需的库。从版本6.5开始,您可以选择性地将Google Play服务API编译到您的应用中。例如,要仅包含Google Fit和Android Wear API,请替换build.gradle文件中的以下行:

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

这些行:

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

参考我的回答 https://stackoverflow.com/a/34948154/1140237

答案 1 :(得分:4)

我在棒棒糖设备下面临这个错误。

我正在使用multiDexEnabled true。

将此代码添加到扩展Application类的类后,我的问题解决了。

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

参考: https://stackoverflow.com/a/39968486/4777524

答案 2 :(得分:2)

您是否添加了以下proguard规则?

add = function(x, y) x+y
sapply(1:5, add(y = 10))

文档:http://square.github.io/retrofit/

答案 3 :(得分:2)

这是Gradle bulid配置问题我也有同样的问题

在Gradle中使用

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

Enire Google Playservice Lib可以更改您的项目中使用的库

示例

com.google.android.gms:play-services-gcm:8.4.0 
com.google.android.gms:play-services-maps:8.4.0
com.google.android.gms:play-services-auth:8.4.0

参考此URl https://developers.google.com/android/guides/setup#add_google_play_services_to_your_project

答案 4 :(得分:1)

你应该像这样制作Utils类:

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();

    }



}

为http方法创建这样的界面:

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

在您调用网络服务的活动中,请按以下步骤操作:

 @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());
            }

        });
    }

答案 5 :(得分:1)

我通过将改造gradle版本2.7.0更改为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' 

答案 6 :(得分:0)

mRetrofit = new Retrofit.Builder()
                    .baseUrl(AppConstance.APP_URL)
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .build();

REWRITE TO

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
mRetrofit = new Retrofit.Builder()
                        .baseUrl(AppConstance.APP_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .client(httpClient)
                        .build();

答案 7 :(得分:0)

有了这么多的库马鞍,它必须超出臭名昭着的64k方法限制,你需要启用你的应用程序的multidex。这是你如何做到的。 https://developer.android.com/tools/building/multidex.html

答案 8 :(得分:0)

尝试使用相同的lib版本进行基本改造lib和转换器。

compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-scalars:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

答案 9 :(得分:0)

我遇到类似这样的问题,可能是依赖问题

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

已经包含okhttp,如此处https://github.com/square/retrofit/blob/d04f3a50e41ca01d22f370ac4f332f6ddf4ba9fe/pom.xml所示,因此从依赖项列表中删除okhttp,然后同步并重试。

答案 10 :(得分:0)

我遇到了这个错误。经过多次搜索,发现我忘了添加Internet权限才能显示。

添加此权限后,我的错误已解决。

答案 11 :(得分:0)

如果未添加改造依赖项或未添加任何其他 google 服务,您可能会遇到此类问题。如果您添加了 Internet 权限,请务必检查清单文件

在清单文件中

<uses-permission android:name="android.permission.INTERNET" />

在应用级gradle

implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.retrofit2:converter-scalars:2.4.0'