Errore durante il gonfiaggio durante l'estensione di una classe


188

Sto cercando di creare una vista personalizzata GhostSurfaceCameraViewche si estendeSurfaceView . Ecco il mio file di definizione della classe

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();
    }
}

E questo è nel mio ghostviewscreen.xml:

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

Ora nell'attività che ho fatto:

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

Quando setContentView()viene chiamato, viene generata un'eccezione:

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

Qualcuno può dirmi perché ho questo errore? Grazie.

Risposte:


369

Penso di aver capito perché non funzionava. Stavo solo fornendo un costruttore per il caso di un parametro 'contesto' quando avrei dovuto fornire un costruttore per il caso due parametri 'Contesto, AttributeSet'. Avevo anche bisogno di dare al costruttore accesso pubblico. Ecco la mia soluzione:

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();
        }

4
A volte le cose più semplici possono essere un problema :) Buono a sapersi che entrambi i parametri vengono utilizzati per gonfiare.
Warpzit,

5
Grazie!! In nessun punto degli esempi potrei trovare alcuna menzione sulla necessità di sovraccaricare tutti i costruttori! Mi hai risparmiato ore (giorni?) Di tempo.
Scott Biggs,

1
Molte grazie! Il messaggio di errore è piuttosto aspecifico, il che mi ha lasciato perplesso per un momento, avrebbero dovuto includere il motivo (sovraccarico costruttore mancante) nel loro messaggio di errore.
AgentKnopf,

1
grazie per questo. qualcuno sa se questo va oltre il limite per visualizzazioni personalizzate? devi includere entrambi i costruttori ogni volta che crei una vista personalizzata? (contesto, quindi contesto e attributi)
Tim

2
O, avrei dovuto vederlo prima! Il messaggio View is not using the 2- **OR** 3-argument View constructorsè in qualche modo fuorviante.
Attacco

45

@Tim - Entrambi i costruttori non sono richiesti, ViewClassName(Context context, AttributeSet attrs )è necessario solo il costruttore. L'ho scoperto in modo doloroso, dopo ore e ore di tempo sprecato.

Sono molto nuovo nello sviluppo di Android, ma sto facendo un'ipotesi selvaggia qui, che forse a causa del fatto che poiché stiamo aggiungendo la Viewclasse personalizzata nel file XML, stiamo impostando diversi attributi ad esso nell'XML, che ha bisogno di da elaborare al momento dell'istanza. Qualcuno molto più esperto di me sarà in grado di fare luce più chiara su questo argomento però.


Questo ha senso, il mio TextView personalizzato viene sempre costruito con ViewClassName (Context context, AttributeSet attrs) quando definisco gli attributi per esso nel file XML. Se lo creo un'istanza senza definire nel file xml, il costruttore normale viene chiamato con solo contesto, ViewClassName (contesto di contesto). Mi chiedevo cosa facesse l'altro costruttore e secondo questo: stackoverflow.com/a/4022916/1505341 risposta, dovrebbe essere usato per impostare uno stile di base per la vista.
Kerem,

19

Un'altra possibile causa del messaggio "Errore durante il gonfiaggio della classe" potrebbe essere l'ortografia errata del nome del pacchetto completo in cui è specificato in XML:

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

L'apertura del file XML di layout nell'editor XML di Eclipse dovrebbe evidenziare questo problema.


2
Questa era davvero la soluzione per la mia applicazione. com.zerokol.views.joystickview È diventato com.zerokol.views.JoystickView E ha funzionato!
Andy,

vero. Controlla l'ortografia o prova a lavorare usando le intenzioni fornite dal tuo IDE, basta iniziare digitando il nome del pacchetto e tutte le classi disponibili verranno visualizzate sotto le intenzioni.
Khay,

questo è stato il mio caso.
Banee Ishaque K,

2

È importante scrivere il percorso completo della classe nel file XML. Ho ricevuto "Error inflating class" quando è stato scritto solo il nome della sottoclasse.


Questo è molto simile a quello che suggerisce @rmtheis. Forse meglio commentare la sua risposta o addirittura modificarla con ulteriori informazioni.
Ilia Barahovski,

1

Ho avuto questo errore che mi ha tormentato nelle ultime ore. A quanto pare, avevo aggiunto la vista personalizzata lib come modulo in Android Studio, ma avevo trascurato di aggiungerla come dipendenza nelle app build.gradle.

dependencies {
    ...
    compile project(':gifview')
}

1

prima ho ricevuto questo errore a causa di un'inizializzazione personalizzata all'interno del costruttore che tentava di accedere a un oggetto null.


0

Ho avuto lo stesso problema estendendo un TextEdit. Per me l'errore è stato di non aggiungere "pubblico" al costruttore. Nel mio caso funziona anche se definisco solo un costruttore, quello con argomenti Contexte AttributeSet. La cosa cablata è che il bug si rivela solo quando creo un APK (cantato o meno) e lo trasferisco sui dispositivi. Quando l'applicazione viene eseguita tramite AndroidStudio -> RunApp su un dispositivo USB collegato, l'app funziona.


0

nel mio caso ho aggiunto tale risorsa ciclica:

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

quindi cambiato in

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

e ha funzionato


0

Nel mio caso, ho copiato la mia classe da qualche altra parte e non ho notato subito che si trattava di una abstractclasse. Non puoi gonfiare classi astratte.


0

La cosa da capire qui è che:

Il costruttore ViewClassName(Context context, AttributeSet attrs )viene chiamato quando si gonfia customView tramite xml. Vedi che non stai usando la nuova parola chiave per creare un'istanza del tuo oggetto, cioè non lo stai facendo new GhostSurfaceCameraView(). In questo modo stai chiamando il primo costruttore cioè public View (Context context).

Considerando che quando si gonfia la vista da XML, cioè quando si usa setContentView(R.layout.ghostviewscreen);o si usa findViewById, tu, NO, non tu! , il sistema Android chiama ilViewClassName(Context context, AttributeSet attrs ) costruttore.

Questo è chiaro quando si legge la documentazione: "Costruttore che viene chiamato quando si gonfia una vista da XML." Vedi: https://developer.android.com/reference/android/view/View.html#View(android.content.Context,%20android.util.AttributeSet)

Quindi, non dimenticare mai il polimorfismo di base e non dimenticare mai di leggere la documentazione. Salva un sacco di mal di testa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.