Hilfsklasse zum Speichern - NPE

  • 4 Antworten
  • Letztes Antwortdatum
K

klettertiger

Neues Mitglied
0
Hallo zusammen!

Ich würde mich freuen, wenn ihr mir einen Tipp geben könnt. :thumbsup:
Ich möchte eine Hilfsklasse mit Speichern/Laden Funktion ins Programm einbinden.
Leider taucht beim Ausführen der Funktionen dieser Klasse immer eine NPE auf.

Die Testfunktion "test" derselben Klasse läuft ohne Probleme.

Aber z.B. bei der Funktion save wird das Programm abgebrochen.

Code:
public void save (String data, String file) {
		 try {
		FileOutputStream os = openFileOutput(file, MODE_PRIVATE);
		OutputStreamWriter out = new OutputStreamWriter(os);
		BufferedWriter buffi = new BufferedWriter(out);
		buffi.write(data);
		buffi.close();
		out.close();
		os.close();
		} catch (IOException ex) { Log.e("Save", ex.getMessage());
		} }
	
}

Dies ist die Fehlermeldung dazu:

Code:
02-04 04:32:14.644: E/AndroidRuntime(5326): FATAL EXCEPTION: main
02-04 04:32:14.644: E/AndroidRuntime(5326): java.lang.NullPointerException
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:165)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at com.example.my_cat.SaveLoad.save(SaveLoad.java:48)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at com.example.my_cat.Hauptmenue$1.onClick(Hauptmenue.java:96)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at android.view.View.performClick(View.java:3511)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at android.view.View$PerformClick.run(View.java:14105)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at android.os.Handler.handleCallback(Handler.java:605)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at android.os.Handler.dispatchMessage(Handler.java:92)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at android.os.Looper.loop(Looper.java:137)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at android.app.ActivityThread.main(ActivityThread.java:4424)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at java.lang.reflect.Method.invokeNative(Native Method)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at java.lang.reflect.Method.invoke(Method.java:511)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-04 04:32:14.644: E/AndroidRuntime(5326): 	at dalvik.system.NativeStart.main(Native Method)

Und das der komplette Code der Klasse.
Er compiliert einwandfrei.

Code:
package com.example.my_cat;

import java.io.*;
import android.*;


public class SaveLoad extends Activity{
	
	
	SaveLoad(){	
	}
	
	public String test(){
		return "Hallo";
	}
	
	public  String load (String file){
		  try {
			  String result;
				FileInputStream is = openFileInput(file); 
				InputStreamReader in = new InputStreamReader(is); 
				BufferedReader buffi = new BufferedReader(in);
				result= buffi.readLine();
		buffi.close(); in.close(); is.close();
		return result;
		} catch (IOException ex) {
		                return null;
		                }}
	
	public void save (String data, String file) {
		 try {
		FileOutputStream os = openFileOutput(file, MODE_PRIVATE);
		OutputStreamWriter out = new OutputStreamWriter(os);
		BufferedWriter buffi = new BufferedWriter(out);
		buffi.write(data);
		buffi.close();
		out.close();
		os.close();
		} catch (IOException ex) { Log.e("Save", ex.getMessage());
		} }
	
}

Ich hoffe, ich kann euch - sobald ich selbst mehr Ahnung habe - bei Problemen selbst ein wenig behilflich sein.

Vielen Dank an alle, die sich die Mühe machen, den Code zu lesen!

Gruß
Stefan
 
wo rufst du denn die methode auf?

machst du irgendwo
SaveLoad saveLoad = new SaveLoad();
saveLoad.save("data", "filename");
?

Das Problem dürfte sein, dass du keinen Context hast würde ich sagen.
Hab gerade mal in den Android SourceCode geguckt.
Der Nonargument Constructor hat keinen Context und somit ist der dann Null.

Du solltest eine Activity niemals einfach so erstellen, da fehlen ja alle lifecycle methoden.

"extends Activity" das ist hier definitiv falsch.
 
Hallo amfa!

wo rufst du denn die methode auf?
machst du irgendwo
SaveLoad saveLoad = new SaveLoad();
saveLoad.save("data", "filename");?

Ja, über jeweils einen Button, mit eignen OnClickListener.
Die Testmethode von SaveLoad zur Anzeige von "Hallo" funktioniert damit ja einwandfrei.
Hier der restliche Code:
init(): saveloadContent = new SaveLoad();
initOnClickListener(): sämtliche OnClickListener

Wie du siehst, hab ich in dieser Klasse die selben zwei Methoden: save und load. Hier funktionieren sie aber. Einzig wenn ich sie von der anderen Klasse her aufrufe kommts zu dem Fehler.

