java.lang.IllegalArgumentException:width和height必须是>设置位图时为0

时间:2013-12-05 12:52:08

标签: android

我在设备Galaxy Nexus(maguro),Nexus 4(mako),Nexus 7(flo),Xperia Z(C6603)上遇到以下错误,但我的设备Note2 4.1.1工作正常。我正在做的是使用Visualizer和我的声音文件向用户显示来自其音频文件的酷炫图形反馈。

我在我的应用中使用com.pheelicks.visualizer,它在我的设备上运行正常,但它已经为我的一些用户崩溃了。这对我来说很难测试,因为我没有新设备,但如果有人能够确认我为什么会收到错误,我会非常感激!我注意到它是否与它有关,但我也从视图的可见性开始,以view.GONE,然后在时间正确时将其设置为可见,然后开始动画。我将在下面包含此代码,以防万一出现问题。

java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:695)
at android.graphics.Bitmap.createBitmap(Bitmap.java:674)
at android.graphics.Bitmap.createBitmap(Bitmap.java:641)
at com.pheelicks.visualizer.VisualizerView.onDraw(VisualizerView.java:193)
at android.view.View.draw(View.java:13944)
at android.view.View.getDisplayList(View.java:12838)
at android.view.View.getDisplayList(View.java:12880)
at android.view.View.draw(View.java:13657)
at android.view.ViewGroup.drawChild(ViewGroup.java:3083)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2920)
at android.view.View.draw(View.java:13947)
at android.view.View.getDisplayList(View.java:12838)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1411)
at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1359)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2367)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2239)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1872)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

