iniciar otra actividad desde la actividad que tiene hilo

I want to move from activity that has thread in it (actually it's in the activity's SurfaceView) to other activity. But when I run it, sometimes it works, sometimes it's not responding (it moves to other activity but the activity freezes). I really frustrated right now. I have searched everywhere but I can't find the answer to my problem. Somebody please help me. :(

I'll show you the code. If you need other pieces of code I'll show it to you.

Here is the Activity code:

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);
    }
}

Here is the SurfaceView code (I don't give you all part of the code because it will be too long):

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);
    }
}

Aquí está el código del hilo:

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 is executed in update method in SurfaceView code. What should I do? Really needs help here.

preguntado el 05 de mayo de 13 a las 14:05

Not responding in the sense what happened... -

sorry I don't get what you mean :( -

sometimes it works, sometimes it's not responding I mean this, -

@Pragnani I've edited it -

try to call intent in runOnUiThread(Runnable), and let me know if it work for you. -

1 Respuestas

SurfaceView extends View, so you can call the View.post() method. In the code where you currently startThe activity you want to do this. You can call another function to do this if you want it to be a little cleaner.

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

This will call startActivity on the mainThread.

contestado el 05 de mayo de 13 a las 17:05

I've tried method that you've suggested but the result is the same. Thanks for replying - Darkstallion

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.