Canvas without using bitmap takes more memory in Android

送分小仙女□ 提交于 2019-12-24 14:10:08

问题


I have a view where I draw a tree shaped structure using Canvas and Path and it looks like the one given below. The way I draw the tree is a bad coding habit and I am well aware of it but I had to follow this style due to the lack of better way. (I did not try it in OpenGL, I'm a bit afraid to try that). So the steps that takes place in tree are as follows :

  1. Tree is drawn without using any text in it.
  2. As the users are added to the tree, the leaves color gets changed and text is added to it.
  3. Further to this, these leaves should have images rather than plain text which can be achieved by using drawBitmap which will obviously lead me to OOM (Out Of Memory) in the future.

So these are the steps that happens as of now, this takes me at least 3-4 seconds to load the screen when the colored leaf count is less (meaning that there are less users), if there are more users then the loading time exceeds more than 5 seconds and at times, it shows "App not responding" due to more memory consumption.

I have no idea on how to proceed further because showing this screen to the user takes up all the memory and forces my app to close.

So I am completely stuck at this point unable to proceed further and I have invested a great deal of time building this tree so I hope that there should be way to clear the memory and re-build the canvas.

What have I learned so far : Android does not allow to draw a part of the page again, so the whole canvas has to be regenerated again when the page is loaded.

P.S: If there is a way to overcome the memory issue using the existing code then its highly appreciated cause the time wasted has been too much, if at all there is no other way but to destroy this completely and start from scratch then I hope that way will give me exactly what I want.

Tree :

CODE :

 @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);

                    }
                }


            }

        }



    }

回答1:


I saw your code. So you are using a View to draw all the filled circles. The onDraw method is overloaded with calculations and object instantiation. I suggest that you remove as much as you can from onDraw method. If the calculation can be carried out during the construction of the View, then do it in the constructor and not in the onDraw. You need to keep onDraw as light as possible.

Now is this a good design? Having a View in your case is not a good idea, because a single change will redraw the whole view. Instead I suggest that you create a custom ViewGroup, and have all these filled circles as child to that. That way, when a single circle changes in color or text, you don't need to redraw the whole screen.



来源:https://stackoverflow.com/questions/33461000/canvas-without-using-bitmap-takes-more-memory-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!