从具有线程的活动开始其他活动

时间:2013-05-05 13:16:04

标签: android multithreading android-activity surfaceview

我想从其中包含线程的活动(实际上它在活动的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方法中执行。我该怎么办?真的需要帮助。

1 个答案:

答案 0 :(得分: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。