传入的通知使我的应用程序 Android 崩溃

Posted

技术标签:

【中文标题】传入的通知使我的应用程序 Android 崩溃【英文标题】:Incoming notifications are crashing my app Android 【发布时间】:2019-01-23 21:38:48 【问题描述】:

使用我的 android 应用程序时,一切正常,但只要我收到传入通知(来自其他应用程序),我的应用程序就会重新启动。 只有当我的相机处于活动状态并且在此期间我也在画布视图上绘图时,它才会这样做。

据我了解,在某些过程(例如录制)期间无法禁用通知,因此我需要以某种方式修复它,但我得到的唯一错误日志如下:

   --------- beginning of crash
2019-01-23 23:33:59.712 7469-7469/com.myApp.com E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myApp.com, PID: 7469
    java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@cafcfb0
        at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1271)
        at android.graphics.Canvas.drawBitmap(Canvas.java:1368)
        at android.graphics.Bitmap.createBitmap(Bitmap.java:973)
        at com.author.myApp.Songplayer.Managers.CanvasDraw.getResizedBitmap(CanvasDraw.java:53)
        at com.author.myApp.Songplayer.Managers.CanvasDraw.onDraw(CanvasDraw.java:38)
        at android.view.View.draw(View.java:17236)
        at android.view.View.updateDisplayListIfDirty(View.java:16201)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.support.design.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1254)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.updateDisplayListIfDirty(View.java:16196)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.updateDisplayListIfDirty(View.java:16196)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.updateDisplayListIfDirty(View.java:16196)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.draw(View.java:17239)
        at android.view.View.updateDisplayListIfDirty(View.java:16201)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.draw(View.java:17239)
        at android.view.View.updateDisplayListIfDirty(View.java:16201)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.updateDisplayListIfDirty(View.java:16196)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.updateDisplayListIfDirty(View.java:16196)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.updateDisplayListIfDirty(View.java:16196)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.updateDisplayListIfDirty(View.java:16196)
        at android.view.View.draw(View.java:17002)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3777)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3560)
        at android.view.View.draw(View.java:17239)
        at com.android.internal.policy.DecorView.draw(DecorView.java:801)
        at android.view.View.updateDisplayListIfDirty(View.java:16201)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:677)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:683)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:797)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2991)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2785)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2376)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1366)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6768)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:926)
        at android.view.Choreographer.doCallbacks(Choreographer.java:735)
        at android.view.Choreographer.doFrame(Choreographer.java:667)
2019-01-23 23:33:59.712 7469-7469/com.myApp.com E/AndroidRuntime:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:912)
        at android.os.Handler.handleCallback(Handler.java:761)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6523)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
2019-01-23 23:33:59.742 542-8728/? I/ImagingSystem: virtual TRetCode hw::CIMX219Spec::getOTPTestResult(): OTP module_id=0xc8,vendor_id=0x31,checksum=0x1
2019-01-23 23:33:59.746 542-8714/? I/ProjectName: Tornado: mrc_cv_ColorSaturationDetectionTOA:UISaturationLevel:0,saturationCompValid:0,outPutSaturationComp:256.
2019-01-23 23:33:59.775 542-8728/? I/ImagingSystem: virtual TRetCode hw::CIMX219Spec::getOTPTestResult(): OTP module_id=0xc8,vendor_id=0x31,checksum=0x1
2019-01-23 23:33:59.779 542-8714/? I/ProjectName: Tornado: mrc_cv_ColorSaturationDetectionTOA:UISaturationLevel:0,saturationCompValid:0,outPutSaturationComp:256.
2019-01-23 23:33:59.802 1218-4278/? E/ReportTools: This is not beta user build

这基本上什么也没告诉我……只是它在通知后找不到画布。

我不确定我应该做什么。当我检查 Android 的相机是如何做到的时,他们会禁用声音和振动,所以也许这对我有帮助?如果是,那么我已经搜索了很长时间,但没有找到一种方法来禁用其他通知的振动/声音。

编辑

添加onDraw 类:

public class CanvasDraw extends View

    Bitmap voiceMeterChart;
    Paint linePaint = new Paint();

    public CanvasDraw(Context context) 
        super(context);
        voiceMeterChart = BitmapFactory.decodeResource(getResources(), R.drawable.voice_chart_meter);
        voiceMeterChart = adjustOpacity(voiceMeterChart, 125);


        linePaint.setColor(Color.RED);
        linePaint.setStrokeWidth(1);
    

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

        int canvasWidth = canvas.getWidth();
        int canvasHeight = canvas.getHeight();


        canvas.drawBitmap(getResizedBitmap(voiceMeterChart, (canvasWidth * 0.1), canvasHeight, canvasWidth), 25, 0, null);

    

    public Bitmap getResizedBitmap(Bitmap bm, double newWidth, int newHeight, int canvasWidth) 
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(
                bm, 0, 0, width, height, matrix, false);
        bm.recycle();
        return resizedBitmap;
    

    private Bitmap adjustOpacity(Bitmap bitmap, int opacity)
    
        Bitmap mutableBitmap = bitmap.isMutable()
                ? bitmap
                : bitmap.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(mutableBitmap);
        int colour = (opacity & 0xFF) << 24;
        canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
        return mutableBitmap;
    

在日志中显示它在这一行崩溃:

 Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);

【问题讨论】:

"我也在画布视图上绘图" - 显示此代码肯定是相关的,因为堆栈跟踪与在画布上绘制这一行有关 --> com.author.myApp.Songplayer.Managers.CanvasDraw.getResizedBitmap(CanvasDraw.java:53),所以堆栈跟踪确实告诉你很多?我希望通知只会触发重绘(副作用),如果你只是拉 dpwn 通知托盘,这可能会发生。 添加了代码部分 我还没有清理那部分,但目前不需要调整大小是的,但是为什么它只在弹出通知时崩溃,而在没有通知时不会崩溃。 【参考方案1】:

第一个onDraw 调用会回收getResizedBitmap 中的voiceMeterChart 位图。

// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
        bm, 0, 0, width, height, matrix, false);
bm.recycle();

当再次调用onDraw 时,它会尝试使用原始位图创建另一个位图,但它不再存在。

【讨论】:

是的,正确,我在调整大小时错了(但可能发生),原始实例立即被回收! 干得好伙伴:) 这实际上是问题所在,谢谢。当我删除调整大小时,它不再崩溃。即使需要调整大小,我现在也可以修复它,因为我知道问题出在哪里。再次感谢您。

以上是关于传入的通知使我的应用程序 Android 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

更改为横向会使我的 Android 应用程序崩溃

使用浮动使我的应用程序在 Android 中崩溃

android studio中片段内的RecyclerView使我的应用程序崩溃

RemoteServiceException 在 MIUI 11 上使我的应用程序崩溃

为啥我的 ListView 使我的应用程序崩溃而不是列出我的条目?

Thread.sleep 不会使我的应用程序崩溃[关闭]