【问题标题】:Canvas without using bitmap takes more memory in Android不使用位图的画布在Android中占用更多内存
【发布时间】:2023-03-10 11:45:01
【问题描述】:

我有一个视图,我使用 Canvas 和 Path 绘制了一个树形结构,它看起来像下面给出的那个。我画树的方式是一个不好的编码习惯,我很清楚这一点,但由于缺乏更好的方法,我不得不遵循这种风格。 (我没有在 OpenGL 中尝试过,我有点害怕尝试)。所以在树中发生的步骤如下:

  1. 树的绘制不使用任何文本。
  2. 当用户被添加到树中时,叶子的颜色会发生变化并添加文本。
  3. 除此之外,这些叶子应该有图像而不是纯文本,这可以通过使用 drawBitmap 来实现,这显然会导致我将来出现 OOM(Out Of Memory)。

所以这些是目前发生的步骤,当彩色叶子数量较少(意味着用户较少)时,这至少需要 3-4 秒才能加载屏幕,如果用户较多,则加载时间超过 5 秒,有时会显示“应用程序无响应”,因为内存消耗过多。

我不知道如何继续,因为向用户显示此屏幕会占用所有内存并强制我的应用关闭。

所以我完全被困在这一点上,无法继续前进,我已经投入了大量时间来构建这棵树,所以我希望应该有办法清除内存并重新构建画布。

到目前为止我学到了什么: Android 不允许再次绘制页面的一部分,因此在加载页面时必须重新生成整个画布。

附注: 如果有一种方法可以使用现有代码来克服内存问题,那么它的高度赞赏会导致浪费的时间太多,如果除了完全破坏它并从头开始之外别无他法,那么我希望这种方式会给我我想要的。

树:

