2015-09-28 1 views
6

У меня есть код с использованием нового класса Palette, и я получаю эти отчеты о сбоях на Crashlytics, говоря, что width and height must be > 0. Что странно, что это, как я называю код палитры:android.support.v7.graphics.Palette width и height должны быть> 0

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

Так что я просто не знаю, как это возможно, что растровое все вдруг не имеет правильную ширину или высоту. Я не знаю, в какой части моего кода возникает исключение, потому что отчет включает только материал внутри класса палитры.

Вот исключение:

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) 

Я использую класс Palette от com.android.support:palette-v7:23+

Любые идеи о том, что может быть не так?

+0

являетесь вы действительно уверен, что растровое изображение что-то или даже показывает? палитра должна проанализировать изображение и несколько минут спустя, вы получите цвет. –

+0

Ну, я только получаю ошибки над Crashlytics, никогда со мной не происходит. Но я проверяю нуль и размер перед вызовом кода палитры. – casolorz

+0

приложение никогда не падает? вы могли бы воссоздать проблему? если нет ... возможно, у некоторых пользователей есть смартфон с низким уровнем конца, и задача заняла слишком много времени, а палитра находила нулевые значения (сбой по палитре и не над растровым изображением) –

ответ

0

Возможно, вы пытаетесь получить доступ к ширине и высоте элемента пользовательского интерфейса, прежде чем он будет добавлен в макет.

Именно поэтому вы получили ширину и высоту, равную 0, так как элемент на самом деле отсутствует.

Используйте 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; 
       } 
      }); 

где myView будет ваш растровый

+0

Я не пытаюсь получить к нему доступ, класс «Палитра». И я проверяю ширину и высоту и null до вызова класса «Палитра». Я не могу изменить код «Палитра», так как я могу убедиться, что этого не происходит? – casolorz

+0

Вызовите класс Palette внутри TreeObserver. Таким образом, битмап определяется до того, как класс палитры попытается получить к нему доступ. –

+0

На самом деле у меня нет представлений, на которые загружены эти растровые изображения, прежде чем вызывать код палитры. Я загружаю их в представления после того, как я знаю цвет палитры. Это работает отлично для большинства моих пользователей, только получая 4 или 5 сбоев в день из ежедневных пользователей 20k. – casolorz

0

Я не думаю, что ваш код не имеет никаких проблем. Я смотрел на StackTrace, который вы разместили.

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

Если вы посмотрите на исходный код Palette.java, вы найдете масштабирования логики написанный в методе scaleBitmapDown(Bitmap bitmap). Если ваше «растровое изображение» меньше 100 пикселей, то масштабирование не выполняется. Однако, если ваше «растровое изображение» больше 100 пикселей, вызывается Bitmap.createScaledBitmap(). Теперь этот метод выдает IllegalArgumentException, если ширина или высота < 0;

Таким образом, битмап, который вы передаете, не имеет нулевой ширины, потому что если бы это было так, вы бы никогда не достигли метода Bitmap.createScaledBitmap(). При этом я не знаю, какова может быть настоящая причина. Попробуйте использовать исходный код точного Palette.java, который вы используете.

+0

Код для палитры, который Android Studio дает мне, когда я нажимаю на вставленную стеклу, немного отличается, но у нее есть те же проверки, что и вы. Я думаю, что если что-то случится с растровым изображением между проверкой и масштабированием, будет единственной возможностью. – casolorz

+0

Мое предположение тоже. Является ли авария на каком-либо конкретном устройстве в конкретной версии? Если это так, то, вероятно, код версии ОС имеет ошибку. Но в любом случае я не думаю, что вы что-то делаете. – Henry

0

Проблема связана с вопросом параллелизма: так как вы используете Palette в пути «асинхронной», при вызове

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

ваших растровый действителен, но когда Palette использует растровое изображение его собственная асинхронная логика, битмап может быть нулевым или недействительным больше (из-за одновременной манипуляции).

Там легко исправить эту проблему: так как вы не нужно с высоким разрешением изображения, чтобы извлечь основные цвета, просто обеспечивает низкое разрешение растрового изображения, созданное из оригинального одного:

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

Интересная идея, я попробую это. Благодарю. – casolorz

+0

@mntgoat Не забудьте сохранить пропорции в вашем растровом изображении с измененным размером, или вы можете получить неправильные цвета клавиш (в примере я заставляю 100x100px) – bonnyz

+0

Да, я. Код, который я действительно вижу для класса Palette, использует 192 как минимум. – casolorz

Смежные вопросы