Fehler beim Aufblasen beim Erweitern einer Klasse

188

Ich versuche, eine benutzerdefinierte Ansicht zu erstellen GhostSurfaceCameraView, die erweitert wird SurfaceView. Hier ist meine Klassendefinitionsdatei

GhostSurfaceCameraView.java::

public class GhostSurfaceCameraView extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;

    GhostSurfaceCameraView(Context context) {
        super(context);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where to draw.
        mCamera = Camera.open();
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return, so stop the preview.
        // Because the CameraDevice object is not a shared resource, it's very
        // important to release it when the activity is paused.
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }   

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(w, h);
        parameters.set("orientation", "portrait");
        // parameters.setRotation(90); // API 5+
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }
}

Und das ist in meiner ghostviewscreen.xml:

<com.alpenglow.androcap.GhostSurfaceCameraView android:id="@+id/ghostview_cameraview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"/>

Jetzt in der Aktivität, die ich gemacht habe:

protected void onCreate(Bundle savedInstanceState) {
    try {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ghostviewscreen);
    }
}

Beim setContentView()Aufruf wird eine Ausnahme ausgelöst:

Binary XML file 09-17 22:47:01.958: ERROR/ERROR(337):
ERROR IN CODE:
android.view.InflateException: Binary
XML file line #14: Error inflating
class
com.alpenglow.androcap.GhostSurfaceCameraView

Kann mir jemand sagen, warum ich diesen Fehler bekomme? Vielen Dank.

exzentrisch
quelle

Antworten:

369

Ich glaube, ich habe herausgefunden, warum das nicht funktioniert hat. Ich habe nur dann einen Konstruktor für den Fall eines Parameters 'context' bereitgestellt, wenn ich einen Konstruktor für den Fall mit zwei Parametern 'Context, AttributeSet' hätte bereitstellen sollen. Ich musste dem / den Konstruktor (en) auch öffentlichen Zugang gewähren. Hier ist mein Fix:

public class GhostSurfaceCameraView extends SurfaceView implements SurfaceHolder.Callback {
        SurfaceHolder mHolder;
        Camera mCamera;

        public GhostSurfaceCameraView(Context context)
        {
            super(context);
            init();
        }
        public GhostSurfaceCameraView(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            init();
        }
        public GhostSurfaceCameraView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
exzentrisch
quelle
4
Manchmal können die einfachsten Dinge ein Problem sein :) Gut zu wissen, dass beide Parameter zum Aufblasen verwendet werden.
Warpzit
5
Danke dir!! Nirgendwo in den Beispielen konnte ich die Notwendigkeit einer Überladung aller Konstruktoren erwähnen! Du hast mir Stunden (Tage?) Zeit gespart.
Scott Biggs
1
Vielen Dank! Die Fehlermeldung ist ziemlich unspezifisch, was mich für einen Moment verblüfft hatte. Sie hätten den Grund (fehlende Konstruktorüberladung) in ihre Fehlermeldung aufnehmen sollen.
AgentKnopf
1
Danke dafür. Weiß jemand, ob dies für benutzerdefinierte Ansichten allgemein gilt? Sie müssen beide Konstruktoren einschließen, wenn Sie eine benutzerdefinierte Ansicht erstellen? (Kontext und dann Kontext und Attribute)
Tim
2
O, hätte es früher sehen sollen! Die Nachricht View is not using the 2- **OR** 3-argument View constructorsist irgendwie irreführend.
Attacktive
45

@Tim - Beide Konstruktoren sind nicht erforderlich, nur der ViewClassName(Context context, AttributeSet attrs )Konstruktor ist erforderlich. Ich fand das auf schmerzhafte Weise heraus, nach Stunden und Stunden verschwendeter Zeit.

Ich bin sehr neu in der Android-Entwicklung, aber ich vermute hier wild, dass dies möglicherweise darauf zurückzuführen ist, dass wir, da wir die benutzerdefinierte ViewKlasse in die XML-Datei einfügen , im XML mehrere Attribute festlegen, die benötigt werden zum Zeitpunkt der Instanziierung zu verarbeiten. Jemand, der viel besser informiert ist als ich, wird in der Lage sein, diese Angelegenheit klarer zu beleuchten.

KVNam
quelle
Dies ist sinnvoll. Meine benutzerdefinierte Textansicht wird immer mit ViewClassName (Kontextkontext, AttributeSet-Attribute) erstellt, wenn ich Attribute dafür in der XML definiere. Wenn ich es instanziiere, ohne es in der XML-Datei zu definieren, wird der reguläre Konstruktor nur mit dem Kontext ViewClassName (Kontextkontext) aufgerufen. Ich habe mich gefragt, was der andere Konstruktor macht, und laut der folgenden Antwort : stackoverflow.com/a/4022916/1505341 soll er zum Festlegen eines Basisstils für die Ansicht verwendet werden.
Kerem
19

