Timer funktioniert nur in innerer Klasse?!

M

maeview

Neues Mitglied
0
Guten Abend,
ich versuche schon eine Weile einen Countdown einzubinden, der auch von außerhalb ansprechbar ist.
Die Klasse Counter arbeitet ohne Probleme, in der Activity "GameActivity", als inner Class.
Doch, sobald ich eine seperate daraus mache, wirft er mir eine java.lang.NullPointerException an den Kopf. Und peinlicherweise weiß ich echt nicht was das Problem ist.

Hier noch einmal im Detail

at com.example.maeview.xxxxxxxx.Counter.onTick(Counter.java:34)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:124)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

Zum Verständnis stell ich auch direkt die Codes der Klassen vor.

Code:
package com.example.maeview.[/COLOR][/COLOR][COLOR=Red][COLOR=Black]xxxxxxxx;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;


public class GameActivity extends Activity {


    TextView tss;  //tts = timeSetStart


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.game);

        tss = (TextView) findViewById(R.id.time);

                tss.setText("00:01:00");
         final Counter timer = new Counter(60000,1000);
        timer.start();


    }

}


Code:
package com.example.maeview.[/COLOR][/COLOR][COLOR=Red][COLOR=Black][COLOR=Red][COLOR=Black]xxxxxxxx[/COLOR][/COLOR];


import android.os.CountDownTimer;
import java.util.concurrent.TimeUnit;



public class Counter extends CountDownTimer{


    GameActivity gA = new GameActivity();


    public Counter(long millisInFuture, long countDownInterval) {
    super(millisInFuture, countDownInterval);

}
    @Override
    public void onTick(long millisUntilFinished){


        long millis = millisUntilFinished;
               String zeit = String.format("%02d:%02d:%02d:", TimeUnit.MILLISECONDS.toHours(millis),
               TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
               TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
        System.out.println(zeit);
        gA.tss.setText(zeit);
    }
    @Override
    public void onFinish(){

    }

}


Ich bin mir relativ sich, dass es noch effizientere Methoden gibt, einen Counter zu erstellen und vielleicht könnt ihr sogar welche vorstellen, wenn ihr möchtet.

Die App startet auch ganz normal in der Haupt Activity, doch drücke ich auf Start, um in die GameActivity zu kommen, stürzt die App ab.
Von euch kennen sich damit bestimmt die meisten aus und ich blick da mal wieder nicht durch :razz:
Ich bedanke mich schon mal im voraus,
lG
 

Der ursprüngliche Beitrag von 21:42 Uhr wurde um 21:44 Uhr ergänzt:

gA.tss.setText(zeit);

Denke mal, dein NullpointerException tritt hier auf.


Der grundlegende Fehler liegt hier:

GameActivity gA = new GameActivity();

Du erzeugst zwar ein Objekt der der Activity. Die Methode onCreate() wird aber nicht aufgerufen. Folglich ist der TextView tss null.

Der eigentliche Fehler aber liegt viel tiefer. Man startet Activities in Android anders.
https://developer.android.com/training/basics/firstapp/starting-activity.html

Am besten du fängst von vorne an, und arbeitest die Dokumentation in Ruhe durch.
 
Zuletzt bearbeitet:
maeview schrieb:
Ich bin mir relativ sich, dass es noch effizientere Methoden gibt, einen Counter zu erstellen und vielleicht könnt ihr sogar welche vorstellen, wenn ihr möchtet.


[/COLOR][/COLOR]



hey so startet man keine activity wie mein vorredner shcon meinte...
ich hab zwar noch nie selbst ein timer programmiert aber ich würde
-System.currenttimeMillis() benutzen um die Zeitspanne in milisekunden zu bekommen und dann mit ein paar variablen(year ,day,hour,minute,second,milisecond) und dem Modulooperator mir daraus die einzelnen werte für die entsprechenden variablen "rausschneiden" :)

etwa so:
PHP:
public String timer(long milliSecs)
{
    int year,day,hour,min,sec;


    year=milliSecs%31 556 926 000;
    milliSecs-=year*31 556 926 000;

    day=milliSecs%86 400 000;
    milliSecs-=day*86 400 000;

    hour=milliSecs%3 600 000;
    milliSecs-=hour*3 600 000;

    minute=milliSecs%60 000;
    milliSecs-=minute*60 000;

    sec=milliSecs%1 000;
    milliSecs-=sec*1 000;


   return (year + " years, " + day + " days, " + hour + ... + milliSecs + " ms")
  
   
}
 
Da Jahre (Stichwort: Schaltjahre) unterschiedlich lang sind, ist die Berechnung von Jaiel bei Zeiträumen >365 Tage aber evtl. ungenau.

Evtl. solltest du dir auch mal die Klasse DateUtils anschauen.
 