代码:

 @Override
    public void onDraw(Canvas canv) {



        //gggggggggggg
        for (CircleArea circle : mCircles) {



                if(dbHelper.getRelationTypes().size() > 0)
                {
                    //System.out.println("dbHelper.getRelationTypes().size() > 0");
                    //System.out.println("Inside the Spouse or Father and Mother");
                    CircleCanvas.spouse_added = true;
                    //Couples
                    if(circle.radius==XHDPI_COUPLE_RADIUS_LIMIT)
                    {
                        // System.out.println("if(circle.radius==70)");
                        if(circle.getCenterX() == my_x && circle.getCenterY() == my_y)
                        {
                            dbHelper.insertXYOfRelation("Self", circle.getCenterX(), circle.getCenterY());

                            if(DashboardActivity.profile_image_from_local!=null)
                            {
                                Bitmap resized = Bitmap.createScaledBitmap(DashboardActivity.profile_image_from_local, 200, 200, true);
                                Bitmap result = null;
                                try {
                                    result = Bitmap.createBitmap(200,200, Bitmap.Config.ARGB_8888);
                                    Canvas canvas = new Canvas(result);
                                    int color = 0xff424242;
                                    Paint paint = new Paint();
                                    Rect rect = new Rect(0, 0, 200, 200);
                                    //RectF rectF = new RectF(rect);
                                    paint.setAntiAlias(true);
                                    canvas.drawARGB(0, 0, 0, 0);
                                    paint.setColor(color);
                                    canvas.drawCircle(XHDPI_COUPLE_RADIUS_LIMIT, XHDPI_COUPLE_RADIUS_LIMIT, XHDPI_COUPLE_RADIUS_LIMIT, paint);
                                    //canvas.drawOval(rectF, paint);
                                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                                    canvas.drawBitmap(resized, rect, rect, paint);

                                } catch (NullPointerException e) {
                                } catch (OutOfMemoryError o) {
                                }

                                System.out.println("Inside Me");
                                canv.drawBitmap(result, circle.getCenterX() - result.getWidth() / 3, circle.getCenterY() - result.getHeight() / 3, null);
                            }

                            else  if(DashboardActivity.profile_image!=null)
                            {
                                Bitmap resized = Bitmap.createScaledBitmap(DashboardActivity.profile_image, 200, 200, true);
                                Bitmap result = null;
                                try {
                                    result = Bitmap.createBitmap(200,200, Bitmap.Config.ARGB_8888);
                                    Canvas canvas = new Canvas(result);
                                    int color = 0xff424242;
                                    Paint paint = new Paint();
                                    Rect rect = new Rect(0, 0, 200, 200);
                                    //RectF rectF = new RectF(rect);
                                    paint.setAntiAlias(true);
                                    canvas.drawARGB(0, 0, 0, 0);
                                    paint.setColor(color);
                                    canvas.drawCircle(XHDPI_COUPLE_RADIUS_LIMIT, XHDPI_COUPLE_RADIUS_LIMIT, XHDPI_COUPLE_RADIUS_LIMIT, paint);
                                    //canvas.drawOval(rectF, paint);
                                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                                    canvas.drawBitmap(resized, rect, rect, paint);

                                } catch (NullPointerException e) {
                                } catch (OutOfMemoryError o) {
                                }

                                System.out.println("Inside Me");
                                canv.drawBitmap(result, circle.getCenterX() - result.getWidth() / 3, circle.getCenterY() - result.getHeight() / 3, null);
                            }
                            else
                            {
                                canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_COUPLE_RADIUS_LIMIT, mMarriedPaint);
                                canv.drawText(dbHelper.getNameOfRelation("Self"), circle.getCenterX() - 34, circle.getCenterY(), mXHDPICoupleTextPaint);
                                Log.e("Ondraw Self", "Ondraw Self");
                            }


                        }
                        else
                        {
                            if(dbHelper.getWhatRelationTypes("Spouse"))
                            {
                               // System.out.println("Inside Spouse");
                                dbHelper.insertXYOfRelation("Spouse",circle.getCenterX(),circle.getCenterY());
                                Log.e("Spouseeeeeeee ", "" + circle.getCenterX() + " " + circle.getCenterY() + dbHelper.insertXYOfRelation("Spouse", circle.getCenterX(), circle.getCenterY()));
                                canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_COUPLE_RADIUS_LIMIT, mMarriedPaint);
                                canv.drawText(dbHelper.getNameOfRelation("Spouse"), circle.getCenterX() - 34, circle.getCenterY(), mXHDPICoupleTextPaint);
                            }
                            else
                            {
                                canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_COUPLE_RADIUS_LIMIT, mFilledPaint);
                                Log.e("Ondraw Spouse", "Ondraw Spouse");
                            }


                        }
                    }

                    //Parents
                    if(circle.radius==XHDPI_PARENTS_RADIUS_LIMIT)
                    {

                       // System.out.println("if(circle.radius==55)");
                        if(circle.getCenterX() == father_x && circle.getCenterY() == father_y)
                        {

                            if(dbHelper.getWhatRelationTypes("Father"))
                            {
                                dbHelper.insertXYOfRelation("Father", circle.getCenterX(), circle.getCenterY());
                              //  System.out.println("Inside Father" + "X : " + dbHelper.getXOfRelation("Father") + " Y: " +dbHelper.getYOfRelation("Father"));
                                    canv.drawCircle(dbHelper.getXOfRelation("Father"),dbHelper.getYOfRelation("Father"), XHDPI_PARENTS_RADIUS_LIMIT, mMarriedPaint);
                                    canv.drawText(dbHelper.getNameOfRelation("Father"), circle.getCenterX() - 22, circle.getCenterY(), mXHDPIParentsTextPaint);
                            }
                            else
                            {
                                canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_PARENTS_RADIUS_LIMIT, mFilledPaint);
                                Log.e("Ondraw Father", "Ondraw Father");
                            }
                        }else if(circle.getCenterX() == mother_x && circle.getCenterY() == mother_y)
                        {
                            if(dbHelper.getWhatRelationTypes("Mother"))
                            {
                               // System.out.println("Inside Mother");
                                dbHelper.insertXYOfRelation("Mother", circle.getCenterX(), circle.getCenterY());
                                canv.drawCircle(dbHelper.getXOfRelation("Mother"), dbHelper.getYOfRelation("Mother"), XHDPI_PARENTS_RADIUS_LIMIT, mMarriedPaint);
                                canv.drawText(dbHelper.getNameOfRelation("Mother"), circle.getCenterX() - 22, circle.getCenterY(), mXHDPIParentsTextPaint);
                            }
                            else
                            {
                                canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_PARENTS_RADIUS_LIMIT, mFilledPaint);
                                Log.e("Ondraw Mother", "Ondraw Mother");
                            }
                        }else if(circle.getCenterX() == spouse_father_x && circle.getCenterY() == spouse_father_y)
                        {
                            if(dbHelper.getWhatRelationTypes("Spouses Father"))
                            {
                               // System.out.println("Inside Spouses Father");
                                dbHelper.insertXYOfRelation("Spouses Father", circle.getCenterX(), circle.getCenterY());
                                canv.drawCircle(dbHelper.getXOfRelation("Spouses Father"), dbHelper.getYOfRelation("Spouses Father"), XHDPI_PARENTS_RADIUS_LIMIT, mMarriedPaint);
                                canv.drawText(dbHelper.getNameOfRelation("Spouses Father"), circle.getCenterX() - 22, circle.getCenterY(), mXHDPIParentsTextPaint);
                            }
                            else
                            {
                                canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_PARENTS_RADIUS_LIMIT, mFilledPaint);
                                Log.e("Ondraw Spouses Father", "Ondraw Spouses Father");
                            }
                        }else if(circle.getCenterX() == spouse_mother_x && circle.getCenterY() == spouse_mother_y)
                        {
                            if(dbHelper.getWhatRelationTypes("Spouses Mother"))
                            {
                                dbHelper.insertXYOfRelation("Spouses Mother", circle.getCenterX(), circle.getCenterY());
                                canv.drawCircle(dbHelper.getXOfRelation("Spouses Mother"), dbHelper.getYOfRelation("Spouses Mother"), XHDPI_PARENTS_RADIUS_LIMIT, mMarriedPaint);
                                canv.drawText(dbHelper.getNameOfRelation("Spouses Mother"), circle.getCenterX() - 22, circle.getCenterY(), mXHDPIParentsTextPaint);
                            }
                            else
                            {
                                canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_PARENTS_RADIUS_LIMIT, mFilledPaint);
                                Log.e("Ondraw Spouses Mother", "Ondraw Spouses Mother");
                            }
                        }

                    }



                   //Childrens
                    if (circle.radius == XHDPI_CHILD_RADIUS_LIMIT) {

                        if (dbHelper.FetchChildFriendCountFromUserTable("Child").size() > 0) {

                            child_x.clear();
                            child_y.clear();

                            child_x.add(c1_x);
                            child_x.add(c2_x);
                            child_x.add(c3_x);
                            child_x.add(c4_x);
                            child_x.add(c5_x);

                            child_y.add(c1_y);
                            child_y.add(c2_y);
                            child_y.add(c3_y);
                            child_y.add(c4_y);
                            child_y.add(c5_y);


                            for (int r = 0; r < dbHelper.FetchChildFriendCountFromUserTable("Child").size(); r++) {


                                if(dbHelper.FetchChildFriendCountFromUserTable("Child").get(r).equalsIgnoreCase("Child1"))
                                {

                                    new_c_x = c1_x;
                                    new_c_y = c1_y;

                                    dbHelper.insertChildOriginalXY("Child1", new_c_x, new_c_y);
                                    dbHelper.insertXYOfRelation("Child1", new_c_x, new_c_y);

                                    child_x.remove(new Integer(c1_x));
                                    child_y.remove(new Integer(c1_y));

                                    canv.drawCircle(dbHelper.getXOfRelation("Child1"), dbHelper.getYOfRelation("Child1"), XHDPI_DRAWN_CHILD_RADIUS_LIMIT, mChildFilledPaint);
                                    canv.drawText(dbHelper.getNameOfRelation("Child1"), dbHelper.getXOfRelation("Child1") - 14, dbHelper.getYOfRelation("Child1"), mXHDPIChildTextPaint);

                                }else  if(dbHelper.FetchChildFriendCountFromUserTable("Child").get(r).equalsIgnoreCase("Child2"))
                                {

                                    new_c_x = c2_x;
                                    new_c_y = c2_y;

                                    child_x.remove(new Integer(c2_x));
                                    child_y.remove(new Integer(c2_y));

                                    dbHelper.insertChildOriginalXY("Child2", new_c_x, new_c_y);
                                    dbHelper.insertXYOfRelation("Child2", new_c_x, new_c_y);
                                    canv.drawCircle(dbHelper.getXOfRelation("Child2"), dbHelper.getYOfRelation("Child2"), XHDPI_DRAWN_CHILD_RADIUS_LIMIT, mChildFilledPaint);
                                    canv.drawText(dbHelper.getNameOfRelation("Child2"), dbHelper.getXOfRelation("Child2") - 14, dbHelper.getYOfRelation("Child2"), mXHDPIChildTextPaint);
                                }else   if(dbHelper.FetchChildFriendCountFromUserTable("Child").get(r).equalsIgnoreCase("Child3"))
                                {

                                    new_c_x = c3_x;
                                    new_c_y = c3_y;


                                    child_x.remove(new Integer(c3_x));
                                    child_y.remove(new Integer(c3_y));


                                    dbHelper.insertChildOriginalXY("Child3", new_c_x, new_c_y);
                                    dbHelper.insertXYOfRelation("Child3", new_c_x, new_c_y);
                                    canv.drawCircle(dbHelper.getXOfRelation("Child3"), dbHelper.getYOfRelation("Child3"), XHDPI_DRAWN_CHILD_RADIUS_LIMIT, mChildFilledPaint);
                                    canv.drawText(dbHelper.getNameOfRelation("Child3"), dbHelper.getXOfRelation("Child3") - 14, dbHelper.getYOfRelation("Child3"), mXHDPIChildTextPaint);
                                }else   if(dbHelper.FetchChildFriendCountFromUserTable("Child").get(r).equalsIgnoreCase("Child4"))
                                {

                                    new_c_x = c4_x;
                                    new_c_y = c4_y;


                                    child_x.remove(new Integer(c4_x));
                                    child_y.remove(new Integer(c4_y));


                                    dbHelper.insertChildOriginalXY("Child4", new_c_x, new_c_y);
                                    dbHelper.insertXYOfRelation("Child4", new_c_x, new_c_y);
                                    canv.drawCircle(dbHelper.getXOfRelation("Child4"), dbHelper.getYOfRelation("Child4"), XHDPI_DRAWN_CHILD_RADIUS_LIMIT, mChildFilledPaint);
                                    canv.drawText(dbHelper.getNameOfRelation("Child4"), dbHelper.getXOfRelation("Child4") - 14, dbHelper.getYOfRelation("Child4"), mXHDPIChildTextPaint);
                                }else  if(dbHelper.FetchChildFriendCountFromUserTable("Child").get(r).equalsIgnoreCase("Child5"))
                                {

                                    new_c_x = c5_x;
                                    new_c_y = c5_y;


                                    child_x.remove(new Integer(c5_x));
                                    child_y.remove(new Integer(c5_y));

                                    dbHelper.insertChildOriginalXY("Child5", new_c_x, new_c_y);
                                    dbHelper.insertXYOfRelation("Child5", new_c_x, new_c_y);
                                    canv.drawCircle(dbHelper.getXOfRelation("Child5"), dbHelper.getYOfRelation("Child5"), XHDPI_DRAWN_CHILD_RADIUS_LIMIT, mChildFilledPaint);
                                    canv.drawText(dbHelper.getNameOfRelation("Child5"), dbHelper.getXOfRelation("Child5") - 14, dbHelper.getYOfRelation("Child5"), mXHDPIChildTextPaint);
                                }


                            }
                            if(child_x.size()!=0)
                            {
                                for(int i=0;i<child_x.size();i++)
                                {
                                    canv.drawCircle(child_x.get(i),child_y.get(i),XHDPI_CHILD_RADIUS_LIMIT,mCirclePaint);
                                }

                            }


                        } else {

                            canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_CHILD_RADIUS_LIMIT, mCirclePaint);

                        }
                    }

                    //Friends
                    if (circle.radius==FRIENDS_RADIUS_LIMIT)
                    {
                        //tujomila
                        if(dbHelper.FetchChildFriendCountFromUserTable("Friend").size() > 0)
                        {

                           // Log.e("","The friend list size is " + dbHelper.getFriendRelationTypes().size());
                           // Log.e("","The size of circlepointers is " + circle_pointers);

                            for (int q=1;q<=dbHelper.FetchChildFriendCountFromUserTable("Friend").size();q++)
                            {
                                //Log.e("","The X of friend" + q + " is " + dbHelper.getFriendCorrespondingXValue(q,"Married")) ;
                                //Log.e("","The Y of friend" + q + " is " + dbHelper.getFriendCorrespondingYValue(q,"Married")) ;

                                canv.drawCircle(dbHelper.getFriendCorrespondingXValue(q,"Married"),dbHelper.getFriendCorrespondingYValue(q,"Married"),FRIENDS_RADIUS_LIMIT,mChildFilledPaint);
                                canv.drawText(dbHelper.getNameOfRelation("Friend" + q), dbHelper.getXOfRelation("Friend" + q) - 17, dbHelper.getYOfRelation("Friend"+q), mXHDPIFriendTextPaint);
                                dbHelper.insertXYOfRelation("Friend" + q, dbHelper.getFriendCorrespondingXValue(q,"Married"), dbHelper.getFriendCorrespondingYValue(q,"Married"));
                                friend_x.add(dbHelper.getFriendCorrespondingXValue(q,"Married"));
                                friend_y.add(dbHelper.getFriendCorrespondingYValue(q,"Married"));

                            }
                            for(int w=dbHelper.FetchChildFriendCountFromUserTable("Friend").size()+ 1;w<=34;w++) {

                               // Log.e("Pointer is " + w,"The X value at w is " + dbHelper.getFriendCorrespondingXValue(w,"Married") + " The Y value at w is " + dbHelper.getFriendCorrespondingYValue(w,"Married"));
                                canv.drawCircle(dbHelper.getFriendCorrespondingXValue(w,"Married"),dbHelper.getFriendCorrespondingYValue(w,"Married"), FRIENDS_RADIUS_LIMIT, mCirclePaint);
                            }

                        }
                        else
                        {
                            canv.drawCircle(circle.getCenterX(), circle.getCenterY(), FRIENDS_RADIUS_LIMIT, mCirclePaint);
                        }
                    }
                }
                else
                {

                    //System.out.println("Else of CircleCanvas.member_type!=null");
                    if (circle.radius == FRIENDS_RADIUS_LIMIT) {
                        canv.drawCircle(circle.getCenterX(), circle.getCenterY(), FRIENDS_RADIUS_LIMIT, mCirclePaint);
                    }else if (circle.radius == XHDPI_CHILD_RADIUS_LIMIT) {
                    canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_CHILD_RADIUS_LIMIT, mCirclePaint);
                    } else if (circle.radius == XHDPI_PARENTS_RADIUS_LIMIT) {
                        canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_PARENTS_RADIUS_LIMIT, mFilledPaint);
                    } else {
                        canv.drawCircle(circle.getCenterX(), circle.getCenterY(), XHDPI_COUPLE_RADIUS_LIMIT, mMarriedPaint);

                    }
                }


            }

        }



    }

