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

有人可以帮我解决这个问题吗?

更新后来我发现这不是 AsyncTaskJsonArrayRequest 的问题,但我的应用程序库中的所有类都抛出了 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 总是构建所有模块,而不仅仅是我运行的模块

1.3Android Studio创建一个Android Library

Android Studio 上的新 Flutter 项目

如何在 Android Studio 中创建测试?