【发布时间】:2016-11-18 20:13:19
【问题描述】:
我正在为 android 开发一个家庭 brew family guy 角色创建器。基本上你可以为你的角色选择头发、胡须、衬衫、裤子等。我正在使用复合图案来存储当前佩戴的面部特征和衣服。我正在使用画布来显示用户正在创建的自定义角色的当前状态。当我的活动开始时,画布会立即绘制 3 个位图,但之后当用户单击(触摸)一种头发类型时,由于某种原因(有时甚至长达 1 分钟),绘制需要非常长的时间。我似乎找不到任何合理的解释来解释为什么会发生这种情况。提前致谢。
我的 onCreate 重写方法的一部分:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
character = new Character();
character.attach(this); //observes the character
assetManager = getAssets();
BitmapLoader.setAssetManager(assetManager);
/*...*/
characterView = (LinearLayout) findViewById(R.id.character_view);
initCanvas();
initButtons();
loadPersistedCharacter();
character.notifyAllObservers(); //just for testing purposes
}
我的画布初始化代码:
private void initCanvas() {
Paint paint = new Paint();
Bitmap background = Bitmap.createBitmap(600, 800, Bitmap.Config.ARGB_8888);
canvas = new Canvas(background);
paint.setColor(Color.parseColor("#CD5C5C"));
characterView.setBackground(new BitmapDrawable(getResources(), background));
}
当通过使用观察者模式点击衣服或面部特征(在 onClickListeners 的帮助下)时,会调用更新方法,该方法可以在与之前代码相同的 Activity 中找到。
@Override
public void update() {
Paint paint = new Paint();
Skin skin = character.getSkin();
Bitmap bitmap = BitmapLoader.load(skin.getPath());
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
float scale = skin.getScale();
int asd = bitmap.getWidth();
int asdY = bitmap.getHeight();
float coordX = (canvas.getWidth() - scale * asd) / skin.getXPosDivider();
float coordY = (canvas.getHeight() - scale * asdY) / skin.getYPosDivider();
RectF rect= new RectF(coordX, coordY, coordX + scale * bitmap.getWidth(), coordY + scale * bitmap.getHeight());
canvas.drawBitmap(bitmap, null, rect, paint);
for (HeadFeature feature : character.getHeadFeatures()) {
scale = feature.getScale();
bitmap = BitmapLoader.load(feature.getPath());
coordX = (canvas.getWidth() - scale * bitmap.getWidth()) / feature.getXPosDivider();
coordY = (canvas.getHeight() - scale * bitmap.getHeight()) / feature.getYPosDivider();
rect= new RectF(coordX, coordY, coordX + scale * bitmap.getWidth(), coordY + scale * bitmap.getHeight());
canvas.drawBitmap(bitmap, null, rect, paint);
}
}
【问题讨论】:
-
您是在 SurfaceView 上绘图吗?我没有看到任何需要一分钟才能绘制的特别费力的东西。此外,如果您在主线程上绘图,您会遇到 ANR 崩溃(但在 SurfaceView 线程上绘图不会导致这种情况)。
-
还有一些小的优化,如果你不在每个绘制周期创建像
Paint或RectF这样的新对象,你将获得更好的性能。将它们隐藏在类级别并使用它们的 setter 方法更新它们。 -
感谢您的提示。我没有使用 SurfaceView,而是使用简单的 LinearLayout。我尝试使用 SurfaceView 但从未调用过 onSurfaceCreated 回调。加上 SurfaceView 我无法使背景透明。我不认为我收到了 ANR 崩溃,只是出于某种奇怪的原因没有立即绘制它。绘图发生在我猜的主线程上。
-
使用 RGB_565 而不是 ARGB_8888,因为 ARGB_8888 每个像素占用 4 个字节并编码 RGB + alpha 通道,而 RGB_565 每个像素使用 2 个字节并且只编码 RGB,但质量问题不大。试一试
-
我已经尝试过了。我什至尝试设置 android:hardwareAccelerated="true" 并有所帮助,但效果不大。