Probleme mit lokalen Highscore - Programmabsturz

  • 3 Antworten
  • Letztes Antwortdatum
B

Bacianthos

Neues Mitglied
0
Hallo Miteinander

Ich bin relativ neu in der Android App Entwickler Szene. Ich habe mir ein Buch zugelegt um das Ganze zu lernen. Jetzt bin ich mit der eigenen App dran, ich möchte das Spielprinzip Breakout programmieren.

Grundsätzlich verwendet meine Übungsapp den "gleichen" Code wie ich ihn hier habe, doch irgendetwas möchte noch nicht richtig funktionieren. Ich konnte den Fehler lokalisieren. Und zwar befindet er sich in den Zeilen mit:

NameInput = (LinearLayout) findViewById(R.id.NameInput);
Save = (Button) findViewById(R.id.Save);
Save.setOnClickListener(this);
NameInput.setVisibility(View.INVISIBLE);

Wenn ich das ausmaskiere, funktioniert das ganze ohne Absturz. Aber ich habe das Spiel (Gameplay) noch nicht programmiert und somit kann ich meinen Highscore nicht testen (Code habe ich wie oben beschrieben schon in der Probeapp verwendet und hat geklappt). Aber ich brauche diesen Codeteil ja auch in der Übungsapp. Mir ist es unverständlich warum ich einen Fehler bekomme. Den ganzen Codeauszug in voller Länge im folgenden Teil:





package com.example.breakoutapp;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class menu extends Activity implements OnClickListener {


private LinearLayout NameInput;
private Button Save;


@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
Button Start = (Button) findViewById(R.id.start);
Start.setOnClickListener(this);
Button Einstellungen = (Button) findViewById(R.id.einstellungen);
Einstellungen.setOnClickListener(this);
Button Highscore = (Button) findViewById(R.id.highscore);
Highscore.setOnClickListener(this);

NameInput = (LinearLayout) findViewById(R.id.NameInput);
Save = (Button) findViewById(R.id.Save);
Save.setOnClickListener(this);
NameInput.setVisibility(View.INVISIBLE);

}

public void onClick(View v) {

switch (v.getId()) {
case R.id.start:
setContentView(R.layout.activity_level);
startActivityForResult(new Intent(this,Game.class),1);
break;
case R.id.einstellungen:
setContentView(R.layout.activity_einstellungen);
//Funktionsrumpf
break;
case R.id.highscore:
setContentView(R.layout.activity_highscore);
break;
case R.id.Save:
HighscoreNameWrite();
HighscoreShow();
NameInput.setVisibility(View.VISIBLE);
break;
}
}

@Override
protected void onResume(){
super.onResume();
HighscoreShow();
TextView tv = (TextView) findViewById(R.id.highscore);
tv.setText(Integer.toString(HighscoreRead()));
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1) {
if(resultCode > HighscoreRead()) {
HighscoreWrite(resultCode);
NameInput.setVisibility(View.VISIBLE);
}
}
}

private void HighscoreShow(){
TextView tv = (TextView) findViewById(R.id.highscore);
int highscore = HighscoreRead();
if(highscore>0){
tv.setText(Integer.toString(highscore) + " von " + HighscoreNameRead());
}
else{
tv.setText("-");
}
}

private int HighscoreRead() {
SharedPreferences pref = getSharedPreferences("GAME", 0);
return pref.getInt("Highscore", 0);
}

private String HighscoreNameRead() {
SharedPreferences pref = getSharedPreferences("GAME", 0);
return pref.getString("HIGHSCORE_NAME", "");
}

private void HighscoreWrite(int highscore) {
SharedPreferences pref = getSharedPreferences("GAME", 0);
SharedPreferences.Editor editor = pref.edit();
editor.putInt("Highscore", highscore);
editor.commit();

}

private void HighscoreNameWrite() {
TextView tv = (TextView) findViewById(R.id.PlayerName);
String name = tv.getText().toString().trim();
SharedPreferences pref = getSharedPreferences("GAME", 0);
SharedPreferences.Editor editor = pref.edit();editor.putString("HIGHSCORE_NAME", name);
editor.commit();
}
}
 
Ohne Fehlermeldung sehr schwer zu sagen.
Wie ist denn die Fehlermeldung?

Bei dem Code würde ich raten: "NullPointerException"
Entweder Save oder NameInput oder beide sind null.

Ich würde vermuten die sind nicht im activity_menu vorhanden sondern wahrscheinlich eher hier:
R.layout.activity_highscore

Und da du das erstgenannte Layout lädst findet er natürlich die View nicht.

Desweitere kenn ich dein Buch nicht, aber das ganze mit den verschiedenen setContentView halte ich für einen ganz schlechten Stil.
Eigentlich müsste man dafür jeweils eigene Acitivities machen.
und Letzte Anmerkung:
Variablen namen schreibt man eigentlich klein also so:
private LinearLayout nameInput;
private Button save;

Aber das ist eher Kosmetik.
 
Hallo amfa

Es tut mir leid, dass ich nicht sofort geantwortet habe. Ich war noch ausser Landes und habe erst Heute gesehen, dass Sie geschrieben habe.

Ich glaube ich habe micht nicht klar ausgedrückt. Der Compiler meldet mir keinen Fehler. Wenn ich dann aber die App starte, kommt zuerst der Splashscreen und anschliessend stürzt die App auf dem Tablet ab.

Ich bin Ihnen sehr dankbar wenn sie meinen Programmierstil kritisieren, ich wäre Ihnen dankbar, wenn Sie ihn weiterhin kritisieren würden, um mich zu verbessern.

Was würden Sie vorschlagen, was ich verbessern soll? Was soll ich anstatt setcontentview denn verwenden?

Wenn Sie möchten, sende ich ihnen das ZIP File mit dem ganzen Projekt, falls es ihnen einfacher fällt, den Fehler zu reproduzieren.

Vielen Dank und Entschuldigung nochmals

Bacianthos
 
Ach dafür ist keine Entschuldigung fällig :)

Statt setContentView würde ich eigene Activities machen. die dann jeweils ihr eigenes Layout haben.

Und das Problem habe ich glaube ich schon verstanden.

Wenn ich mich jetzt nicht irrer findet "findViewById" immer nur die gerade geladenen Views.
Wenn man jetzt mit setContentView ein layout setzt findet man nur die Views die auch in diesem layout gesetzt sind nehmen wir als beiSpiel
R.id.Save
In welchem Layout ist dieser Button definiert?
Ich würde fast vermuten in R.layout.activity_highscore
Deswegen findet er den button nicht an dieser Stelle:
Save = (Button) findViewById(R.id.Save);
Weil hier noch
R.layout.activity_menu
Als ContentView gesetzt ist.
Wenn man danach
Save.setOnClickListener(this);

Aufruft ist Save an dieser Stelle null, also nicht definiert.
Dass führt zu einer NullPointerException und somit zum Absturz der App.

Da das ganze in der OnCreate Methode gemacht wird, passiert das direkt nach dem starten der App

Ich hoffe das war soweit verständlich :)
 
Zurück
Oben Unten