J'utilise Retrofit pour gérer les données Serverside de Mobile. Après la mise en œuvre de la modernisation, j'obtiens l'exception ci-dessous.
Qu'est-ce que je fais mal?
com.name.App_idea W/System.err: Java.lang.NoClassDefFoundError: retrofit2.Utils à retrofit2.Retrofit $ Builder.baseUrl (Retrofit.Java:434) sur com.name.App_idea.utils.Idea.onCreate (Idea.Java:103) sur Android.app.Instrumentation.callApplicationOnCreate (Instrumentation.Java:1007) sur Android.app.ActivityThread .handleBindApplication (ActivityThread.Java:4541) à Android.app.ActivityThread.access $ 1500 (ActivityThread.Java:151) à Android.app.ActivityThread $ H.handleMessage (ActivityThread.Java: 1381) Sur Android.os.Handler.dispatchMessage (Handler.Java:110) Sur Android.os.Looper.loop (Looper.Java:193) Sur Android. app.ActivityThread.main (ActivityThread.Java:5292) à Java.lang.reflect.Method.invokeNative (Méthode native) à Java.lang.reflect.Method.invoke (Method.Java : 515) Sur com.Android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.Ja va: 824) sur com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:640) sur dalvik.system.NativeStart.main (Méthode native)
Retrofit Init
mRetrofit = new Retrofit.Builder()
.baseUrl(AppConstance.APP_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpClient())
.build();
Fichier 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'
}
Classe d'application
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);
}
}
}
C'est le problème de configuration de Bulid J'ai également eu le même problème parfois
Dans ton utilisation
compile 'com.google.Android.gms:play-services:8.4.0'
Enire Google Playservice Lib pouvez-vous changer les éléments que les lib utilisent dans votre projet
Exemple
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
Référez-vous à cet URl https://developers.google.com/Android/guides/setup#add_google_play_services_to_your_project
Cette erreur viendra à cause de MultiDexApplication .J'ai face à ce genre de problème avec une autre bibliothèque pas la même bibliothèque, mais une autre bibliothèque. votre code de bibliothèque de conversion est converti en dex) le fichier n’est pas à définir (installer).
Pour résoudre ce problème, vous devez gérer plusieurs fichiers Dex. à l'aide de l'application build.gradle
& classe d'application
modifications ci-dessous requises dans le fichier 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
entier
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.
}
Si votre application utilise la classe ApplicationClass, vous pouvez remplacer la méthode attachBaseContext()
et appeler MultiDex.install(this)
pour activer multidex. Pour installer le fichier multipledex context à l'aide de la classe Applicaiton qui devrait être étendue à [MultiDexApplication][2]
public class MyAppClass extends MultiDexApplication{
@Override
protected void attachBaseContext(Context newBase) {
MultiDex.install(newBase);
super.attachBaseContext(newBase);
}
}
Suggestion
compilation sélective d’API dans votre exécutable
N'utilisez pas l'intégralité du service Google Play, utilisez uniquement la bibliothèque requise. À partir de la version 6.5, vous pouvez compiler de manière sélective les API du service Google Play dans votre application. Par exemple, pour inclure uniquement les API Google Fit et Android Wear, remplacez la ligne suivante dans votre fichier build.gradle:
compile 'com.google.Android.gms:play-services:8.4.0'
avec ces lignes:
compile 'com.google.Android.gms:play-services-fitness:8.4.0'
compile 'com.google.Android.gms:play-services-wearable:8.4.0'
Avec la référence de ma réponse https://stackoverflow.com/a/34948154/1140237
Je faisais face à cette erreur ci-dessous périphériques Lollipop.
J'utilisais multiDexEnabled true.
Après avoir ajouté ce code à la classe qui étend la classe Application, mon problème a été résolu.
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
MultiDex.install(this);
}
référence: https://stackoverflow.com/a/39968486/4777524
Avez-vous ajouté les règles de proguard suivantes?
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
Documentation: http://square.github.io/retrofit/
Vous devriez faire la classe Utils comme ceci:
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();
}
}
Créez une interface comme celle-ci pour les méthodes http:
public interface EndPointInterface{
@FormUrlEncoded
@POST(Constants.URL_LOGON)
Call<Doctor> login(@Field(Constants.EMAIL) String email,
@Field(Constants.PASSWORD) String password);
}
Dans votre activité où vous appelez les webservices, procédez comme suit:
@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());
}
});
}
mRetrofit = new Retrofit.Builder()
.baseUrl(AppConstance.APP_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpClient())
.build();
Renvoyer à
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
mRetrofit = new Retrofit.Builder()
.baseUrl(AppConstance.APP_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
J'ai rencontré des problèmes similaires, c'est probablement un problème de dépendance
compile 'com.squareup.retrofit2:retrofit:2.0.2'
comprend déjà okhttp comme vu ici https://github.com/square/retrofit/blob/d04f3a50e41e01d22f370ac4f332f6ddf4ba9fe/pom.xml , supprimez donc okhttp de la liste des dépendances, puis synchronisez et essayez à nouveau.
Essayez d’utiliser la même version de lib pour la modernisation de base lib et les convertisseurs.
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'
J'ai rencontré avec cette erreur. Et après de nombreuses recherches, j'ai constaté que j'oublie d'ajouter une autorisation Internet pour se manifester.
Après avoir ajouté cette permission, mon erreur a été résolue.
Avec ces nombreuses bibliothèques, il doit avoir dépassé la fameuse limite de la méthode 64k, vous devez activer votre application pour multidex. Voici comment vous le faites. https://developer.Android.com/tools/building/multidex.html