0

スレッドを含むアクティビティ (実際にはアクティビティの SurfaceView にあります) から他のアクティビティに移動したいと考えています。しかし、実行すると、動作することもあれば、応答しないこともあります (他のアクティビティに移動しますが、アクティビティがフリーズします)。私は今本当にイライラしています。どこでも検索しましたが、問題の答えが見つかりません。誰か助けてください。:(

コードをお見せします。他のコードが必要な場合は、それを示します。

アクティビティ コードは次のとおりです。

public class MapActivity extends Activity {

    private static final String TAG = MapActivity.class.getSimpleName();
    private DisplayMetrics metrics;
    private MapView mapView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        DrawableManager.initInstance(getApplicationContext());
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        Log.d(TAG, "start game activity");
        metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics); // dapetin
                                                                    // ukuran
                                                                    // layar
                                                                    // mapView =
                                                                    // new
                                                                    // MapView(this,
                                                                    // metrics.widthPixels,
                                                                    // metrics.heightPixels);
        MapView.initInstance(getApplicationContext(), metrics.widthPixels,
                metrics.heightPixels);
        setContentView(MapView.getInstance());
    }

    @Override
    public void onPause() {
        super.onPause();
        MapView.getInstance().thread.setRunning(false);
    }
}

SurfaceView のコードは次のとおりです (コードが長くなりすぎるため、コードのすべての部分は示しません)。

public class MapView extends SurfaceView implements SurfaceHolder.Callback {
    public final Random rand;
    private Resources res;
    private static MapView instance;
    private static int screenWidth;
    private static int screenHeight;
    private static final String TAG = MapView.class.getSimpleName();
    public mapThread thread;
    private Matrix matrix = new Matrix();
    public static Block blockTile[][];
    private Player player;
    public static int tileSize;
    public static boolean isMalam = false;
    public static boolean isAdaMonster = false;
    private ArrayList<Monster> monsters;
    public static int leftMargin;
    public static final int nTileH = 10;
    public static final int nTileW = 17;
    private int ctrMonster = 0;
    private int ctrDetik = 0;
    private int ctrMenit = 0;
    private int ctrJam = 6;
    private int ctrHari = 0;
    private static boolean isOutdoor;

    private Pair<Float, Float> tapPos;
    private Pair<Float, Float> tapPos2;
    private Context parentActivity;
    private boolean isTouch = false;
    private boolean Found = false;
    private Street street;
    private Store store;
    private Combinatorium combinatorium;
    private Stadium stadium;
    private Home home;
    private AreaLuar3 arealuar3;
    private AreaLuar2 arealuar2;
    private AreaLuar1 arealuar1;
    private String dataMap[];
    public static String currentMap;

    public MapView(Context context, int scrWidth, int scrHeight) {
        super(context);
        parentActivity = context;
        blockTile = new Block[nTileW][nTileH];
        screenWidth = scrWidth;
        screenHeight = scrHeight;
        int sTile = scrHeight / nTileH;
        tileSize = sTile;
        getHolder().addCallback(this);
        res = context.getResources();
        rand = new Random();
        dataMap = new String[15];
        currentMap = "street";
        player = new Player(7, 4);
        build();
        setFocusable(true);
    }

    public void surfaceCreated(SurfaceHolder arg0) {
        // inisialisasi thread
        initThread();
        Log.d(TAG, "surface created");
    }

    public void surfaceDestroyed(SurfaceHolder arg0) {
        releaseThread();
        Log.d(TAG, "surface destroyed");
    }

    public static void initInstance(Context context, int W, int H) {
        assert instance == null;
        instance = new MapView(context, W, H);
    }

    public static MapView getInstance() {
        assert instance != null;
        return instance;
    }

    // inisialisasi thread
    public void initThread() {
        if (thread == null || !thread.isAlive()) {
            thread = new mapThread(getHolder(), this);
            thread.start();
        }
        thread.setRunning(true);
    }

    private void releaseThread() {
        boolean retry = true;
        while (retry)
            try {
                thread.join();
                retry = false;
                thread = null;
            } catch (InterruptedException e) {
            }
    }

