unlockCanvasAndPost() ist sehr langsam

K

kay-ju

Neues Mitglied
0
Hallo,

ich habe die Schleife aus der Main-Methode in einen eigenen Thread
ausgelagert. So weit funktioniert alles wie es soll. Kein weißer Schirm
mehr. Aber jetzt habe ich ein anderes Problem : Die surface holder-
Methode unlockCanvasAndPost() ist sehr langsam. In Werten reicht
der zeitliche Bedarf von 100 bis über 200 ms (das ist komisch, weil
ich in anderen Foren gelesen habe, dass die Methode lockCanvas()
eher so langsam sei - diese läuft bei mir aber in 1-2 ms). Das ist für
meine Bedürfnisse zu langsam. Ich brauche wenigstens 30 FPS.

Weiß jemand, wie ich da Abhilfe schaffen kann?

Javascript:
package com.example.surfaceviewtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.content.res.AssetManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import java.io.IOException;
import android.graphics.Rect;
import android.graphics.Paint;
import java.lang.*;

public class SurfaceViewTest extends Activity {   
    FastRenderView renderView;
    Paint paint;
    AssetManager assetMgr;
    Bitmap numbers, background;
    Rect srcRect = new Rect();
    Rect dstRect = new Rect();

   
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        paint = new Paint();
        assetMgr = this.getAssets();   
        try {
            numbers = BitmapFactory.decodeStream(assetMgr.open("Nummern.png"));
          } catch (IOException e) {     
          }
        try {
            background = BitmapFactory.decodeStream(assetMgr.open("Hintergrund.png"));
        } catch (IOException e) {     
        }
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN);
        renderView = new FastRenderView(this);
        setContentView(renderView);
    }   
   
    protected void onResume() {
        super.onResume();
        renderView.resume();
    }
   
    protected void onPause() {
        super.onPause();   
        renderView.pause();
    }   
   
    class FastRenderView extends SurfaceView implements Runnable {
        Thread renderThread = null;
        SurfaceHolder holder;
        volatile boolean running = false;
   
        public FastRenderView(Context context) {
            super(context);   
            holder = getHolder();   
        }

    public void resume() {   
        running = true;
        renderThread = new Thread(this);
        renderThread.start();   
    }   
   
    public void run() {
        long time;
     
        while(running) {     
            if(!holder.getSurface().isValid()) {
                continue; 
            }
            Canvas canvas = holder.lockCanvas();
            myDraw(canvas);
            time = System.currentTimeMillis();
            holder.unlockCanvasAndPost(canvas);
            Log.d("in run", (System.currentTimeMillis() - time) + " ms");
        }
    }

    public void pause() {   
        running = false;   
        while(true) {
            try {
                renderThread.join();
                return;
            } catch (InterruptedException e) {
                // retry
            }
        }   
    }   
   
    protected void myDraw(Canvas canvas) {
        int indexI, indexJ;
        int offsetX, offsetY;
     
        paint.setColor(Color.BLACK);
        canvas.drawPaint(paint);
            if (numbers != null) {
                offsetX = 100;
                offsetY = 100;
                for (int i = 0; i < 4; i++) {
                    for (int j = 0; j < 4; j++) {
                        indexI = i;
                        indexJ = j;
           
                        srcRect.left = 128 * indexJ;
                        srcRect.top = 128 * indexI;
                        srcRect.right = srcRect.left + 127;
                        srcRect.bottom = srcRect.top + 127;

                        dstRect.left = offsetX + 128 * j;
                        dstRect.top = offsetY + 128 * i;
                        dstRect.right = dstRect.left + 127;
                        dstRect.bottom = dstRect.top + 127;
                        canvas.drawBitmap(numbers, srcRect, dstRect, null);
                    }
                }
            }
        }
    }   
}

Gruß
Kay-ju
 
Eigentlich sollte das Zeichnen auf einen Canvas die meiste Zeit beanspruchen. Aber je nachdem wie viele Pixel vom Bildschirm gezeichnet werden müssen kann es sein dass es einbricht. So 4-5 Vollbild Bitmaps sollten je nach Hardware die 50 FPS nicht überschreiten.

Gaaaanz früher gab es vom Android System mal etwas auf die Patscher falls eine MEthode zu schnell den SurfaceFlinger in Anspruch nimmt also zu schnell zeichnen möchte. Da gab es dann 100-200 ms Auszeit aber das hat sich längst geändert und man braucht sich da eig. keine Sorgen mehr machen.
 

Ähnliche Themen

S
  • skywalker22
Antworten
1
Aufrufe
173
swa00
swa00
S
Antworten
17
Aufrufe
554
jogimuc
J
U
  • unerfahrenerAppEntwickler
Antworten
3
Aufrufe
705
swa00
swa00
Zurück
Oben Unten