首页 > 解决方案 > MessageQueue 回调中的异常:handleReceiveCallback 洪水填充算法 Android

问题描述

我正在 Android 中创建一个 Unicorn Color 应用程序,用选定的颜色为触摸的白色像素着色。我在下面找到了有关如何从可绘制图像中创建位图并获取触摸区域的点 x、y 方向和 targetColor 以用replacementColor替换它的算法。

这是我的算法代码:

  public void floodFill(Bitmap  image, Point node, int targetColor,
                          int replacementColor) {
        int width = image.getWidth();
        int height = image.getHeight();
        int target = targetColor;
        int replacement = replacementColor;
        if (target != replacement) {
            Queue<Point> queue = new LinkedList<Point>();
            do {
                int x = node.x;
                int y = node.y;
                while (x > 0 && image.getPixel(x - 1, y) == target) {
                    x--;
                }
                boolean spanUp = false;
                boolean spanDown = false;
                while (x < width && image.getPixel(x, y) == target) {
                    image.setPixel(x, y, replacement);
                    if (!spanUp && y > 0 && image.getPixel(x, y - 1) == target) {
                        queue.add(new Point(x, y - 1));
                        spanUp = true;
                    } else if (spanUp && y > 0
                            && image.getPixel(x, y - 1) != target) {
                        spanUp = false;
                    }
                    if (!spanDown && y < height - 1
                            && image.getPixel(x, y + 1) == target) {
                        queue.add(new Point(x, y + 1));
                        spanDown = true;
                    } else if (spanDown && y < height - 1
                            && image.getPixel(x, y + 1) != target) {
                        spanDown = false;
                    }
                    x++;
                }
            } while ((node = queue.poll()) != null);
        }
    }

这是我创建的使用算法的方法

  imageView.setOnTouchListener(new ImageView.OnTouchListener()
        {
            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                final Point p1 = new Point();
//this code I have initialized in the onCreate above but put it here for deceleration
               // bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.unicorn_1);
                int x = (int)event.getX();
                int y = (int)event.getY();
                Point point = new Point();
                point.x = x;
                point.y = y;
                final int sourceColor = bitmap.getPixel((int) x, (int) y);
                FloodFill(bitmap,point,sourceColor,Color.RED);
                return true;
            }
        });

但我收到此错误:

     E/InputEventReceiver: Exception dispatching input event.
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI: java.lang.IllegalStateException
        at android.graphics.Bitmap.setPixel(Bitmap.java:1771)
        at com.example.unicornbookcolor.FastImageTry.FloodFill(FastImageTry.java:86)
        at com.example.unicornbookcolor.FastImageTry.access$200(FastImageTry.java:20)
        at com.example.unicornbookcolor.FastImageTry$3.onTouch(FastImageTry.java:69)
        at android.view.View.dispatchTouchEvent(View.java:11931)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:527)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1875)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3453)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:477)
        at android.view.View.dispatchPointerEvent(View.java:12183)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5510)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5260)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4910)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4967)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7494)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7468)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7425)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7612)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:325)
        at android.os.Looper.loop(Looper.java:159)
        at android.app.ActivityThread.main(ActivityThread.java:7025)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:514)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.unicornbookcolor, PID: 2420
    java.lang.IllegalStateException
        at android.graphics.Bitmap.setPixel(Bitmap.java:1771)
        at com.example.unicornbookcolor.FastImageTry.FloodFill(FastImageTry.java:86)
        at com.example.unicornbookcolor.FastImageTry.access$200(FastImageTry.java:20)
        at com.example.unicornbookcolor.FastImageTry$3.onTouch(FastImageTry.java:69)
        at android.view.View.dispatchTouchEvent(View.java:11931)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3052)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2646)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:527)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1875)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3453)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:477)
        at android.view.View.dispatchPointerEvent(View.java:12183)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5510)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5260)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4910)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4967)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4802)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4761)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4769)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4742)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7494)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7468)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7425)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7612)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:325)
        at android.os.Looper.loop(Looper.java:159)
        at android.app.ActivityThread.main(ActivityThread.java:7025)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:514)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)

如何解决这个问题并通过算法方法获得所需的参数?

标签: javaandroidalgorithm

解决方案


推荐阅读