Code:
package com.example.my_cat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Hauptmenue extends Activity {

	private static final String TAG = null;
	Button load = null;
	Button save = null;
	Button clear = null;
	EditText anzeige = null;
	SaveLoad saveloadContent = null;

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

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.hauptmenue, menu);
		return true;
	}

	void init() {

		anzeige = (EditText) findViewById(R.id.hauptmenue_EditText);
		load = (Button) findViewById(R.id.hauptmenue_load);
		save = (Button) findViewById(R.id.hauptmenue_save);
		clear = (Button) findViewById(R.id.hauptmenue_clear);
		saveloadContent = new SaveLoad();

	}

	public String load(String file) {
		try {
			String result;
			FileInputStream is = openFileInput(file);
			InputStreamReader in = new InputStreamReader(is);
			BufferedReader buffi = new BufferedReader(in);
			result = buffi.readLine();
			buffi.close();
			in.close();
			is.close();
			
			return result;
		} catch (IOException ex) {
			
			return null;
		}
	}

	public void save(String data, String file) {
		try {
			FileOutputStream os = openFileOutput(file, MODE_PRIVATE);
			OutputStreamWriter out = new OutputStreamWriter(os);
			BufferedWriter buffi = new BufferedWriter(out);
			buffi.write(data);
			buffi.close();
			out.close();
			os.close();
			Log.d(TAG, getDir(file, MODE_PRIVATE).getAbsolutePath());
		} catch (IOException ex) {
			Log.e("Save", ex.getMessage());
		}
	}

	void initOnClickListener() {

		save.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				//save(anzeige.getText().toString(), "data.txt");
				//anzeige.setText(saveloadContent.test());
				 saveloadContent.save(anzeige.getText().toString(),  "data.txt");
			}
		});

		load.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				
				//anzeige.setText(load("data.txt"));
				 anzeige.setText(saveloadContent.load("data.txt"));
			}
		});

		clear.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				anzeige.setText("");
			}
		});

	}
	

}



Das Problem dürfte sein, dass du keinen Context hast würde ich sagen.
Hab gerade mal in den Android SourceCode geguckt.
Der Nonargument Constructor hat keinen Context und somit ist der dann Null.

Kannst mir da etwas mehr zu sagen?
Was ich so dazu ergoogelt habe, ist mehr ein Schuss ins Blaue.

Du solltest eine Activity niemals einfach so erstellen, da fehlen ja alle lifecycle methoden.

"extends Activity" das ist hier definitiv falsch.
Das dachte ich mir auch, aber sobald ich es weglasse, bekomme ich bei
FileInputStream is = openFileInput(file);
Code:
The method openFileInput(String) is undefined for the type 
 SaveLoad
Bei FileOutputStream os = openFileOutput(file, MODE_PRIVATE);
erkennt er mir dann MODE_PRIVATE nicht.
Das war eigentlich der einzige Grund dafür, dass ich es eingefügt habe.
 
Ja das ist normal weil Mode_PRIVATE und die methode openFileOutput aus der Activity kommen.
Das Problem ist du hast dir jetzt eine neue Activity gebaut.
Wenn die Activity von Android selber aufgerufen wird (z.B. dein Hauptmenue) dann setzt das System z.B. den Context und ruft zur richtigen Zeit auch die anderen Methoden auf wie z.B. onCreate(), OnPause, OnResume usw.

Wenn du die allerdings einfach so startest fehlt das ganze drumherum was Android normalerweise mit einer Acitivity macht.

Was du machen kannst ist aber z.B. folgendes:
Code:
package com.example.my_cat;
    import java.io.*;
    import android.*;
    public class SaveLoad{   
    private Context context;         
    SaveLoad(Context context){
    this.context = context;    
    }         
    public String test(){       
     return "Hallo";     
     }         

    public  String load (String file){
        try {               
            String result;                 
            FileInputStream is = context.openFileInput(file);                  
            InputStreamReader in = new InputStreamReader(is);                  
            BufferedReader buffi = new BufferedReader(in);                 
            result= buffi.readLine();         
            buffi.close(); 
            in.close(); 
            is.close();         
            return result;         
            } 
        catch (IOException ex) {
                return null;
            }}
    public void save (String data, String file) {
            try {         
                FileOutputStream os = context.openFileOutput(file, context.MODE_PRIVATE);
                OutputStreamWriter out = new OutputStreamWriter(os);         
                BufferedWriter buffi = new BufferedWriter(out);
                buffi.write(data);        
                buffi.close();        
                out.close();       
                os.close();     
            } 
            catch (IOException ex) {
                Log.e("Save", ex.getMessage());       
                } 
            }      
    }
Und in deiner Acitivity machst du dann:

saveloadContent = new SaveLoad(this);

Damit hast du dann den Context der aktuellen Activity in deiner anderen Klasse und kannst alle methoden davon ausrufen.
 
Zuletzt bearbeitet:
:drool:

Is ja geil.
Jetzt komm ich mit. :scared:


Vielen Dank, amfa!!
 
Zurück
Oben Unten