Я работаю над Android-приложением, но продолжаю получать сообщение об утечке. Вот стек вызовов:Мое приложение для Android продолжает давать мне утечку Найденная ошибка
11-01 11:26:47.087: ERROR/Database(7317): Leak found
11-01 11:26:47.087: ERROR/Database(7317): java.lang.IllegalStateException: /data/data/com.noshufou.android.su/databases/permissions.sqlite SQLiteDatabase created and never closed
11-01 11:26:47.087: ERROR/Database(7317): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1792)
11-01 11:26:47.087: ERROR/Database(7317): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:798)
11-01 11:26:47.087: ERROR/Database(7317): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:857)
11-01 11:26:47.087: ERROR/Database(7317): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:850)
11-01 11:26:47.087: ERROR/Database(7317): at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:535)
11-01 11:26:47.087: ERROR/Database(7317): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
11-01 11:26:47.087: ERROR/Database(7317): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
11-01 11:26:47.087: ERROR/Database(7317): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
11-01 11:26:47.087: ERROR/Database(7317): at com.noshufou.android.su.DBHelper.<init>(DBHelper.java:28)
11-01 11:26:47.087: ERROR/Database(7317): at com.noshufou.android.su.UninstallReceiver.onReceive(UninstallReceiver.java:10)
11-01 11:26:47.087: ERROR/Database(7317): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2637)
11-01 11:26:47.087: ERROR/Database(7317): at android.app.ActivityThread.access$3100(ActivityThread.java:119)
11-01 11:26:47.087: ERROR/Database(7317): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913)
11-01 11:26:47.087: ERROR/Database(7317): at android.os.Handler.dispatchMessage(Handler.java:99)
11-01 11:26:47.087: ERROR/Database(7317): at android.os.Looper.loop(Looper.java:123)
11-01 11:26:47.087: ERROR/Database(7317): at android.app.ActivityThread.main(ActivityThread.java:4363)
11-01 11:26:47.087: ERROR/Database(7317): at java.lang.reflect.Method.invokeNative(Native Method)
11-01 11:26:47.087: ERROR/Database(7317): at java.lang.reflect.Method.invoke(Method.java:521)
11-01 11:26:47.087: ERROR/Database(7317): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
11-01 11:26:47.087: ERROR/Database(7317): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
11-01 11:26:47.087: ERROR/Database(7317): at dalvik.system.NativeStart.main(Native Method)
Проблема в том, что я не использую базу данных нигде в моем коде.
EDIT:
Вот фрагмент кода программы в целом. Кроме того, я иногда получаю эту ошибку, а иногда и не знаю, какая еще странная вещь.
Вот основная активность:
public class SetAlarmUI extends Activity {
TextView mTimeDisplay;
Button setAlarmButton;
private Calendar time;
private int alarmHour;
private int alarmMin;
static final int TIME_DIALOG_ID = 0;
Toast toast;
@Override
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setalarm);
// Holder for the Time, user will set this value later
time = Calendar.getInstance();
// Show the selected time
mTimeDisplay = (TextView) findViewById(R.id.timeText);
// Allow user to select the time for alarm and set it
setAlarmButton = (Button) findViewById(R.id.pickTime);
/***************** LISTENERS ******************/
// add a click listener to the Set Time button
OnClickListener setTimeListener = new OnClickListener() {
// Do this when the Set-Time button is clicked;
public void onClick(View v) {
// Display the Time Selector Dialog box so DEVELOPER can set the alarm
/** This will later be changed so that time is retrieved from a server */
showDialog(TIME_DIALOG_ID); // TIME_DIALOG_ID = a unique ID for the Time Picker Dialog
}
};
Log.e("OUT", "Line 59: Continuing...");
//--------- Assign The Listeners ----------//
setAlarmButton.setOnClickListener(setTimeListener);
/**********************************************/
// get the current time
time.setTimeInMillis(System.currentTimeMillis());
alarmHour = time.get(Calendar.HOUR_OF_DAY);
alarmMin = time.get(Calendar.MINUTE);
// Update the current display
updateDisplay();
}
// updates the time we display in the TextView
private void updateDisplay() {
mTimeDisplay.setText(
new StringBuilder()
.append(pad(alarmHour)).append(":")
.append(pad(alarmMin)));
}
// Fix up the string representation of the time
private static String pad(int c) {
if (c >= 10)
return String.valueOf(c);
else
return "0" + String.valueOf(c);
}
// the callback received when the user "sets" the time in the dialog
private TimePickerDialog.OnTimeSetListener mTimeSetListener =
new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
time.set(Calendar.HOUR_OF_DAY, hourOfDay);
time.set(Calendar.MINUTE, minute);
// Tell user alarm was set
String timeSetTo = "Alarm Set: " + time.get(Calendar.HOUR_OF_DAY) + ":" + time.get(Calendar.MINUTE) + " " + time.get(Calendar.AM_PM);
if(toast != null)
toast.cancel();
toast = Toast.makeText(SetAlarmUI.this, "L" + timeSetTo, Toast.LENGTH_LONG);
toast.show();
// When the alarms goes off we want to send an Intent to our Broadcast Receiver (AlarmAction),
// so set an Intent between the AlarmUI and the AlarmAction
Intent intent = new Intent(SetAlarmUI.this, CallAlarm.class);
// Create an IntentSender to have the intent executed as a broadcast later when alarm goes off.
PendingIntent sender = PendingIntent.getBroadcast(SetAlarmUI.this, 0, intent, 0);
/** Schedule the alarm */
// To get any service we use getSystemService(Service Name)
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
/* Finally, we set the alarm to the desired time! WOOHOO! */
alarmManager.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), sender);
}
};
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case TIME_DIALOG_ID:
return new TimePickerDialog(this,
mTimeSetListener, alarmHour, alarmMin, false);
}
return null;
}
}
Вот мой Broadcast Receiver:
public class CallAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent callDismiss)
{
Toast.makeText(context, R.string.debug, Toast.LENGTH_LONG).show();
Log.e("AlarmAction", context.getResources().getStringArray(R.array.ahadith)[0]);
callDismiss = new Intent(context, DismissUI.class);
context.startActivity(callDismiss);
}
}
И, наконец, вот моя вторая активность, которая вызывается приемником Broadcast, когда тревога уходит:
public class DismissUI extends Activity {
@Override
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
// Display the Hadith
//super.onCreate(savedInstanceState);
setContentView(R.layout.dismiss);
Log.e("DismissUI", "MADE IT TO THE DISMISS!"); /* DEBUG */
// Get the Activity's Layout
LinearLayout mLayout = (LinearLayout) findViewById(R.layout.dismiss);
// Get a hadith from the String xml file and display it
TextView textView = new TextView(this);
textView.setText(getResources().getTextArray(R.array.ahadith)[0]);
// Set the layout for the Text (hadith)
LayoutParams p = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
textView.setLayoutParams(p);
// Add the hadith text to the layout at the beginning hence the ZERO
mLayout.addView(textView, 0);
// Get the Text box for user input
EditText textBox = (EditText) findViewById(R.id.userInput);
// Get the Snooze and Dismiss buttons
// Set listener for Snooze button
// Set listener for Dismiss Button
}
}
Ну, без дополнительной информации (фрагменты кода?), Что мы должны вам сказать? По-видимому, вы должны каким-то образом использовать базу данных, возможно, неявно. – EboMike
Извините, я не хотел вставлять код, потому что он длинный, и я не знаю, какую часть программы нужно вставить. Я напишу как можно больше из кода. –
Но как насчет полной трассировки стека? – EboMike