Thread wird bei Start aus Activity nicht ausgeführt

  • Antworten:5
Vincenzo Seggio
  • Forum-Beiträge: 8

15.06.2016, 19:33:02 via Website

Hallo, ich bin immer noch dabei ein Ping Pong Spiel zu programmieren und hab jetzt folgendes Problem.

Wenn der Ball ins Aus geht, soll der Thread angehalten werden und nach einem Klick auf den Bildschirm soll er wieder neu gestartet werden. Dazu habe ich in der Klasse "Grafik" eine Methode "start" geschrieben, die den Thread neu starten soll. Aus der MainActivity aufgerufen (Funktion "restartGame") wird der Thread nicht neu gestartet.

Aus der Klasse Grafik aufgerufen (Nach "if (y < -100 && !directionY)") wird der Thread neu gestartet. Hat jemand einen Tip woran das liegt?

Vielen Dank und Grüße

Vincenzo

Hier der Code:

MainActivity :

package com.example.vince.myapplication;

import android.graphics.Canvas;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

RelativeLayout layout;
ImageView imageOne, imageTwo;
TextView playerOneName, playerTwoName, scorePlayerOne, scorePlayerTwo;

DisplayMetrics displaymetrics = new DisplayMetrics();//Dient dazu die Abmessungen des Bildschirms zu ermitteln

float height;
float width;
int imageWith;
Grafik grafik;



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

    setContentView(R.layout.activity_main);
    //Gehört dazu die Abmessungen des Bildschirms zu ermitteln---------------------------------
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    height = displaymetrics.heightPixels - 150;
    width = displaymetrics.widthPixels;


    //-----------------------------------------------------------------------------------------
    layout = (RelativeLayout) findViewById(R.id.layout);
    imageOne = (ImageView) findViewById(R.id.paddle_one);
    imageTwo = (ImageView) findViewById(R.id.paddle_two);
    playerOneName = (TextView) findViewById(R.id.tv_player_1);
    playerTwoName = (TextView) findViewById(R.id.tv_player_2);
    scorePlayerOne = (TextView) findViewById(R.id.tv_score_1);
    scorePlayerTwo = (TextView) findViewById(R.id.tv_score_2);
    playerOneName.setText("Olaf");
    playerTwoName.setText("Vince");

    grafik = new Grafik(this);

    imageWith = imageOne.getDrawable().getIntrinsicWidth();//Balkenbreite ermitteln

    grafik.setImageWithTwo(imageWith);//Balkenbreite an die Klasse Grafik übermitteln
    Grafik.setImageOne(imageOne);
    Grafik.setImageTwo(imageTwo);

    grafik.setPosX(imageOne.getX());
    grafik.setPosY(imageOne.getY());


    layout.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();
            //restartGame();
            if (grafik.isBallOutPlayerOne() && action == MotionEvent.ACTION_DOWN){
                Log.d("Test", "ballOutPlayerOne in Main = true");
                scorePlayerTwo.setText(grafik.getPointPlayerTwo() + "Points");

                    grafik.start();


            }else {
                switch (action){
                    case MotionEvent.ACTION_DOWN:
                        if (event.getY() < height/3) {

                            imageOne.setX(event.getX()-imageWith/2);
                            imageOne.setY(event.getY()+100);
                            grafik.setPosX(imageOne.getX());
                            grafik.setPosY(imageOne.getY());
                            grafik.setStartPlayerOne(true);
                        }else if (event.getY() > (height - height/3)){
                            imageTwo.setX(event.getX()-imageWith/2);
                            imageTwo.setY(event.getY()-100);
                            grafik.setPosX(imageTwo.getX()+imageWith/2);
                            grafik.setPosY(imageTwo.getY()+100);
                            grafik.setStartPlayerTwo(true);

                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        if (event.getY() < height/3) {
                            imageOne.setX(event.getX()-imageWith/2);
                            imageOne.setY(event.getY()+100);
                        }else if (event.getY() > (height - height/3)){
                            imageTwo.setX(event.getX()-imageWith/2);
                            imageTwo.setY(event.getY()-100);
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (event.getY() < height/3) {
                            imageOne.setX(event.getX()-imageWith/2);
                            imageOne.setY(event.getY()+100);
                        }else if (event.getY() > (height - height/3)){
                            imageTwo.setX(event.getX()-imageWith/2);
                            imageTwo.setY(event.getY()-100);
                        }
                        break;

                }
            }
            return true;
        }
    });
}

public void restartGame (View view){

    if (view.getId() == R.id.linear_one){
        Log.d("Test", "Linear One wurde geklickt!!");
        grafik.isRunning = true;
        Log.d("Test", "isRunning = " + grafik.isRunning);
        grafik.start();
    }
    if (view.getId() == R.id.linear_two){
        Log.d("Test", "Linear Two wurde geklickt!!");
        grafik.isRunning = true;
        Log.d("Test", "isRunning = " + grafik.isRunning);
        grafik.start();
    }


}