【问题讨论】:

    标签: android bitmap android-canvas


    【解决方案1】:

    我看到了你的代码。因此,您使用View 来绘制所有实心圆圈。 onDraw 方法重载了计算和对象实例化。我建议您从onDraw 方法中尽可能多地删除。如果可以在View的构建过程中进行计算,那么在构造函数中进行而不是在onDraw中进行。你需要让onDraw 尽可能轻。

    现在这是一个好的设计吗?在您的情况下使用View 不是一个好主意,因为单个更改将重绘整个视图。相反,我建议您创建一个自定义ViewGroup,并将所有这些filled circles 作为其子级。这样,当单个圆圈的颜色或文字发生变化时,您无需重新绘制整个屏幕。

    【讨论】:

    • 我的整个画布是一个视图,所以使用 ViewGroup 意味着我在它下面有多个视图并且再次只绘制已编辑的圆圈?我已经编辑了问题中的代码,以便给出一个清晰的想法,它有点简单。
    • 是的。但是在您的onDraw 中,您正在创建这么多bitmap 对象。这很糟糕。而是通过onDraw 中提供的画布使用视图的底层位图。不要使用drawBitmap,而是使用drawCircledrawPath。长期解决方案是使用ViewGroup,而不是在单个View 中完成所有操作。
    • 但是我用drawBitmap给圆添加图片,基本上我用的都是drawCircle和drawPath。您能否为我提供一个继续使用 ViewGroup 的示例,因为我使用的 ViewGroup 不多?
    • Refer this:javatechig.com/android/…ViewGroup 中,您所要做的就是将您的子视图排列在您想要的位置。这是在onLayout 方法中完成的。覆盖它以将您的所有子视图(实心圆圈)放置在您想要的位置。
    • 谢谢亨利,我去看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    相关资源
    最近更新 更多