Android Studio:应用模块所有类上的 NoClassDefFoundError
Posted
技术标签:
【中文标题】Android Studio:应用模块所有类上的 NoClassDefFoundError【英文标题】:Android Studio: NoClassDefFoundError on all classes of the app module 【发布时间】:2016-05-17 01:35:04 【问题描述】:您好,我正在开发一个在 android Studio 中使用 minSdkVersion 17 的应用程序。
这是我的 MainActivity.java
package in.co.dryve.customer.activities;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import in.co.dryve.customer.R;
import in.co.dryve.customer.fragments.AboutUsFragment;
import in.co.dryve.customer.fragments.BookNowFragment;
import in.co.dryve.customer.fragments.HelpFragment;
import in.co.dryve.customer.fragments.HowItWorksFragment;
import in.co.dryve.customer.fragments.MyBookingsFragment;
import in.co.dryve.customer.models.User;
import in.co.dryve.customer.utils.LoginPreferences;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener
LoginPreferences loginPreferences;
private static final int LOGIN_REQ_CODE = 1;
private static final int PROFILE_REQ_CODE = 2;
TextView navNameTv, navEmailTv;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginPreferences = new LoginPreferences(this);
BookNowFragment bookNowFragment = new BookNowFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,bookNowFragment);
fragmentTransaction.commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
View view = navigationView.getHeaderView(0);
navNameTv = (TextView)view.findViewById(R.id.nav_username);
navEmailTv = (TextView)view.findViewById(R.id.nav_useremail);
if(loginPreferences.isLoggedIn())
User user = loginPreferences.getUser();
navNameTv.setText(user.getName().toUpperCase());
navEmailTv.setText(user.getEmail());
else
navNameTv.setText(getResources().getString(R.string.login_as_user));
navEmailTv.setVisibility(View.GONE);
view.findViewById(R.id.ll_profile).setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (loginPreferences.isLoggedIn())
startActivityForResult(new Intent(MainActivity.this, ProfileActivity.class), PROFILE_REQ_CODE);
else
startActivityForResult(new Intent(MainActivity.this, LoginActivity.class), LOGIN_REQ_CODE);
);
navigationView.setNavigationItemSelectedListener(this);
@Override
public void onBackPressed()
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START))
drawer.closeDrawer(GravityCompat.START);
else
super.onBackPressed();
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if(loginPreferences.isLoggedIn())
navNameTv.setVisibility(View.VISIBLE);
navEmailTv.setVisibility(View.VISIBLE);
User user = loginPreferences.getUser();
navNameTv.setText(user.getName());
navEmailTv.setText(user.getEmail());
else
navNameTv.setText(getResources().getString(R.string.login_as_user));
navEmailTv.setVisibility(View.GONE);
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item)
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_book_now)
BookNowFragment bookNowFragment = new BookNowFragment();
bookNowFragment.setContext(MainActivity.this);
bookNowFragment.setContext(MainActivity.this);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,bookNowFragment);
fragmentTransaction.commit();
getSupportActionBar().setTitle("Dryve");
else if (id == R.id.nav_my_bookings)
MyBookingsFragment myBookingsFragment = new MyBookingsFragment();
myBookingsFragment.setContext(MainActivity.this);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,myBookingsFragment);
fragmentTransaction.commit();
getSupportActionBar().setTitle("My Bookings");
else if (id == R.id.nav_how_it_works)
HowItWorksFragment howItWorksFragment = new HowItWorksFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,howItWorksFragment);
fragmentTransaction.commit();
getSupportActionBar().setTitle("How It Works");
else if (id == R.id.nav_share)
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.share_text));
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, "Send via"));
else if (id == R.id.nav_rate_us)
Intent rateUsIntent = new Intent(Intent.ACTION_VIEW);
rateUsIntent.setData(Uri.parse("market://details?id=in.co.dryve.customer"));
startActivity(rateUsIntent);
else if (id == R.id.nav_help)
HelpFragment helpFragment = new HelpFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,helpFragment);
fragmentTransaction.commit();
getSupportActionBar().setTitle("Help");
else if(id == R.id.nav_about_us)
AboutUsFragment aboutUsFragment = new AboutUsFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,aboutUsFragment);
fragmentTransaction.commit();
getSupportActionBar().setTitle("About Us");
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
这是 BookNowFragment.java
package in.co.dryve.customer.fragments;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.android.gms.fitness.request.DataDeleteRequest;
import com.google.android.gms.maps.model.LatLng;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import in.co.dryve.customer.R;
import in.co.dryve.customer.adapters.VehicleAdapter;
import in.co.dryve.customer.datePicker.DatePickerActivity;
import in.co.dryve.customer.models.Constants;
import in.co.dryve.customer.models.Vehicle;
import in.co.dryve.customer.parsers.VehicleListParser;
import in.co.dryve.customer.serverutils.AppController;
import in.co.dryve.customer.serverutils.ServerRequests;
import in.co.dryve.customer.serverutils.Urls;
import in.co.dryve.customer.utils.Intents;
public class BookNowFragment extends Fragment
private static final int REQ_PICKUP_DATE = 4;
private static final int REQ_RETURN_DATE = 5;
Context context;
ListView bikesListView;
LatLng latLng;
ProgressBar progressBar;
LinearLayout pickupTimeLL, returnTimeLL;
TextView pickupTimeTV, returnTimeTV, pickupTimeLabelTV, returnTimeLabelTV;
VehicleAdapter adapter;
Date pickupDate = new Date(), returnDate = new Date();
boolean isPickupTimeSet, isReturnTimeSet;
public void setContext(Context context)
this.context = context;
public BookNowFragment()
// Required empty public constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_book_now, container, false);
bikesListView = (ListView)view.findViewById(R.id.listview_bikes);
progressBar = (ProgressBar)view.findViewById(R.id.pb_load_vehicle);
pickupTimeLL = (LinearLayout)view.findViewById(R.id.ll_pickup_time);
returnTimeLL = (LinearLayout)view.findViewById(R.id.ll_return_time);
pickupTimeTV = (TextView)view.findViewById(R.id.tv_pickup_time);
returnTimeTV = (TextView)view.findViewById(R.id.tv_return_time);
pickupTimeLabelTV = (TextView)view.findViewById(R.id.tv_pickup_time_label);
returnTimeLabelTV = (TextView)view.findViewById(R.id.tv_return_time_label);
return view;
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
this.context = getContext();
latLng = new LatLng(12.9667,77.5667); //Bangalore LatLng
isPickupTimeSet =false;
isReturnTimeSet = false;
loadVehicles(latLng, 0, 0);
pickupTimeLL.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent intent = new Intent(context, DatePickerActivity.class);
Calendar calendar = Calendar.getInstance();
intent.putExtra(Constants.MONTH, calendar.get(Calendar.MONTH));
intent.putExtra(Constants.YEAR, calendar.get(Calendar.YEAR));
intent.putExtra(Constants.DATE, calendar.get(Calendar.DATE));
intent.putExtra(Constants.HOUR, calendar.get(Calendar.HOUR_OF_DAY));
startActivityForResult(intent, REQ_PICKUP_DATE);
);
returnTimeLL.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent intent = new Intent(context, DatePickerActivity.class);
if(isPickupTimeSet)
intent.putExtra(Constants.YEAR, pickupDate.getYear()+1900);
intent.putExtra(Constants.MONTH, pickupDate.getMonth());
intent.putExtra(Constants.DATE, pickupDate.getDate());
intent.putExtra(Constants.HOUR, pickupDate.getHours());
else
Calendar calendar = Calendar.getInstance();
intent.putExtra(Constants.MONTH, calendar.get(Calendar.MONTH));
intent.putExtra(Constants.YEAR, calendar.get(Calendar.YEAR));
intent.putExtra(Constants.DATE, calendar.get(Calendar.DATE));
intent.putExtra(Constants.HOUR, calendar.get(Calendar.HOUR_OF_DAY));
startActivityForResult(intent, REQ_RETURN_DATE);
);
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQ_PICKUP_DATE)
if(resultCode == Activity.RESULT_OK)
isPickupTimeSet = true;
pickupDate = new Date(data.getIntExtra(Constants.YEAR,0)-1900,data.getIntExtra(Constants.MONTH,0),data.getIntExtra(Constants.DATE,0),data.getIntExtra(Constants.HOUR,0),0);
pickupTimeLabelTV.setTextSize(12);
pickupTimeTV.setVisibility(View.VISIBLE);
pickupTimeTV.setText(new SimpleDateFormat("dd MMM\nhh:mm a", Locale.getDefault()).format(pickupDate.getTime()).toUpperCase());
if(isPickupTimeSet && isReturnTimeSet)
loadVehicles(latLng,pickupDate.getTime(),returnDate.getTime());
else if(requestCode == REQ_RETURN_DATE)
if(resultCode == Activity.RESULT_OK)
isReturnTimeSet = true;
returnDate = new Date(data.getIntExtra(Constants.YEAR,0)-1900,data.getIntExtra(Constants.MONTH,0),data.getIntExtra(Constants.DATE,0),data.getIntExtra(Constants.HOUR,0),0);;
returnTimeLabelTV.setTextSize(12);
returnTimeTV.setVisibility(View.VISIBLE);
returnTimeTV.setText(new SimpleDateFormat("dd MMM\nhh:mm a",Locale.getDefault()).format(returnDate.getTime()).toUpperCase());
if(isPickupTimeSet && isReturnTimeSet)
loadVehicles(latLng,pickupDate.getTime(),returnDate.getTime());
public void loadVehicles(final LatLng latLng, final long pickupTime, final long returnTime)
String url = Urls.BASE_URL + Urls.SEARCH_NEAR
+ "lat=" + latLng.latitude
+ "&lon=" + latLng.longitude
+ "&pickup_time=" + pickupTime
+ "&drop_time=" + returnTime;
progressBar.setVisibility(View.VISIBLE);
JsonArrayRequest jsonObjectRequest = new JsonArrayRequest(Request.Method.GET, url, new Response.Listener<JSONArray>()
@Override
public void onResponse(JSONArray response)
try
progressBar.setVisibility(View.GONE);
List<Vehicle> vehicleList = new VehicleListParser().parse(response);
initListView(vehicleList);
catch (Exception e)
e.printStackTrace();
, new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
progressBar.setVisibility(View.GONE);
Log.e("error",error.getMessage());
Toast.makeText(context, "ERROR", Toast.LENGTH_SHORT).show();
);
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
/*new AsyncTask<Void,Void,List<Vehicle>>()
@Override
protected void onPreExecute()
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
@Override
protected List<Vehicle> doInBackground(Void... params)
return new ServerRequests().searchVehicles(latLng,pickupTime,returnTime);
@Override
protected void onPostExecute(List<Vehicle> vehicleList)
super.onPostExecute(vehicleList);
if(vehicleList!=null)
progressBar.setVisibility(View.GONE);
initListView(vehicleList);
.execute();*/
public void initListView(final List<Vehicle> vehicleList)
adapter = new VehicleAdapter(context,vehicleList);
bikesListView.setAdapter(adapter);
bikesListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
if(isPickupTimeSet && isReturnTimeSet)
Intents.openBikeDetailActivity(context,vehicleList.get(position),pickupDate, returnDate);
if(!isPickupTimeSet && isReturnTimeSet)
Intents.openBikeDetailActivity(context,vehicleList.get(position),returnDate,false);
if(isPickupTimeSet && !isReturnTimeSet)
Intents.openBikeDetailActivity(context,vehicleList.get(position),pickupDate,true);
if(!isPickupTimeSet && !isReturnTimeSet)
Intents.openBikeDetailActivity(context,vehicleList.get(position));
);
这是应用程序的 build.gradle 文件
apply plugin: 'com.android.application'
android
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig
applicationId "in.co.dryve.customer"
minSdkVersion 17
targetSdkVersion 23
multiDexEnabled true
versionCode 1
versionName "1.0"
buildTypes
release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debug
debuggable true
lintOptions
checkReleaseBuilds false
abortOnError false
repositories
mavenCentral()
dependencies
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'junit:junit:4.12'
compile files('libs/razorpay-android-0.10.0.jar')
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services-maps:8.4.0'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services-maps:8.4.0'
compile 'com.android.support:design:23.1.1'
compile 'com.facebook.android:facebook-android-sdk:4.8.1'
compile 'com.facebook.android:audience-network-sdk:4.8.1'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.google.android.gms:play-services-auth:8.4.0'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:multidex:1.0.1'
compile 'com.google.android.gms:play-services-ads:8.4.0'
compile 'com.google.android.gms:play-services-identity:8.4.0'
compile 'com.google.android.gms:play-services-gcm:8.4.0'
compile 'com.mcxiaoke.volley:library:1.0.19'
apply plugin: 'com.google.gms.google-services'
该应用在大多数设备上运行良好,但在少数设备上崩溃。这是崩溃的日志。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.co.dryve.customer, PID: 19380
java.lang.NoClassDefFoundError: in.co.dryve.customer.fragments.BookNowFragment$3
at in.co.dryve.customer.fragments.BookNowFragment.loadVehicles(BookNowFragment.java:169)
at in.co.dryve.customer.fragments.BookNowFragment.onActivityCreated(BookNowFragment.java:97)
at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1970)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1092)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5256)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2174)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
at android.app.ActivityThread.access$900(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1213)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5072)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
最初我使用OkHttpClient
进行网络调用。该应用程序在使用相同的 NoClassDefFoundError
初始化 AsyncTask 时曾经崩溃。寻找解决方案,但找不到合适的解决方案。然后我观察到应用程序在所有网络调用期间崩溃并出现相同的错误。然后我用 Volley JsonArrayRequest
替换了 AsyncTask
。该应用程序在初始化JsonArrayRequest
时仍然崩溃,并出现相同的错误NoClassDefFOundError
。
有人可以帮我解决这个问题吗?
更新:后来我发现这不是 AsyncTask
或 JsonArrayRequest
的问题,但我的应用程序库中的所有类都抛出了 NoClassDefFoundError,但活动除外.在某些手机中,找不到应用程序模块中类的类定义。在 MI 3、MI 4、Google Nexus 等手机中观察到。
【问题讨论】:
【参考方案1】:感谢您的回答。 NoClassDefFoundError 的最初原因是我忘记通过设置启用 MultiDex
multiDexEnabled true
在 gradle 文件中建议 here.
【讨论】:
【参考方案2】:根据https://github.com/lukaspili/Android-Volley-library,您需要将此行添加到您在 build.gradle 中的依赖项中:
compile 'com.google.volley:volley:1.0.0-SNAPSHOT'
【讨论】:
我正在使用 mcxiaoke volley library 并且我没有将库作为 jar 导入,而是将其添加到依赖项中作为compile 'com.mcxiaoke.volley:library:1.0.19'
即使我没有使用 Volley,我的应用程序也崩溃了。您可以在 BookNowFragment.java 中看到注释的 AsyncTask
更新:后来我发现这不是 AsyncTask 或 JsonArrayRequest 的问题,但我的应用程序库中除活动外的所有类都被抛出 NoClassDefFoundError 。在某些手机中,找不到应用程序模块中类的类定义。在 MI 3、MI 4、Google Nexus 等手机中观察到。
***.com/questions/26609734/…以上是关于Android Studio:应用模块所有类上的 NoClassDefFoundError的主要内容,如果未能解决你的问题,请参考以下文章
将模块导入到 android studio 0.4.0v 上的 gradle 项目
Android Studio 中应用程序、项目、模块等的所有不同名称是啥
Android Studio - Gradle 总是构建所有模块,而不仅仅是我运行的模块