简体   繁体   中英

android - call method in view from activity

I am working on a 2d game and I'm trying to make the view where I draw and update everything tell the activity that contains it that the game ended and display a pop-up on the screen. The problem is that I don't know how to access the method in the activity from the view because they work on different threads.

The code looks more or less like this and I want to access the method displayFrame() from the view class. The method in the real code does more operations with other textViews etc. that only the activity has access to.

public class MainActivity extends Activity{

    private MyView myView;
    RelativeLayout finalFrame;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        myView = new MyView(this.getApplicationContext());
        this.setContentView(myView);

        finalFrame = (RelativeLayout) findViewById(R.id.framefinal);
    }

    private void displayFrame(){
        this.finalFrame.setVisibility(View.VISIBLE);
    }
}

public class MyView extends SurfaceView implements SurfaceHolder.Callback{
    private MyThread myThread;
    private boolean finished = false;

    public MyView(Context context) {
        super(context);

        getHolder().addCallback(this);
        this.myThread = new MyThread(getHolder(), this);

        this.myThread.setRunning(true);
    }

    public void update() {
        this.finished = someMethod();
        if(this.finished){
            MainActivity.displayFrame();
        }
    }

    public void draw(Canvas canvas){
        //draw something
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
}

public class MyThread extends Thread{
    private MyView myView;
    private SurfaceHolder surfaceHolder;
    private boolean running = false;
    private static Canvas canvas;

    public MyThread(SurfaceHolder surfaceHolder, MyView myView){
        super();
        this.surfaceHolder = surfaceHolder;
        this.myView = myView;
    }

    @Override
    public void run(){
        while(running){
            canvas = null;

            try {
                canvas = this.surfaceHolder.lockCanvas();
                synchronized (surfaceHolder) {
                    this.myView.update();
                    this.myView.draw(canvas);
                }
            } catch (Exception e) {e.printStackTrace();}
            finally{
                if(canvas!=null)
                {
                    try {
                        surfaceHolder.unlockCanvasAndPost(canvas);
                    }
                    catch(Exception e){e.printStackTrace();}
                }
            }
        }
    }

    public void setRunning(boolean running){
        this.running = running;
    }
}

The easiest way to do that is to define a listener interface in your view and make the activity implement it. Then you can notify the activity that your game has ended and execute the appropriate logic.

public class MyView extends SurfaceView implements SurfaceHolder.Callback {

     // your other fields
     private GameListener mGameListener;

     public void setGameListener(GameListener gameListener) {
         mGameListener = gameListener;
     }

     public void update() {
         // your logic
         if (mGameListener != null) {
             // calling onGameEnd on the main thread
             post(new Runnable() {

                 public void run() {
                     mGameListener.onGameEnd();
                 }

             });
         }
     }

     // rest of your class as it is

     public interface GameListener {

         void onGameEnded();

     }
}

public class MainActivity extends Activity implements GameListener {

    // the rest of your class

    public void onGameEnded() {
        // call the method you need
    } 
}
public class MyView extends SurfaceView implements SurfaceHolder.Callback{
private MyThread myThread;
private boolean finished = false;
private Context context;

public MyView(Context context) {
    super(context);
    this.context=context;

    getHolder().addCallback(this);
    this.myThread = new MyThread(getHolder(), this);

    this.myThread.setRunning(true);
}

runOnUiThread(new Runnable(){
@Override
public void run(){
    update();
}
});

    public void update() {
    this.finished = someMethod();
    if(this.finished){
        MainActivity mainActivity = (MainActivity) context;
        mainActivity.displayFrame();
    }
}

public void draw(Canvas canvas){
    //draw something
}

@Override
public void surfaceCreated(SurfaceHolder holder) {

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}
}

Can you try this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM