# App Programmierung: Thread starten und Variablenwerte oder Objekte mitgeben



## Meri (4. Nov 2014)

Ich bin am Programmieren einer Spiele App, in welcher sich ein Balken über Touch bewegen lasst (am unteren Rand) und ein Ball quer durch das Bild laufen soll. Mit dem Brett soll der Ball dann immer wieder aufgefangen werden. Die einzelnen Funktionen habe ich schon aber ich bekomme es nicht in ein gemeinsammes Fenster rein.
Einen der vielen Ansatz war ein Thread von der anderen klasse zu öffnen, aber das Funktioniert auch noch nicht ganz, denn ich muss da eigentlich eine Information mitgeben, bzgl. wo etwas ausgegeben werden soll oder so, aber das FUnktioniert nicht und auch wenn ich die Variable im Hauptfenster Deklarieren kann es diese im Thread nicht verwenden.
Folgenden Code habe ich schon probiert: 
(Hier wierden über die Startklasse zwei butten angezeigt, über einen soll der thread dann gestartet werden. Er wurde zwar schon oben erstellt aber noch auf pause gesetzt. Wenn er dann startet solte er bis 100 Zählen im selben fesnter, aber wie gesagt bis jetzt tut er das noch nicht da die werte für das fenster in der er ausgeben soll nicht mit übergeben werden können. Der andere butten ist für reset und pause) Dieses Beispiel stammt ursprünglich von folgender Seite(obwohl ich es eigentlich relativ eins zu eins übernomen habe funktioniert es nicht): Android

Counter.java

```
package com.example.threadtest;

import android.os.Handler;
import android.widget.TextView;

public class Counter implements Runnable {        //private

    private int result = 0;
    private boolean pause = false;

    @Override
    public void run() {
        
        pause = false;
        result = 0;
        while (true) {
            if (pause) {

                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                    }

                continue;
            }
            result++;
            result = result % 100;
            //Diesen erkennt er nicht, bzw. kann er nicht von der Anderen klasse verwenden, aber ich kann ihn hier auch nicht nochmal deklarieren, das geht auch nciht
            handler.post(new Runnable() {
            @Override
            public void run() {        
                //Und hier ist es das selbe
                tvStatusNeu.setText("" + result);
                }
            });
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
            }
        }
    }

    public void setPause(boolean pause) {
        this.pause = pause;
    }

    public boolean isPause() {
        return pause;
    }

    public void reset() {
        this.result = 0;
        handler.post(new Runnable() {
            @Override
            public void run() {
                tvStatusNeu.setText("" + result);
            }
        });
    }
}
```
MainActivity.java

```
package com.example.threadtest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
    private static final String TAG = MainActivity.class.getSimpleName();        //MyThreadExample1Activity

    private Button bStart;
    private Button bReset;
    public TextView tvStatus;

    private Handler handler;

    private Counter worker;
    private Thread workthread;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activty_main);
    
        handler = new Handler();
        bStart = (Button) findViewById(R.id.main_b_start);
        bReset = (Button) findViewById(R.id.main_b_reset);
        tvStatus = (TextView) findViewById(R.id.main_tv_status);

        worker = new Counter();
        workthread = new Thread(worker);
        worker.setPause(true);
        

        bStart.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Thread.State status = workthread.getState();
                Log.d(TAG, "status: " + status);
                if (Thread.State.NEW.equals(status)) {
                    // first start
                    Log.d(TAG, "start");
                    workthread.start();    
                    setButtonMsg("pause");
                    bReset.setEnabled(true);
                } else {
                    if (worker.isPause()) {
                        Log.d(TAG, "weiter");
                        worker.setPause(false);
                        bReset.setEnabled(false);
                        setButtonMsg(getString(R.string.pause));
                    } else {
                        Log.d(TAG, "pause");
                        worker.setPause(true);
                        bReset.setEnabled(true);
                        setButtonMsg(getString(R.string.weiter));
                    }
                }
            }
        });

        bReset.setEnabled(false);
        bReset.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(worker.isPause()){
                    worker.reset();
                    Log.d(TAG, getString(R.string.pause));
                    setButtonMsg(getString(R.string.start));
                }
            }
        });
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        workthread.interrupt();
        workthread = null;
    }

    private void setButtonMsg(final String msg) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (msg == null) {
                    bStart.setText("");
                } else {
                    bStart.setText(msg);
                }
            }
        });
    }
}
```

Hat jemand eine Lösung oder hilfe zu diesem Code und kann mir da weiter helfen oder sogar zu meinem Grundproblem eine Idee wie ich es machen kann?


----------



## Gucky (4. Nov 2014)

Du könntest dem Thread die Variablen im Konstruktor mitgeben.


----------



## Meri (4. Nov 2014)

Danke für das, dieses Funktioniert jetzt soweit, aber in meinem nächsten Schritt geht es leider nicht mehr, wenn ich dann die zweite Klasse (Counter.java) von der View erben lassen will um dann eben meinen Ball mit Paint und onDraw zu zeichnen, denn da wird dann ein Konstruktor mit Context erwartet und wenn ich mehr dazu schreibe sturzt die App ab.
Wie kann ich das lösen? Das ich wie gesagt in dem Thread den Ball im Fenster bewegen lassen kann z.b. über eine View?

Freue mich über jede weitere hilfe


----------