Eine weitere mögliche Ursache für die Meldung "Fehler beim Aufblasen der Klasse" könnte darin bestehen, dass der vollständige Paketname, in dem er in XML angegeben ist, falsch geschrieben wurde:

<com.alpenglow.androcap.GhostSurfaceCameraView android:id="@+id/ghostview_cameraview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>

Das Öffnen Ihrer Layout-XML-Datei im Eclipse-XML-Editor sollte dieses Problem hervorheben.

rmtheis
quelle
2
Dies war in der Tat die Lösung für meine Bewerbung. com.zerokol.views.joystickview Wurde com.zerokol.views.JoystickView Und es hat funktioniert!
Andy
wahr. Überprüfen Sie die Rechtschreibung noch einmal oder versuchen Sie, mit den von Ihrer IDE bereitgestellten Absichten zu arbeiten. Geben Sie zunächst Ihren Paketnamen ein, und alle verfügbaren Klassen werden unter Absichten angezeigt.
Khay
Das war mein Fall.
Banee Ishaque K
2

Es ist wichtig, den vollständigen Klassenpfad in die XML zu schreiben. Ich habe 'Fehler beim Aufblasen der Klasse' erhalten, als nur der Name der Unterklasse geschrieben wurde.

Mykola
quelle
Dies ist sehr ähnlich zu dem, was @rmtheis vorschlägt. Möglicherweise ist es besser, seine Antwort zu kommentieren oder sie sogar mit zusätzlichen Informationen zu bearbeiten.
Ilia Barahovski
1

Ich hatte diesen Fehler in den letzten Stunden. Es stellte sich heraus, dass ich die benutzerdefinierte Ansicht lib als Modul in Android Studio hinzugefügt hatte, aber ich hatte es versäumt, sie als Abhängigkeit in Apps hinzuzufügen build.gradle.

dependencies {
    ...
    compile project(':gifview')
}
Ionoklast Brigham
quelle
1

fwiw , ich habe diesen Fehler aufgrund einer benutzerdefinierten Initialisierung innerhalb des Konstruktors erhalten, der versucht, auf ein Nullobjekt zuzugreifen.

Tom Howard
quelle
0

Ich hatte das gleiche Problem beim Erweitern eines TextEdit. Für mich war der Fehler, dass ich dem Konstruktor nicht "public" hinzugefügt habe. In meinem Fall funktioniert es auch, wenn ich nur einen Konstruktor definiere, den mit Argumenten Contextund AttributeSet. Die verdrahtete Sache ist, dass sich der Fehler nur zeigt, wenn ich eine APK (versengt oder nicht) erstelle und sie auf die Geräte übertrage. Wenn die Anwendung über AndroidStudio -> RunApp auf einem über USB angeschlossenen Gerät ausgeführt wird, funktioniert die App.

Nicola Mingotti
quelle
0

In meinem Fall habe ich eine solche zyklische Ressource hinzugefügt:

<drawable name="above_shadow">@drawable/above_shadow</drawable>

dann geändert zu

<drawable name="some_name">@drawable/other_name</drawable>

und es hat funktioniert

Evgenii Vorobei
quelle
0

In meinem Fall habe ich meine Klasse von einem anderen Ort kopiert und nicht sofort bemerkt, dass es sich um eine abstractKlasse handelt. Sie können abstrakte Klassen nicht aufblasen.

Jesaja
quelle
0

Das, was hier zu verstehen ist, ist Folgendes:

Der Konstruktor ViewClassName(Context context, AttributeSet attrs )wird aufgerufen, wenn die customView über XML aufgeblasen wird. Sie sehen, dass Sie das neue Schlüsselwort nicht verwenden, um Ihr Objekt zu instanziieren, dh Sie tun es nicht new GhostSurfaceCameraView(). Dadurch Sie den ersten Konstruktor dh nennendpublic View (Context context) .

Während beim Aufblasen der Ansicht aus XML, dh beim Verwenden setContentView(R.layout.ghostviewscreen);oder Verwenden findViewById, Sie, NEIN, nicht Sie! , ruft das Android-System dieViewClassName(Context context, AttributeSet attrs ) Konstruktor.

Dies wird beim Lesen der Dokumentation deutlich: "Konstruktor, der beim Aufblasen einer Ansicht aus XML aufgerufen wird." Siehe: https://developer.android.com/reference/android/view/View.html#View(android.content.Context,%20android.util.AttributeSet)

Vergessen Sie daher niemals den grundlegenden Polymorphismus und vergessen Sie niemals das Lesen der Dokumentation. Es erspart eine Menge Kopfschmerzen.

kush
quelle