2010-10-31 62 views
1

我正在开发一个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) 

问题是我不在我的代码中的任何地方使用数据库。

编辑:

这里是整个程序的代码片段。此外,我只是有时会得到这个错误,有时我不会这是另一个奇怪的事情。

这里是主要的活动:

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; 
} 
} 

这里是我的广播接收器:

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); 
} 
} 

最后一点,这里是我是被由广播接收器,当警报响起时称为第二个活动:

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 

} 
} 
+0

那么,没有更多的信息(代码片段?),我们应该告诉你什么?显然,你必须以某种方式使用数据库,也许是隐含的。 – EboMike 2010-10-31 06:36:31

+0

对不起,我不想粘贴代码,因为它很长,我不知道要粘贴哪个程序部分。我会尽可能地从代码中发布信息。 – 2010-11-01 13:25:28

+0

但是完整的堆栈跟踪呢? – EboMike 2010-11-01 14:50:34

回答

2

让我猜 - 你正在使用一个带有定制ROM的固定电话。最有可能的是CyanogenMod?您可能正在使用越野车版本。在这里看到这个问题:http://code.google.com/p/cyanogenmod/issues/detail?id=1512

它基本上来自管理超级用户状态,并允许应用程序成为超级用户的应用程序。它似乎没有妥善维护其数据库。

+0

这适合,在回溯中给出'com.noshufou.android.su'。 – hobbs 2010-11-02 03:36:54

+0

哇..去图。谢谢,我也期待着。感谢您的链接 – 2010-11-02 18:22:02

0

这个问题我我不在我的代码中的任何地方使用数据库。

可以毫不怀疑,你实际上使用SQLite。调用堆栈的第二行和第三行清楚地表明SQlite正在被初始化。也许你正在使用一些使用SQlite的库。

如果您包含更多信息(包括完整的堆栈跟踪),可能更容易分辨出发生了什么。

相关问题