2015-09-28 2 views
6

Ich habe einige Code mit der neuen Palette Klasse und ich bekomme diese Absturzberichte auf Crashlytics sagen, dass die width and height must be > 0. Was seltsam ist, dass das ist, wie ich die Palette Code aufrufen:android.support.v7.graphics.Palette Breite und Höhe muss> 0

if(bitmap == null || bitmap.getHeight() <= 0 || bitmap.getWidth() <= 0){ 
    //do something 
}else{ 
    Palette.Builder(bitmap).generate(new Palette.PaletteAsyncListener() { 
..... 
} 

So bin ich einfach nicht sicher, wie es möglich ist, dass die Bitmap ganz plötzlich nicht die richtige Höhe oder Breite hat. Ich weiß nicht, aus welchem ​​Teil meines Codes die Ausnahme stammt, da der Bericht nur Elemente in der Palettenklasse enthält. Hier

ist die Ausnahme:

java.lang.RuntimeException: An error occured while executing doInBackground() 
     at android.os.AsyncTask$3.done(AsyncTask.java:300) 
     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 
     at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
     at java.lang.Thread.run(Thread.java:818) 
Caused by: java.lang.IllegalArgumentException: width and height must be > 0 
     at android.graphics.Bitmap.createBitmap(Bitmap.java:815) 
     at android.graphics.Bitmap.createBitmap(Bitmap.java:794) 
     at android.graphics.Bitmap.createBitmap(Bitmap.java:725) 
     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:601) 
     at android.support.v7.graphics.Palette.scaleBitmapDown(Palette.java:282) 
     at android.support.v7.graphics.Palette.access$100(Palette.java:67) 
     at android.support.v7.graphics.Palette$Builder.generate(Palette.java:557) 
     at android.support.v7.graphics.Palette$Builder$1.doInBackground(Palette.java:623) 
     at android.support.v7.graphics.Palette$Builder$1.doInBackground(Palette.java:620) 
     at android.os.AsyncTask$2.call(AsyncTask.java:288) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
     at java.lang.Thread.run(Thread.java:818) 

ich die Palette Klasse bin mit von com.android.support:palette-v7:23+

Irgendwelche Ideen, was falsch sein könnte?

+0

sind Sie wirklich sicher, dass die Bitmap etwas hat oder überhaupt angezeigt wird? Palette muss das Bild analysieren und einige ms später erhalten Sie die Farbe. –

+0

Nun, ich bekomme nur die Fehler über Crashlytics, passiert mir nie. Aber ich überprüfe vor dem Aufruf des Palettencodes auf Null und Größe. – casolorz

+0

die App stürzt nie ab? Sie könnten das Problem neu erstellen? wenn nicht ... vielleicht haben einige Benutzer ein Low-End-Smartphone und die Aufgabe hat viel zu viel Zeit in Anspruch genommen und Palette Null-Werte finden (Absturz über Palette und nicht über die Bitmap) –

Antwort

0

Sie versuchen wahrscheinlich, auf die Breite und Höhe des Oberflächenelements zuzugreifen, bevor es dem Layout hinzugefügt wurde.

Das ist, warum Sie Breite und Höhe gleich 0 erhalten haben, da das Element nicht wirklich da ist.

Verwenden Sie ein ViewTreeObserver http://developer.android.com/reference/android/view/ViewTreeObserver.html

myView.getViewTreeObserver().addOnPreDrawListener(
      new ViewTreeObserver.OnPreDrawListener() { 
       public boolean onPreDraw() { 

         int finalHeight = myView.getMeasuredHeight(); 
         int finalWidth = myView.getMeasuredWidth(); 
         // Do your work here 


        return true; 
       } 
      }); 

wo die myView Bitmap

+0

Ich versuche nicht darauf zuzugreifen, die 'Palette' Klasse ist. Und ich überprüfe nach Breite und Höhe und Null bevor ich die 'Palette' Klasse anrufe. Ich kann den 'Palette'-Code nicht ändern, also wie kann ich sicherstellen, dass dies nicht passiert? – casolorz

+0

Rufen Sie die Palette-Klasse im TreeObserver auf. Auf diese Weise wird die Bitmap definiert, bevor die Palettenklasse versucht, darauf zuzugreifen. –

+0

Ich habe keine Ansichten, in die diese Bitmaps geladen werden, bevor der Palettencode aufgerufen wird. Ich lade sie in die Ansichten, nachdem ich die Palettenfarbe kenne. Dies funktioniert für die meisten meiner Benutzer gut, nur 4 oder 5 Abstürze pro Tag von 20k täglichen Nutzern. – casolorz

0

Ich glaube nicht, Ihren Code hat ein Problem sein würde. Ich habe mir den von Ihnen geposteten StackTrace angeschaut.

at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:601) 
at android.support.v7.graphics.Palette.scaleBitmapDown(Palette.java:282) 