供参考,这里是客户VisualizerView

 public class VisualizerView extends View {
 private static final String TAG = "VisualizerView";
 private boolean isLinked = false;
 private byte[] mBytes;
 private byte[] mFFTBytes;
 private Rect mRect = new Rect();
 private Visualizer mVisualizer;

 private Set<Renderer> mRenderers;

 private Paint mFlashPaint = new Paint();
 private Paint mFadePaint = new Paint();

 public VisualizerView(Context context, AttributeSet attrs, int defStyle)
 {
  super(context, attrs);
  init();
 }

 public VisualizerView(Context context, AttributeSet attrs)
 {
   this(context, attrs, 0);
 }

 public VisualizerView(Context context)
 {
   this(context, null, 0);
 }

 private void init() {
   mBytes = null;
   mFFTBytes = null;

   mFlashPaint.setColor(Color.argb(122, 255, 255, 255));
   mFadePaint.setColor(Color.argb(150, 255, 255, 255)); // Adjust alpha to change how quickly the image fades
   mFadePaint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));

   mRenderers = new HashSet<Renderer>();
 }
 /**
  * Links the visualizer to a player
  * @param player - MediaPlayer instance to link to
  */
 public void link(MediaPlayer player)
 {
   if(player == null)
   {
    throw new NullPointerException("Cannot link to null MediaPlayer");
   }

   // Create the Visualizer object and attach it to our media player.
   mVisualizer = new Visualizer(player.getAudioSessionId());
   mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);

   // Pass through Visualizer data to VisualizerView
   Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener()
   {
     @Override
     public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
         int samplingRate)
     {
       updateVisualizer(bytes);
     }

     @Override
     public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
      int samplingRate)
     {
      updateVisualizerFFT(bytes);
     }
   };

   mVisualizer.setDataCaptureListener(captureListener,
       Visualizer.getMaxCaptureRate() / 2, true, true);

    // Enabled Visualizer and disable when we're done with the stream
   mVisualizer.setEnabled(true);
   player.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
   {
     @Override
     public void onCompletion(MediaPlayer mediaPlayer)
     {
      mVisualizer.setEnabled(false);
    }
   });

   this.setLinked(true);
  }

 public void addRenderer(Renderer renderer)
 {
   if(renderer != null)
   {
    mRenderers.add(renderer);
   }
 }

 public void clearRenderers()
 {
   mRenderers.clear();
 }

 /**
  * Call to release the resources used by VisualizerView. Like with the
  * MediaPlayer it is good practice to call this method
  */
 public void release()
 {
   mVisualizer.release();
   this.setLinked(false);
 }
 /**
   * Pass data to the visualizer. Typically this will be obtained from the
   * Android Visualizer.OnDataCaptureListener call back. See
   * {@link Visualizer.OnDataCaptureListener#onWaveFormDataCapture }
   * @param bytes
   */
 public void updateVisualizer(byte[] bytes) {
   mBytes = bytes;
   invalidate();
 }

  /**
  * Pass FFT data to the visualizer. Typically this will be obtained from the
  * Android Visualizer.OnDataCaptureListener call back. See
  * {@link Visualizer.OnDataCaptureListener#onFftDataCapture }
  * @param bytes
  */
  public void updateVisualizerFFT(byte[] bytes) {
    mFFTBytes = bytes;
    invalidate();
   }

    boolean mFlash = false;

  /**
  * Call this to make the visualizer flash. Useful for flashing at the start
  * of a song/loop etc...
  */
  public void flash() {
    mFlash = true;
    invalidate();
  }

    Bitmap mCanvasBitmap;
     Canvas mCanvas;


  @Override
  protected void onDraw(Canvas canvas) {
   super.onDraw(canvas);

   // Create canvas once we're ready to draw
   mRect.set(0, 0, getWidth(), getHeight());  

   if(mCanvasBitmap == null)
   {
     mCanvasBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888); // THIS IS WHERE THE ERROR IS OCCURRING
   }
   if(mCanvas == null)
   {
     mCanvas = new Canvas(mCanvasBitmap);
   }

   if (mBytes != null) {
     // Render all audio renderers
     AudioData audioData = new AudioData(mBytes);
     for(Renderer r : mRenderers)
     {
       r.render(mCanvas, audioData, mRect);
     }
   }

   if (mFFTBytes != null) {
     // Render all FFT renderers
     FFTData fftData = new FFTData(mFFTBytes);
     for(Renderer r : mRenderers)
     {
       r.render(mCanvas, fftData, mRect);
     }
   }

   // Fade out old contents
   mCanvas.drawPaint(mFadePaint);

   if(mFlash)
   {
     mFlash = false;
     mCanvas.drawPaint(mFlashPaint);
   }

   canvas.drawBitmap(mCanvasBitmap, new Matrix(), null);
 }

 public boolean isLinked() {
  return isLinked;
  }

 private void setLinked(boolean isLinked) {
this.isLinked = isLinked;
  }
}

活动中的OnCreate(visualizer_container里面有visualizerView)

this.visualizer_container = (RelativeLayout) findViewById(R.id.visualizer_layout);
this.visualizer_container.setVisibility(View.GONE);

活动后期

sAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom);
            sAnimation.setInterpolator(new AccelerateInterpolator());
            sAnimation.setStartOffset(400);
            sAnimation.setDuration(1000);


            this.mVisualizerView.setAnimation(sAnimation);

2 个答案:

答案 0 :(得分:1)

您在代码中的注释是错误的,这是失败的行(在堆栈跟踪中,您可以看到下一个调用是Bitmap.createBitmap()):

mCanvasBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888);

问题是canvas.getWidth()或canvas.getHeight()或两者都返回0.这是不允许的。反过来,这是由您在注释中指示的行引起的,其中getWidth()/ getHeight()返回0.

我会添加一个打印这些的日志语句,这样你就可以看到它是否只是第一次发生,或者总是发生。如果它仅在第一次发生时,您可以忽略它(例如,检查宽度和高度是否> 0)。

更新:考虑到你最终必须绘制到画布,为什么不使用画布的宽度和高度?

mRect.set(0, 0, canvas.getWidth(), canvas.getHeight());  

答案 1 :(得分:-3)

将Crashlytics添加到您的代码中,以便能够跟踪用户设备上的错误。 http://www.crashlytics.com/blog/its-finally-here-announcing-crashlytics-for-android/