我使用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);
}
}
}
答案 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'
答案 1 :(得分:4)
我在棒棒糖设备下面临这个错误。
我正在使用multiDexEnabled true。
将此代码添加到扩展Application类的类后,我的问题解决了。
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
MultiDex.install(this);
}
答案 2 :(得分:2)
您是否添加了以下proguard规则?
add = function(x, y) x+y
sapply(1:5, add(y = 10))
答案 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'