Meine App scheint also gut zu funktionieren, solange ich aktiv telefoniere. Ich kann den Bildschirm drehen, die App schließen, wieder öffnen, was auch immer, keine Probleme.Stürzt meine App ab, weil ich meine Datenbank Singleton falsch implementiert habe?
Aber wenn ich den Home/Back-Knopf drücke und die App in den Hintergrund sende, und wenn ich dann für die Nacht ins Bett gehe, wenn ich einige Stunden später aufwache und versuche, die App wieder zu öffnen, stürzt sie sofort ab . Ich habe keine Ahnung, was diesen Fehler verursacht, aber ich nehme an, dass es mit einem NullPointerException
(der Fluch meiner Existenz zu diesem Zeitpunkt) zu tun hat, weil Android beschlossen hat, etwas für den Speicher freizugeben.
Ich konsultierte dieses Diagramm:
Also, wenn ich die App in den Hintergrund senden, geht es zu onStop()
, und dann schließlich Android kann etwas Speicher frei und den Prozess töten, ich so, wenn öffne die App erneut, sie versucht onCreate()
aufzurufen, außer jetzt stürzt onCreate()
ab. Das ergab für mich keinen Sinn.
Der einzige andere Grund, den ich mir vorstellen konnte, war die Tatsache, dass ich eine SQLite3
Datenbank Singleton in meiner App verwende, die irgendwie von Android aufgefressen wird und Speicher freigibt. Im onCreate()
Methode aller mein Activities
und Fragments
Ich nenne typischerweise mDatabaseHelper = DatabaseHelper.getInstance(context);
(wo die context
ist in der Regel entweder this
, wenn ich in einem Activity
bin, oder getActivity()
wenn ich in einem Fragment
bin).
Das ist mein DatabaseHelper
Klasse:
public class DatabaseHelper extends SQLiteOpenHelper {
private static volatile SQLiteDatabase mDatabase;
private static DatabaseHelper mInstance = null;
private static Context mContext;
//... various constant fields here ...
public static synchronized DatabaseHelper getInstance(Context context){
if (mInstance == null){
mInstance = new DatabaseHelper(context.getApplicationContext());
}
return mInstance;
}
private DatabaseHelper(Context context){
super(context, DB_NAME, null, DB_VERSION);
mContext = context;
}
public void open() throws SQLException {
mDatabase = getWritableDatabase();
}
public void close(){
mDatabase.close();
}
//... other functions here ...
}
In meiner Abschuss Aktivität (MainActivity
), Ich tue dies:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DatabaseHelper databaseHelper = DatabaseHelper.getInstance(this);
databaseHelper.open();
Intent intent = new Intent(this, AnotherActivity.class);
startActivity(intent);
finish();
}
}
Dies ist die einzige Zeit, die ich je open()
in der gesamten App aufrufen. Ich rufe nie close()
überall an.
Erklärt dies, was meine App zum Absturz bringt? Da ich getInstance()
in meinem onCreate
Methoden aufrufen (die aufgerufen werden, wenn ich die App nach einer langen Leerlaufperiode wieder aufnehmen), führt dies zu dem Verdacht, dass in dieser Funktion etwas schief geht. Kann Android jemals Speicher freigeben, indem er den Anwendungskontext irgendwie zerstört? Ist es möglich, dass mDatabase
irgendwie auf null
gesetzt wird? Was muss ich noch tun, um sicherzustellen, dass ich diese Datenbank richtig implementiert habe?
Sie sollten auch Ihre Stacktrace hier –
habe ich nicht über einen Stacktrace weil dieser Absturz tritt nur auf, wenn ich die App auf meinem Handy installiert haben und ließ es allein für mehrere Stunden.Ich kann den Fehler nicht in meinem Emulator/Android Studio replizieren (der einzige Ort, an dem ich die Stacktrace-/Fehlerprotokolle sehen kann, wenn die Fehler tatsächlich auftreten). –
Sie können den Absturzbericht von Ihrem Telefon senden, wenn es stürzt, denke ich. Versuch das? Laden Sie es im Alpha-Testmodus in den Laden, warten Sie, bis es abstürzt, und senden Sie den Bericht. – Vucko