I am working on an Android app but I keep getting a Leak Found error. Here's the Call Stack:
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)
The problem is I don't use a database anywhere in my code.
EDIT:
Here is the code snippet of the whole program. Also I only get this error sometimes and sometimes I don't which is another weird thing.
Here is the main Activity:
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;
}
}
Here is my 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 );
}
}
And lastly here is my开发者_JS百科 second Activity that gets called by the Broadcast receiver when the Alarm goes off:
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
}
}
Let me guess - you're using a rooted phone with a custom ROM. Most likely CyanogenMod? You are probably using a buggy version. See this issue here: http://code.google.com/p/cyanogenmod/issues/detail?id=1512
It's basically coming from the app that manages superuser status and allows apps to become superusers. It doesn't seem to maintain its database properly.
The problem is I don't use a database anywhere in my code.
There can be little doubt that you actually do use SQLite. The second and third lines of the call stack are clear evidence that SQlite is being initialized. Maybe you are using some library that uses SQlite.
If you included more information (including the complete stack trace) it might be easier to tell what was going on.
精彩评论