Skip to content

Commit 2da0064

Browse files
authored
perf(android): reduce java object creation (#10129)
1 parent ee92512 commit 2da0064

File tree

3 files changed

+185
-40
lines changed

3 files changed

+185
-40
lines changed
5 KB
Binary file not shown.

packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/BorderDrawable.java

Lines changed: 105 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import android.graphics.Shader;
1818
import android.graphics.drawable.ColorDrawable;
1919
import android.graphics.drawable.Drawable;
20+
import android.os.Build;
2021

2122
import androidx.annotation.NonNull;
2223

@@ -276,6 +277,44 @@ public void refresh(int borderTopColor,
276277
}
277278
}
278279

280+
281+
RectF backgroundBoundsF = new RectF();
282+
Path backgroundPath = new Path();
283+
RectF backgroundRect = new RectF();
284+
Paint backgroundColorPaint = new Paint();
285+
Path backgroundNoRepeatPath = new Path();
286+
Paint backgroundImagePaint = new Paint();
287+
Paint backgroundGradientPaint = new Paint();
288+
Paint borderPaint = new Paint();
289+
Path borderPath = new Path();
290+
RectF borderOuterRect = new RectF();
291+
RectF borderInnerRect = new RectF();
292+
293+
PointF lto = new PointF(); // left-top-outside
294+
PointF lti = new PointF(); // left-top-inside
295+
296+
PointF rto = new PointF(); // right-top-outside
297+
PointF rti = new PointF(); // right-top-outside
298+
299+
PointF rbo = new PointF(); // right-bottom-outside
300+
PointF rbi = new PointF(); // right-bottom-inside
301+
302+
PointF lbo = new PointF(); // left-bottom-outside
303+
PointF lbi = new PointF(); // left-bottom-inside
304+
305+
306+
Paint topBorderPaint = new Paint();
307+
Path topBorderPath = new Path();
308+
309+
Paint rightBorderPaint = new Paint();
310+
Path rightBorderPath = new Path();
311+
312+
Paint bottomBorderPaint = new Paint();
313+
Path bottomBorderPath = new Path();
314+
315+
Paint leftBorderPaint = new Paint();
316+
Path leftBorderPath = new Path();
317+
279318
@Override
280319
public void draw(Canvas canvas) {
281320
Rect bounds = this.getBounds();
@@ -287,7 +326,7 @@ public void draw(Canvas canvas) {
287326
return;
288327
}
289328

290-
RectF backgroundBoundsF = new RectF(bounds.left, bounds.top, bounds.right, bounds.bottom);
329+
backgroundBoundsF.set(bounds.left, bounds.top, bounds.right, bounds.bottom);
291330

292331
float topBackoffAntialias = calculateBackoffAntialias(this.borderTopColor, this.borderTopWidth);
293332
float rightBackoffAntialias = calculateBackoffAntialias(this.borderRightColor, this.borderRightWidth);
@@ -301,18 +340,18 @@ public void draw(Canvas canvas) {
301340
Math.max(0, borderBottomLeftRadius + leftBackoffAntialias), Math.max(0, borderBottomLeftRadius + bottomBackoffAntialias)
302341
};
303342

304-
Path backgroundPath = new Path();
305-
RectF backgroundRect = new RectF(
306-
leftBackoffAntialias,
343+
backgroundPath.reset();
344+
345+
backgroundRect.set(leftBackoffAntialias,
307346
topBackoffAntialias,
308347
width - rightBackoffAntialias,
309-
height - bottomBackoffAntialias
310-
);
348+
height - bottomBackoffAntialias);
349+
311350
backgroundPath.addRoundRect(backgroundRect, backgroundRadii, Path.Direction.CW);
312351

313352
// draw background
314353
if (this.backgroundColor != 0) {
315-
Paint backgroundColorPaint = new Paint();
354+
backgroundColorPaint.reset();
316355
backgroundColorPaint.setStyle(Paint.Style.FILL);
317356
backgroundColorPaint.setColor(this.backgroundColor);
318357
backgroundColorPaint.setAntiAlias(true);
@@ -337,7 +376,9 @@ public void draw(Canvas canvas) {
337376
}
338377
transform.postTranslate(params.posX, params.posY);
339378

340-
Paint backgroundImagePaint = new Paint();
379+
380+
backgroundImagePaint.reset();
381+
341382
BitmapShader shader = new BitmapShader(
342383
this.backgroundBitmap,
343384
params.repeatX ? Shader.TileMode.REPEAT : Shader.TileMode.CLAMP,
@@ -358,7 +399,7 @@ public void draw(Canvas canvas) {
358399
} else {
359400
boolean supportsPathOp = android.os.Build.VERSION.SDK_INT >= 19;
360401
if (supportsPathOp) {
361-
Path backgroundNoRepeatPath = new Path();
402+
backgroundNoRepeatPath.reset();
362403
backgroundNoRepeatPath.addRect(params.posX, params.posY, params.posX + imageWidth, params.posY + imageHeight, Path.Direction.CCW);
363404
intersect(backgroundNoRepeatPath, backgroundPath);
364405
canvas.drawPath(backgroundNoRepeatPath, backgroundImagePaint);
@@ -374,7 +415,9 @@ public void draw(Canvas canvas) {
374415

375416
if (this.backgroundGradient != null) {
376417
LinearGradientDefinition def = this.backgroundGradient;
377-
Paint backgroundGradientPaint = new Paint();
418+
419+
backgroundGradientPaint.reset();
420+
378421
LinearGradient shader = new LinearGradient(
379422
def.getStartX() * width, def.getStartY() * height,
380423
def.getEndX() * width, def.getEndY() * height,
@@ -394,7 +437,7 @@ public void draw(Canvas canvas) {
394437
if (this.clipPath != null && !this.clipPath.isEmpty()) {
395438
float borderWidth = this.getUniformBorderWidth();
396439
if (borderWidth > 0) {
397-
Paint borderPaint = new Paint();
440+
borderPaint.reset();
398441
borderPaint.setColor(this.getUniformBorderColor());
399442
borderPaint.setStyle(Paint.Style.STROKE);
400443
borderPaint.setStrokeWidth(borderWidth);
@@ -405,13 +448,15 @@ public void draw(Canvas canvas) {
405448
} else if (this.hasUniformBorderColor()) {
406449
// iOS and browsers use black when no color is specified.
407450
if (borderLeftWidth > 0 || borderTopWidth > 0 || borderRightWidth > 0 || borderBottomWidth > 0) {
408-
Paint borderPaint = new Paint();
451+
borderPaint.reset();
409452
borderPaint.setColor(this.getUniformBorderColor());
410453
borderPaint.setStyle(Paint.Style.FILL);
411454
borderPaint.setAntiAlias(true);
412-
Path borderPath = new Path();
413455

414-
RectF borderOuterRect = new RectF(0, 0, width, height);
456+
borderPath.reset();
457+
458+
borderOuterRect.set(0, 0, width, height);
459+
415460
float[] borderOuterRadii = {
416461
borderTopLeftRadius, borderTopLeftRadius,
417462
borderTopRightRadius, borderTopRightRadius,
@@ -420,7 +465,7 @@ public void draw(Canvas canvas) {
420465
};
421466
borderPath.addRoundRect(borderOuterRect, borderOuterRadii, Path.Direction.CW);
422467

423-
RectF borderInnerRect = new RectF(
468+
borderInnerRect.set(
424469
borderLeftWidth,
425470
borderTopWidth,
426471
width - borderRightWidth,
@@ -453,23 +498,25 @@ public void draw(Canvas canvas) {
453498
// +---------------------+
454499
//lbo rbo
455500

456-
PointF lto = new PointF(0, 0); // left-top-outside
457-
PointF lti = new PointF(left, top); // left-top-inside
501+
lto.set(0, 0); // left-top-outside
502+
lti.set(left, top); // left-top-inside
503+
504+
rto.set(bounds.right, 0); // right-top-outside
505+
rti.set(bounds.right - right, top); // right-top-outside
458506

459-
PointF rto = new PointF(bounds.right, 0); // right-top-outside
460-
PointF rti = new PointF(bounds.right - right, top); // right-top-outside
507+
rbo.set(bounds.right, bounds.bottom); // right-bottom-outside
508+
rbi.set(bounds.right - right, bounds.bottom - bottom); // right-bottom-inside
461509

462-
PointF rbo = new PointF(bounds.right, bounds.bottom); // right-bottom-outside
463-
PointF rbi = new PointF(bounds.right - right, bounds.bottom - bottom); // right-bottom-inside
510+
lbo.set(0, bounds.bottom); // left-bottom-outside
511+
lbi.set(left, bounds.bottom - bottom); // left-bottom-inside
464512

465-
PointF lbo = new PointF(0, bounds.bottom); // left-bottom-outside
466-
PointF lbi = new PointF(left, bounds.bottom - bottom); // left-bottom-inside
467513

468514
if (this.borderTopWidth > 0) {
469-
Paint topBorderPaint = new Paint();
515+
topBorderPaint.reset();
470516
topBorderPaint.setColor(this.borderTopColor);
471517
topBorderPaint.setAntiAlias(true);
472-
Path topBorderPath = new Path();
518+
519+
topBorderPath.reset();
473520
topBorderPath.setFillType(Path.FillType.EVEN_ODD);
474521
topBorderPath.moveTo(lto.x, lto.y);
475522
topBorderPath.lineTo(rto.x, rto.y);
@@ -480,10 +527,12 @@ public void draw(Canvas canvas) {
480527
}
481528

482529
if (this.borderRightWidth > 0) {
483-
Paint rightBorderPaint = new Paint();
530+
531+
rightBorderPaint.reset();
484532
rightBorderPaint.setColor(this.borderRightColor);
485533
rightBorderPaint.setAntiAlias(true);
486-
Path rightBorderPath = new Path();
534+
535+
rightBorderPath.reset();
487536
rightBorderPath.setFillType(Path.FillType.EVEN_ODD);
488537
rightBorderPath.moveTo(rto.x, rto.y);
489538
rightBorderPath.lineTo(rbo.x, rbo.y);
@@ -494,10 +543,12 @@ public void draw(Canvas canvas) {
494543
}
495544

496545
if (this.borderBottomWidth > 0) {
497-
Paint bottomBorderPaint = new Paint();
546+
547+
bottomBorderPaint.reset();
498548
bottomBorderPaint.setColor(this.borderBottomColor);
499549
bottomBorderPaint.setAntiAlias(true);
500-
Path bottomBorderPath = new Path();
550+
551+
bottomBorderPath.reset();
501552
bottomBorderPath.setFillType(Path.FillType.EVEN_ODD);
502553
bottomBorderPath.moveTo(rbo.x, rbo.y);
503554
bottomBorderPath.lineTo(lbo.x, lbo.y);
@@ -508,10 +559,11 @@ public void draw(Canvas canvas) {
508559
}
509560

510561
if (this.borderLeftWidth > 0) {
511-
Paint leftBorderPaint = new Paint();
562+
leftBorderPaint.reset();
512563
leftBorderPaint.setColor(this.borderLeftColor);
513564
leftBorderPaint.setAntiAlias(true);
514-
Path leftBorderPath = new Path();
565+
566+
leftBorderPath.reset();
515567
leftBorderPath.setFillType(Path.FillType.EVEN_ODD);
516568
leftBorderPath.moveTo(lbo.x, lbo.y);
517569
leftBorderPath.lineTo(lto.x, lto.y);
@@ -606,7 +658,12 @@ private static void drawClipPath(String clipPath, Canvas canvas, Paint paint, Re
606658
top = cY - rY;
607659
right = (rX * 2) + left;
608660
bottom = (rY * 2) + top;
609-
canvas.drawOval(new RectF(left, top, right, bottom), paint);
661+
662+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
663+
canvas.drawOval(left, top, right, bottom, paint);
664+
} else {
665+
canvas.drawOval(new RectF(left, top, right, bottom), paint);
666+
}
610667
break;
611668
case "polygon":
612669
Path path = new Path();
@@ -832,18 +889,31 @@ public Drawable getDrawable() {
832889
return drawable;
833890
}
834891

892+
893+
private final Path outlineBackgroundPath = new Path();
894+
private final RectF outlineRectF = new RectF();
895+
835896
@Override
836897
public void getOutline(@NonNull Outline outline) {
837898
if (android.os.Build.VERSION.SDK_INT >= 21) {
838-
Path backgroundPath = new Path();
899+
outlineBackgroundPath.reset();
839900
float[] backgroundRadii = {
840901
Math.max(0, borderTopLeftRadius), Math.max(0, borderTopLeftRadius),
841902
Math.max(0, borderTopRightRadius), Math.max(0, borderTopRightRadius),
842903
Math.max(0, borderBottomRightRadius), Math.max(0, borderBottomRightRadius),
843904
Math.max(0, borderBottomLeftRadius), Math.max(0, borderBottomLeftRadius)
844905
};
845-
backgroundPath.addRoundRect(new RectF(getBounds()), backgroundRadii, Path.Direction.CW);
846-
outline.setConvexPath(backgroundPath);
906+
outlineRectF.setEmpty();
907+
outlineRectF.set(getBounds());
908+
backgroundPath.addRoundRect(outlineRectF, backgroundRadii, Path.Direction.CW);
909+
910+
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
911+
// see setConvexPath notes
912+
outline.setPath(backgroundPath);
913+
} else {
914+
outline.setConvexPath(backgroundPath);
915+
}
916+
847917
} else {
848918
throw new IllegalStateException("Method supported on API 21 or higher");
849919
}

0 commit comments

Comments
 (0)