    public void update() {
        ctrDetik++;
        if (ctrDetik > 59) {
            ctrDetik = 0;
            ctrMenit++;
            if (ctrMenit > 59) {
                ctrMenit = 0;
                ctrJam++;
                cekMalam();
                if (ctrJam > 23) {
                    ctrJam = 0;
                    ctrHari++;
                }
            }
        }
        if (!Found && isAdaMonster) {
            ctrMonster++;
            for (Monster mons : monsters) {
                if (mons.cekEqualBlock(player)) {
                    Found = true;
                    Intent test = new Intent(parentActivity, MainMenu.class);
                    test.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    parentActivity.startActivity(test);
                }
                if (Found)
                    break;
                if (ctrMonster == 30) {
                    ctrMonster = 0;
                    monsters.get(0).moveRandom();
                    monsters.get(1).moveCloser(player.getXBlock(),
                            player.getYBlock());
                }
            }
        }
        if (isTouch)
            if (Math.abs(tapPos2.first - tapPos.first) > 100
                    || Math.abs(tapPos2.second - tapPos.second) > 100)
                if (Math.abs(tapPos2.first - tapPos.first) > Math
                        .abs(tapPos2.second - tapPos.second)) {
                    if (tapPos2.first - tapPos.first > 0)
                        player.move(2);
                    else
                        player.move(4);
                } else if (Math.abs(tapPos2.first - tapPos.first) < Math
                        .abs(tapPos2.second - tapPos.second))
                    if (tapPos2.second - tapPos.second > 0)
                        player.move(3);
                    else
                        player.move(1);
    }
}

スレッドコードは次のとおりです。

package com.map;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class mapThread extends Thread {
    private boolean running;
    private SurfaceHolder surfaceHolder;
    private MapView mapView;
    private final static int MAX_FPS = 60; // fps yang
                                            // diinginkan
    private final static int MAX_FRAME_SKIPS = 5; // maksimum
                                                    // jumlah
                                                    // frame
                                                    // yang bisa
                                                    // diskip
    private final static int FRAME_PERIOD = 1000 / MAX_FPS;

    public mapThread(SurfaceHolder surfaceHolder, MapView gameMapView) {
        super();
        this.surfaceHolder = surfaceHolder;
        mapView = gameMapView;
    }

    public void setRunning(boolean val) {
        running = val;
    }

    @Override
    public void run() {
        Canvas canvas;
        long beginTime; // waktu mulai siklus
        long timeDiff; // waktu yang diperlukan satu siklus untuk selesai
        int sleepTime; // ms untuk tidur(<0 jika ketinggalan)
        int framesSkipped; // jumlah frame yang akan diskip

        sleepTime = 0;

        while (running) {
            canvas = null;
            // ngunci canvas untuk digambar
            try {
                canvas = surfaceHolder.lockCanvas();
                synchronized (surfaceHolder) {
                    beginTime = System.currentTimeMillis();
                    framesSkipped = 0; // reset jumlah frame yang pengen diskip
                    // update game state
                    // draw canvas di panel
                    mapView.update();
                    mapView.render(canvas);
                    // hitung berapa lama satu siklus
                    timeDiff = System.currentTimeMillis() - beginTime;
                    // hitung waktu tidur
                    sleepTime = (int) (FRAME_PERIOD - timeDiff);

                    if (sleepTime > 0)
                        // tidurin thread selama waktu tidur tsb
                        // cycle lebih cepat dari fps
                        try {
                            Thread.sleep(sleepTime);
                        } catch (InterruptedException e) {
                        }

                    while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
                        // ketinggalan fps, update tanpa manggil render
                        mapView.update();
                        sleepTime += FRAME_PERIOD;
                        framesSkipped++;
                    }
                }
            } finally {
                // in case of an exception the surface is not left in
                // an inconsistent state
                if (canvas != null)
                    surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }
    }
}

startActivity は、SurfaceView コードの update メソッドで実行されます。私は何をすべきか?ここで本当に助けが必要です。

4

1 に答える 1

0

SurfaceView は View を拡張するため、メソッドを呼び出すことができますView.post()。現在開始しているコードでこれを実行したいアクティビティ。少しきれいにしたい場合は、別の関数を呼び出してこれを行うことができます。

post(new Runnable() {
    @Override
    public void run() {
        Intent test = new Intent(parentActivity, MainMenu.class);
        test.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        parentActivity.startActivity(test);        
});

これにより、mainThread で startActivity が呼び出されます。

于 2013-05-05T16:20:15.347 に答える