私はアンドロイド用の自家製の男のキャラクタークリエイターを開発しています。基本的に、あなたのキャラクターのために髪、髭、シャツ、ズボンなどを選ぶことができます。私は現在着用している顔の特徴や衣服を保存するために合成パターンを使用しています。キャンバスを使用して、ユーザーが作成しているカスタム文字の現在の状態を表示しています。私のアクティビティが開始されると、キャンバスは即座に3つのビットマップを描画しますが、その後、ユーザがヘアタイプをクリック(接触)すると、何らかの理由で(時には最大1分まで)描画に珍しい時間がかかります。なぜこれが起こっているのかについて、私は合理的な説明を見つけることができないようです。前もって感謝します。ビットマップを描くときのAndroidの遅いキャンバスの動作
私の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の助けを借りて)クリックされましたObserverパターンのupdateメソッドが呼び出され、これは前のコードと同じアクティビティで検出されます。
@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スレッドの描画はこれを引き起こしません)。 – DeeV
小さな最適化でも、描画サイクルごとに 'Paint'や' RectF'のような新しいオブジェクトを作成しないと、より良いパフォーマンスが得られます。それらをクラスレベルで隠し、セッターメソッドを使用して更新します。ヒントのために – DeeV
ありがとう。 SurfaceViewではなく、単純なLinearLayoutを使用しています。私はSurfaceViewを使用しようとしましたが、onSurfaceCreatedコールバックは決して呼び出されませんでした。加えて、SurfaceViewを使って背景を透明にすることができませんでした。私はANRのクラッシュを受けているとは思わないが、ちょっと奇妙な理由のためにただちにそれを描くのではない。描画は私が推測するメインスレッドで発生します。 – masm64