@Override
protected void onPause() {
    super.onPause();
    //grafik.pause();
    Log.d("Test", "onPause wurde aktiviert!");
}

@Override
protected void onResume() {
    super.onResume();
   // grafik.resume();
    Log.d("Test", "onResume wurde aktiviert!");
    if (grafik.isBallOutPlayerOne())
        Log.d("Test", "ballOutPlayerOne in main = true");
}

}

Und die Klasse Grafik:

package com.example.vince.myapplication;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

/**
* Created by vince on 05.06.2016.
*/
public class Grafik extends SurfaceView implements Runnable{
private static ImageView imageOne, imageTwo;
Bitmap ball;
float x, y, speed;
private static float posX, posY;
boolean directionX = true;
boolean directionY = true;
private static boolean startPlayerOne = false;
private static boolean startPlayerTwo = false;
private static int imageWithTwo;

SurfaceHolder myHolder;
Thread myThread;
boolean isRunning = true;
private boolean ballOutPlayerOne = false;
private boolean ballOutPlayerTwo = false;
private int pointPlayerOne = 0;
private int pointPlayerTwo = 0;


public Grafik(Context context) {
    super(context);
    init(null, 0);
}

public Grafik(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(attrs, 0);
}

public Grafik(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(attrs, defStyleAttr);
}

private void init(AttributeSet attrs, int i) {
    ball = BitmapFactory.decodeResource(getResources(), R.drawable.tennisball);

    //Log.d("Test","x aus Grafik ist gleich " + posX);
    x = 0;
    y = 0;
    speed = 2;
    myHolder = getHolder();
    isRunning = true;
    myThread = new Thread(this);
    myThread.setPriority(Thread.MAX_PRIORITY);
    myThread.start();
}

public void pause(){
    isRunning = false;
    Log.d("Test", "grafik.Pause wurde aufgerufen!");
    while (true){
        try {
            myThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        break;
    }
}

public void start (){
    myHolder = getHolder();
    isRunning = true;
    myThread = new Thread(this);
    myThread.setPriority(Thread.MAX_PRIORITY);
    myThread.start();
    Log.d("Test", "grafik.Start wurde aufgerufen!");

}

@Override
public void run() {


    Log.d("Test", "Run() wurde aufgerufen!!");

    while (isRunning){
        if (!myHolder.getSurface().isValid()) {
            //Log.d("Test", "Holder ist nicht valid, Run() wurde wieder aufgerufen!!");
            continue;

        }

        Canvas canvas = myHolder.lockCanvas();
        canvas.drawColor(Color.BLACK);

        canvas.drawBitmap(ball, x, y, null);
        //Log.d("Test", "x = " + x);

        //x Richtung des Balls------------------------------------------------------------------
        if (x < canvas.getWidth()-ball.getWidth()/2 && directionX){
            x += speed;
        }else {
            x -= speed;
            directionX = false;
        }
        if (x > 0 && !directionX){
            x -= speed;
        }else {
            x += speed;
            directionX = true;
        }
        //--------------------------------------------------------------------------------------
        //y Richtung des Balls------------------------------------------------------------------
        if (directionY){
            y += speed;
        }else {
            y -= speed;
            directionY = false;
        }
        if (!directionY){
            y -= speed;
        } else {
            y += speed;
            directionY = true;
        }
        //--------------------------------------------------------------------------------------
        //Abprallen des Balls von den Schlägern-------------------------------------------------
        if (x > imageOne.getX() && x < imageOne.getX()+imageOne.getWidth()
                && y < imageOne.getY()+imageOne.getHeight()
                && y > imageOne.getY()){
            directionY = true;
        }
        if (x > imageTwo.getX() && x < imageTwo.getX()+imageTwo.getWidth()
                && y > imageTwo.getY()-ball.getWidth()
                && y < imageTwo.getY()+imageTwo.getHeight()){
            directionY = false;
        }
        Ball geht bei Spieler 1 ins Aus, Spieler 2 macht den Punkt----------------------------
        if (y < -100 && !directionY){
            x = imageTwo.getX()+imageTwo.getWidth()/2-ball.getWidth()/2;
            y = imageTwo.getY()-ball.getHeight();
            canvas.drawBitmap(ball, x, y, null);
            isRunning = false;

            ballOutPlayerOne = true;
            Log.d("Test", "x = " + x);
            Log.d("Test", "y = " + y);
            if (ballOutPlayerOne)
                Log.d("Test", "ballOutPlayerOne = true");
            pointPlayerTwo++;
            Log.d("Test", "pointPlayerTwo = " + pointPlayerTwo);

            //start();// Von hier aufgerufen, klappt es
        }
        //--------------------------------------------------------------------------------------
        //Ball geht bei Spieler 2 ins Aus, Spieler 1 macht den Punkt----------------------------
       if (y > canvas.getHeight()+100 && directionY){
            canvas.drawBitmap(ball, imageOne.getX()+imageOne.getWidth()/2-ball.getWidth()/2,
                    imageOne.getY()+ball.getHeight()/2, null);
            isRunning = false;
            //ballOutPlayerTwo = true;
            pointPlayerOne++;

            Log.d("Test", "pointPlayerOne = " + pointPlayerOne);
        }
        //--------------------------------------------------------------------------------------

        myHolder.unlockCanvasAndPost(canvas);
    }
}





public float getPosX() {
    return posX;
}

public void setPosX(float posX) {
    this.posX = posX;
}

public float getPosY() {
    return posY;
}

public void setPosY(float posY) {
    this.posY = posY;
}

public int getImageWithTwo() {
    return imageWithTwo;
}

public void setImageWithTwo(int imageWithTwo) {
    this.imageWithTwo = imageWithTwo;
}

public static ImageView getImageOne() {
    return imageOne;
}

public static void setImageOne(ImageView imageOne) {
    Grafik.imageOne = imageOne;
}

public static ImageView getImageTwo() {
    return imageTwo;
}

public static void setImageTwo(ImageView imageTwo) {
    Grafik.imageTwo = imageTwo;
}

public boolean isStartPlayerOne() {
    return startPlayerOne;
}

public void setStartPlayerOne(boolean startPlayerOne) {
    this.startPlayerOne = startPlayerOne;
}

public boolean isStartPlayerTwo() {
    return startPlayerTwo;
}

public void setStartPlayerTwo(boolean startPlayerTwo) {
    this.startPlayerTwo = startPlayerTwo;
}

public boolean isBallOutPlayerOne() {
    return ballOutPlayerOne;
}

public boolean isBallOutPlayerTwo() {
    return ballOutPlayerTwo;
}

public int getPointPlayerOne() {
    return pointPlayerOne;
}

public int getPointPlayerTwo() {
    return pointPlayerTwo;
}

public void setBallOutPlayerOne(boolean ballOutPlayerOne) {
    this.ballOutPlayerOne = ballOutPlayerOne;
}

public void setBallOutPlayerTwo(boolean ballOutPlayerTwo) {
    this.ballOutPlayerTwo = ballOutPlayerTwo;
}

public void setPointPlayerOne(int pointPlayerOne) {
    this.pointPlayerOne = pointPlayerOne;
}

public void setPointPlayerTwo(int pointPlayerTwo) {
    this.pointPlayerTwo = pointPlayerTwo;
}

}

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

15.06.2016, 20:27:54 via App

Du musst erstmal den laufenden Thread beenden bevor du einen neuen starten kannst. beim restart in der Main machst du ja nur erneut nen start da fehlt aber ein stop.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Vincenzo Seggio
  • Forum-Beiträge: 8

15.06.2016, 20:42:07 via Website

Sorry aber wie mach ich das ?

grafik.myThread.stop(); in restart führt dazu, dass die App abstürzt und der Aufruf von grafik.pause(); vor grafik.start(); hat keinen Effekt.

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

15.06.2016, 20:44:42 via App

Ja aber warum stürtzt es ab?
Exception?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Vincenzo Seggio
  • Forum-Beiträge: 8

15.06.2016, 20:50:18 via Website

Caused by: java.lang.reflect.InvocationTargetException für die Zeile mit grafik.myThread.stop();

Der ganze Log Eintrag sieh so aus:

FATAL EXCEPTION: main
Process: com.example.vince.myapplication, PID: 2852
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:3962)
at android.view.View.performClick(View.java:4633)
at android.view.View$PerformClick.run(View.java:19274)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View$1.onClick(View.java:3957)
at android.view.View.performClick(View.java:4633) 
at android.view.View$PerformClick.run(View.java:19274) 
at android.os.Handler.handleCallback(Handler.java:733) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:146) 
at android.app.ActivityThread.main(ActivityThread.java:5593) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.UnsupportedOperationException
at java.lang.Thread.stop(Thread.java:1052)
at java.lang.Thread.stop(Thread.java:1042)
at com.example.vince.myapplication.MainActivity.restartGame(MainActivity.java:153)
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at android.view.View$1.onClick(View.java:3957) 
at android.view.View.performClick(View.java:4633) 
at android.view.View$PerformClick.run(View.java:19274) 
at android.os.Handler.handleCallback(Handler.java:733) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:146) 
at android.app.ActivityThread.main(ActivityThread.java:5593) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) 
at dalvik.system.NativeStart.main(Native Method) 

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

15.06.2016, 21:09:18 via App

Achso stimmt.
Thread stop geht nicht mehr. Das muss man selber handeln

http://www.straub.as/java/threads/interrupt.html

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten