2016-11-17 6 views
0

私はアンドロイド用の自家製の男のキャラクタークリエイターを開発しています。基本的に、あなたのキャラクターのために髪、髭、シャツ、ズボンなどを選ぶことができます。私は現在着用している顔の特徴や衣服を保存するために合成パターンを使用しています。キャンバスを使用して、ユーザーが作成しているカスタム文字の現在の状態を表示しています。私のアクティビティが開始されると、キャンバスは即座に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); 
} 
} 
+0

SurfaceViewに描画していますか?私は、特に税金を徴収することはない。また、メインスレッドを描画している場合は、ANRクラッシュが発生します(ただし、SurfaceViewスレッドの描画はこれを引き起こしません)。 – DeeV

+0

小さな最適化でも、描画サイクルごとに 'Paint'や' RectF'のような新しいオブジェクトを作成しないと、より良いパフォーマンスが得られます。それらをクラスレベルで隠し、セッターメソッドを使用して更新します。ヒントのために – DeeV

+0

ありがとう。 SurfaceViewではなく、単純なLinearLayoutを使用しています。私はSurfaceViewを使用しようとしましたが、onSurfaceCreatedコールバックは決して呼び出されませんでした。加えて、SurfaceViewを使って背景を透明にすることができませんでした。私はANRのクラッシュを受けているとは思わないが、ちょっと奇妙な理由のためにただちにそれを描くのではない。描画は私が推測するメインスレッドで発生します。 – masm64

答えて

0

問題は次のとおりです。私のcharacterView LinearLayoutは決して無効化されず、ほとんどリフレッシュされませんでした。アプリケーションは、単に私のビューがリフレッシュされることを知らなかった。 characterView.invalidate()の簡単な呼び出しは、この問題を解決しました。

public void update() { 
    /*...*/ 
    characterView.invalidate(); 
} 
関連する問題