Zuletzt bearbeitet:
ach dann nimmt man eben anstatt 365 Tage die Millisekunden für 365 und ca 1/4 Tag obwohl ich denke dass hier die Jahresanzeige bei sowas nciht benutzt werden brauch!

Der ursprüngliche Beitrag von 19:49 Uhr wurde um 19:51 Uhr ergänzt:

ausser er will ein countdown zum weltuntergang programmieren oder so lol
 
@maeview
Es gibt zwar noch andere Möglichkeiten ein Counter zu programmieren, aber der Ansatz ist okay. Du solltest den Counter mit der Methode cancel() beenden, wenn die Activity in den Hintergrund geht (onPause()). Sonst kann es zu Probleme kommen.

Als Anfang für ein Spiel ist es echt okay.

Wie schon weiter oben angedeutet, solltest du dich vorher noch mehr mit den Grundlagen beschäftigen (Lifecycle, Activities starten usw.).
 
Danke euch, für die zahlreichen Antworten.
Habe viel gelesen und vieles ausprobiert, komme aber nicht
auf die Lösung. Theoretisch könnte ich jetzt meine ganzen Codes präsentieren aber zum einen, würde es zu einer Explosion des Threads führen und zum anderen, hab ich diese nicht notiert :biggrin:. Vielleicht würde es mir helfen, wenn mir jemand einen Lösungsansatz näher bringt und es eventuell mal mit den Codes oben probiert. Wahrscheinlich habe ich aber einfach nur einen Denkfehler. Bedanke mich jetzt schon einmal.
 
vielleicht hilft dir dieser lösungsansatz von mir obwohl es um ein anderes thema geht aber dort hab ich beschrieben wie man auf den uiThread zugreifen kann und seine Memeber manipulieren kann --->https://www.android-hilfe.de/forum/...ualisiert-sich-nicht.664210.html#post-8641647

Der ursprüngliche Beitrag von 21:02 Uhr wurde um 21:03 Uhr ergänzt:

hast ja schon ein gameactivity objekt jetzt könntest du den Konstruktor des Counters so umschrieben dass er zusätzlich noch ein GameActivity objekt fordert und mit diesem parameter referenzierst du dein gA aufd diesen
 
So langsam freunde ich mich damit an, Klassen von außen zu behandeln aber was von außen immer noch nicht starten möchte, ist der Counter.

Da brauche ich womöglich noch einen Denkanstoß. Wenn ihr so nett seid, versucht es bei euch einmal selbst aus, ob ihr den Counter so starten könnt.
Vielleicht liegts ja einfach am Kot-Code :confused2:
Den TextView kann ich durch einen in der Klasse "Counter" definierten String (zwei = "2") ja auch manipulieren.
Und an den String hms komme ich von außen auch nicht, hab da auch alles versucht!
Schaut es euch einfach mal selbst an, danke.

Code:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class GameActivity extends Activity implements View.OnClickListener {

    Button tButton, stButton;
    TextView tss;  //tss = timeSetStart
    //Zahl zahl = new Zahl();
    Counter timer = new Counter(60000, 1000);


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.game);
        tButton = (Button) findViewById(R.id.tButton);
        tButton.setOnClickListener(this);
        stButton = (Button) findViewById(R.id.stButton);
        stButton.setOnClickListener(this);

        tss = (TextView) findViewById(R.id.time);
        tss.setText(timer.zwei);
        //tss.setText(zahl.sechs);
        //timer.start();

    }

    @Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.tButton:
                timer.start();
                break;
            case R.id.stButton:
                timer.cancel();
        }

    }

    }
Code:
import android.os.CountDownTimer;
import java.util.concurrent.TimeUnit;





    public class Counter extends CountDownTimer {

public String zwei = "2";



        public Counter(long millisInFuture, long countDownInterval) {
                super(millisInFuture, countDownInterval);

            }


            @Override
            public void onTick(long millisUntilFinished) {


                long millis = millisUntilFinished;
                 String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
                        TimeUnit.MILLISECONDS.toMinutes(millis) -  TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))/
                        TimeUnit.MILLISECONDS.toSeconds(millis) -  TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
                System.out.println(hms);



            }


            @Override
            public void onFinish() {

            }

        }
 
Zuletzt bearbeitet:
ja was amchst du da denn auch?
wird es wenigstens korrekt in der Konsole ausgegeben dein hms?

aber sonst ist ja ligisch dass du an hms nciht rankommst weil es eine von außen unsichtbare lokale variable der methode onTick ist und kein klassenmember von counter....kennst du nciht die scope regel?
mach hms zu einem member und sette den Text in regelmäßigen abständen
 

Ähnliche Themen

SaniMatthias
Antworten
19
Aufrufe
955
swa00
swa00
D
Antworten
23
Aufrufe
2.537
Data2006
D
O
Antworten
15
Aufrufe
2.968
ORHUX
O
Zurück
Oben Unten