Wenn Sie sich den Quellcode von Palette.java betrachten, werden Sie die Skalierung Logik scaleBitmapDown(Bitmap bitmap) in Methode geschrieben finden. Wenn Ihre Bitmap kleiner als 100 Pixel ist, wird keine Skalierung durchgeführt. Wenn Ihre "Bitmap" jedoch größer als 100 Pixel ist, wird Bitmap.createScaledBitmap() aufgerufen. Jetzt wirft diese Methode die IllegalArgumentException, wenn entweder Breite oder Höhe < 0;

Also die Bitmap, die Sie übergeben, hat keine Nullbreite, denn wenn das der Fall wäre, hätten Sie nie die Methode Bitmap.createScaledBitmap() überhaupt erreicht. Davon abgesehen bin ich mir nicht sicher, was der wahre Grund sein könnte. Versuchen Sie, den Quellcode des exakten Palette.java zu durchlaufen, den Sie verwenden.

+0

Der Code für Palette, den Android Studio mir gibt, wenn ich auf den eingefügten Stacktrace klicke, ist ein bisschen anders, aber es hat die gleichen Überprüfungen, die Sie sehen. Ich denke, wenn die Bitmap zwischen der Überprüfung und der Skalierung etwas passierte, wäre das die einzige Möglichkeit. – casolorz

+0

Meine Vermutung auch. Tritt der Absturz in einem bestimmten Gerät auf einer bestimmten Version auf? Wenn das der Fall ist, dann hat wahrscheinlich der Betriebssystem-Versionscode den Fehler. Aber auf jeden Fall glaube ich nicht, dass Sie etwas dagegen tun. – Henry

0

Das Problem mit einem Gleichzeitigkeits Problem zusammenhängt: da Sie die Palette in der ‚async‘ Art und Weise verwenden, wenn Sie

Palette.Builder(bitmap).generate(new Palette.PaletteAsyncListener() 

aufrufen Ihre Bitmap ist gültig, aber wenn die Palette das Bitmap verwendet in eine eigene asynchrone Logik, kann die Bitmap (wegen einer gleichzeitigen Manipulation) null oder nicht mehr gültig sein.

Es gibt eine einfache Lösung für dieses Problem: da Sie die wichtigsten Farben extrahieren kein hochauflösendes Bild müssen, bietet nur einen low-res-Bitmap aus dem Original erstellt:

if(bitmap == null || bitmap.getHeight() <= 0 || bitmap.getWidth() <= 0){ 
    //do something 
}else{ 
    //This resized bitmap is just an example: you should keep your bitmap 
    //aspect ratio, and keep width and height < 100 
    Bitmap resizedBitmap = Bitmap.createScaledBitmap(myBitmap, 100, 100, false); 
    Palette.Builder(resizedBitmap).generate(new Palette.PaletteAsyncListener() { 
..... 
} 
+0

Interessante Idee, ich werde das versuchen. Vielen Dank. – casolorz

+0

@mntgoat Vergessen Sie nicht, das Seitenverhältnis in der Größe Ihrer Bitmap beizubehalten, oder Sie erhalten möglicherweise falsche Schlüsselfarben (Ich forciere 100x100px in dem Beispiel) – bonnyz

+0

Yeah I am. Der Code, den ich tatsächlich für die Palette-Klasse sehe, verwendet 192 als Minimum. – casolorz