简体   繁体   中英

Android app, “Class not found exception” in Android Studio - what am I doing wrong?

The Android Studio debugger is giving me a Class Not Found exception whenever I try to run it. It seems like the crash is happening on line 38 - setContentView(R.layout.dataman_main); to set the main activity layout - which was working fine before. I'm an amateur developer and I've been stuck on this problem for 3 days - could anyone tell me what I am doing wrong?

Here's a copy of the debugger variables after the crash, with the "Exception" and "detailMessage" fields expanded:

Exception = {ClassNotFoundException@5326} 
 ex = {NoClassDefFoundError@5330} "java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available"
 backtrace = {Object[38]@5331} 
 cause = null
 detailMessage = "android.widget.ViewStub"
  count = 46
  hash = 0
  shadow$_klass_ = {Class@3925} "class java.lang.String"
  shadow$_monitor_ = -1913475893
 stackTrace = {StackTraceElement[0]@5333} 
 suppressedExceptions = {Collections$EmptyList@5334}  size = 0
 shadow$_klass_ = {Class@4242} "class java.lang.ClassNotFoundException"
 shadow$_monitor_ = -2070025328
Variables debug info not available

Here's what my main activity looks like:

package norrisduncan.dataman;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.view.ViewStub;

import java.lang.reflect.InvocationTargetException;

import norrisduncan.dataman.adapter.MainPagerAdapter;

/**
 * Created by norri on 12/13/2017.
 */


public class DataMan_Main extends AppCompatActivity {

PointF startPoint = new PointF(0,0);
PointF endPoint = new PointF(0,0);

private norrisduncan.dataman.UsableScreenSizeLineView UsableScreenSizeLineView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.dataman_main);

    //FINDING THE SIZE OF THE USABLE SCREEN SPACE SO THAT UI ELEMENTS CAN SCALE TO IT
    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    int usableScreenWidth = displayMetrics.widthPixels;
    int usableScreenHeight = displayMetrics.heightPixels;

    //ASSOCIATES UI JAVA IMAGEVIEW FIELDS WITH THEIR XML IMAGEVIEWS
    ImageView actionDrawerPullTab = findViewById(R.id.actionDrawerPullTabImageViewXML);

    UsableScreenSizeLineView = findViewById(R.id.usable_screen_size_line_view);
    UsableScreenSizeLineView.setStartPoint(startPoint);
    endPoint.set(usableScreenWidth,usableScreenHeight);
    UsableScreenSizeLineView.setEndPoint(endPoint);
    UsableScreenSizeLineView.draw();

    //SETS THE PAINT COLOR AND SIZE FOR THE TEST LINE THAT TELLS ME HOW BIG THE USABLE SCREEN SIZE IS
    Paint screenSizeTestLinePaint = new Paint();
    screenSizeTestLinePaint.setColor(Color.BLACK);
    screenSizeTestLinePaint.setStrokeWidth(1f);

    //SETS THE PULL TAB IMAGEVIEW SIZES ACCORDING TO SCREEN SIZE
    RelativeLayout.LayoutParams actionDrawerPullTabParams = new RelativeLayout.LayoutParams(usableScreenHeight / 3, usableScreenHeight / 6);
    actionDrawerPullTabParams.leftMargin = 0 - usableScreenHeight * 3 / 18;
    actionDrawerPullTabParams.topMargin = 0;
    actionDrawerPullTab.setLayoutParams(actionDrawerPullTabParams);

    //SETS THE VIEWPAGER AND PAGERADAPTER
    ViewPager viewPager = findViewById(R.id.view_pager);
    MainPagerAdapter mainPagerAdapter = new MainPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(mainPagerAdapter);

}

//FINDS THE FULL SCREEN SIZE USING EITHER display.getRealSize() OR ELSE IT DOES SOME ?MAGIC? TO ?.INVOKE?
//(NEVER HEARD OF THIS) getRawHeight()/getRawWidth() ON THE DEFAULT DISPLAY
public static Point getScreenRealSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();

    if (Build.VERSION.SDK_INT >= 17) {
        display.getRealSize(size);
    } else if (Build.VERSION.SDK_INT >= 14) {
        try {
            size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
            size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        } catch (NoSuchMethodException e) {
        }
    }
    return size;
}

public static Point getUsableScreenSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    return size;
}

}

The layout file dataman_main.xml that the setContentView() method is supposed to load:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >

    <View
        android:id="@+id/baselayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/paper" />

    <norrisduncan.doubledrawers.UsableScreenSizeLineView
        android:id="@+id/usable_screen_size_line_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
    android:id="@+id/actionDrawerPullTabImageViewXML"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/actions_drawer_pull_tab_textured_662x331x441ppi"
    />

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="48dp"
        android:text="@string/layout_fragment_1_title" />

</RelativeLayout>

The manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="norrisduncan.dataman">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name="norrisduncan.dataman.DataMan_Main"
            android:screenOrientation="portrait"
            android:theme="@style/FullScreenTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

And if it will help, I can provide my other classes, too - there are 6 of them, but I don't think any of them even get called before the crash happens. What the heck am I doing wrong to this poor program???

I'm guessing you have a gradle dependency to a library containing the UsableScreenSizeLineView class and also to a number of other libraries. Due to a design limitation a dex file (where the classes are stored inside the apk) can't contain more than 65k methods. When an app has more methods or some development features like instant run are used, classes are split into different dex files and different classloaders may be used to load the dex files. There is a classloader tree hierarchy with the boot classloader at the top. These classloaders are used to get the classes from the dex files before they can be used in the app and when a classloader can't find a class it delegates the search to its parent. The problem is the parent doesn't ask its children so if the boot classloader doesn't find it the app stops.

First you should check that UsableScreenSizeLineView is the class causing the problem by removing it from the layout. If the error disappears you can try these potential fixes:

  • disable instant run in android studio settings if it's enabled OR
  • move the dependency to your library up in the list so that it's loaded with the boot classloader if the class is part of a library OR
  • include the source code for the view in your project (as separate module) if it's currently in a library

更换norrisduncan.doubledrawers.UsableScreenSizeLineViewnorrisduncan.dataman.UsableScreenSizeLineView在XML文件中。

Problem is with your xml file.

In xml file you have used <norrisduncan.doubledrawers.UsableScreenSizeLineView> tag whereas in DataMan_Main.java , You have used norrisduncan.dataman.UsableScreenSizeLineView . You need to replace this with correct package name.

change the value in the java

private norrisduncan. dataman .UsableScreenSizeLineView

to

norrisduncan. doubledrawers .UsableScreenSizeLineView

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM