2012-03-05 50 views
0

使用Sqlite數據庫,我正在填充我的列表。該列表每分鐘刷新一次(使用定時器)。此外,我更新/插入Sqlite數據庫(使用服務),檢查新的數據。Android Db鎖定

這也正在每分鐘發生。這是工作,但有時「數據庫被鎖定」。我怎樣才能管理這個,而不是得到那個錯誤。感謝您的意見。

public class Services extends Service { 

Context context; 
int NOTIFICATION_ID = 1; 
NotificationManager notificationManager, chatNotificationManager; 
boolean connected = false; 
boolean notconnected = false; 
int numChat = 0; 
int numTask = 0; 
List<String> list = new ArrayList(); 
String android_id, syncDecision; 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
} 

@Override 
public void onStart(Intent intent, int startId) { 
    super.onStart(intent, startId); 
    android_id = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID); 

    context = getBaseContext(); 

    /* 
    * THIS TIMER CONTAINS ANY SERVICE THAT ACCESSES THE SQLite database 
    */ 
    Timer timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask() { 
     public void run() { 
      Log.d(TAG, "starting to do work in timer1"); 
      synchronizeSQLiteDatabases(); 
     } 
    }, 0, 60000); 


private void synchronizeSQLiteDatabases() { 
    try { 

     if (Functions.isOnline(context)) 
     { 
     // ---------------------------------- COMMENT UPLOAD ---------------------------- 
     if (!((GlobalMobileVianet) this.getApplication()).getUserid().equals("000000")) { 
      try 
      { 
       Log.i(TAG, "uploading comment data"); 
       DataUploader_Comment commentupdater = new DataUploader_Comment(((GlobalMobileVianet) this.getApplication()).getUserid(), 
         ((GlobalMobileVianet) this.getApplication()).getPassword(), context); 
       commentupdater.run(); 
      } 
      catch(Exception e) 
      { 
        Log.i(TAG, " CATCH uploading comment data" + e.toString()); 

      } 
     } 
     else 
     { 
      //Functions.logout(getApplicationContext()); 
      Log.i(TAG, " NOT uploading comment data"); 
     } 
     //--------------------------------------- TASK UPLOAD -------------------------------- 
     if (!((GlobalMobileVianet) this.getApplication()).getUserid().equals("000000")) { 

       try{ 
        Log.i(TAG, "uploading task data"); 
        DataUploader_Task taskuploader = new DataUploader_Task(((GlobalMobileVianet) this.getApplication()).getUserid(), 
         ((GlobalMobileVianet) this.getApplication()).getPassword(), context); 
        taskuploader.run(); 
       } 
       catch(Exception e) 
       { 
        Log.i(TAG, " CATCH uploading task data" + e); 

       } 
     } 
     else 
     { 
      //Functions.logout(getApplicationContext()); 
      Log.i(TAG, " NOT uploading task data"); 
     } 

     // ------------------------------------------AC DOWNLOAD --------------------------------- 
     if (!((GlobalMobileVianet) this.getApplication()).getUserid().equals("000000")) { 


       try{ 
        Log.i(TAG, "running aircraft data download"); 
        DataLoader_Aircraft acloader = new DataLoader_Aircraft(((GlobalMobileVianet) this.getApplication()).getUserid(), 
         ((GlobalMobileVianet) this.getApplication()).getPassword(), context, "N"); 
        acloader.run(); 
       } 
       catch(Exception e) 
       { 
        Log.i(TAG, " CATCH running aircraft data download" + e.toString()); 

       } 
     } 
     else 
     { 
      //Functions.logout(getApplicationContext()); 
      Log.i(TAG, " NOT running aircraft data download"); 
     } 

     // ------------------------------------ TASK DOWNLOAD ------------------------------------ 
     if ( !((GlobalMobileVianet) this.getApplication()).getUserid().equals("000000")) { 

      try{ 
       Log.i(TAG, "running task data download"); 
       DataLoader_Task tasksloader = new DataLoader_Task(((GlobalMobileVianet) this.getApplication()).getUserid(), 
         ((GlobalMobileVianet) this.getApplication()).getPassword(), context, "N"); 
       tasksloader.run(); 
      } 
      catch(Exception e) 
      { 
       Log.i(TAG, " CATCH running task data download" + e.toString()); 

      } 
     } 
     else 
     { 
      //Functions.logout(getApplicationContext()); 
      Log.i(TAG, " NOT running task data download"); 
     } 

     // -------------------------------- EMPLOYEE DOWNLOAD ----------------------------------- 
     if (!((GlobalMobileVianet) this.getApplication()).getUserid().equals("000000")) { 

      try 
      { 
       Log.i(TAG, "running employee data download"); 
       DataLoader_Employee employeeloader = new DataLoader_Employee(((GlobalMobileVianet) this.getApplication()).getUserid(), 
         ((GlobalMobileVianet) this.getApplication()).getPassword(), context, "N"); 
       employeeloader.run(); 
      } 
      catch(Exception e) 
      { 
       Log.i(TAG, " CATCH running employee data download " + e.toString()); 

      } 
     } 
     else 
     { 
      //Functions.logout(getApplicationContext()); 
      Log.i(TAG, " NOT running employee data download"); 
     } 

     // ------------------------------------COMMENT DOWNLOAD ----------------------------------------- 
     if (!((GlobalMobileVianet) this.getApplication()).getUserid().equals("000000")) { 

      try{ 
       Log.i(TAG, "running comment data update"); 
       DataLoader_Comment commentloader = new DataLoader_Comment(((GlobalMobileVianet) this.getApplication()).getUserid(), 
         ((GlobalMobileVianet) this.getApplication()).getPassword(), context, "N"); 
       commentloader.run(); 
      } 
      catch(Exception e) 
      { 
       Log.i(TAG, " CATCH running comment data update" + e.toString()); 

      } 
     } 
     else 
     { 
      //Functions.logout(getApplicationContext()); 
      Log.i(TAG, " NOT running comment data download"); 
     } 

     } 
    } catch (Exception e) { 
     Log.e(TAG, 
       "synchronizeSQLiteDatabases exception: " + e.toString()); 
    } 

} 

,這是活動其中刷新列表

public class TestExList extends ExpandableListActivity{ 

String empid, ctext, fleet_name, rString; 
private DbAdapter_Assignment assignment; 
private DbAdapter_Task task; 
private DbAdapter_Comment comment; 
private DbAdapter_Aircraft aircraft; 
private Cursor accursor, taskcursor; 
private ExpandableListView expListView; 
private Timer taskTimer; 
private ListView lv; 
private Camera cam; 
private boolean onoff; 

private boolean testValue; 

private SimpleCursorTreeAdapter cursorTreeAdapter; 

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     empid = getIntent().getExtras().getString("EmpID"); 
     Log.d("testValue","from onCreate, onoff is " + onoff); 

     setHeader(); 

     if(empid.equals(Functions.getLoginEmpID(this))){ 
      getData(empid); 
     } 
     taskTimer = new Timer(); 
     taskTimer.schedule(new TimerTask() { 
      @Override 
      public void run() { 
       TimerMethod(); 
      } 

     }, 0, 60000); 
     expListView.invalidateViews(); 
    } 


    private void TimerMethod() 
    { 
     this.runOnUiThread(Timer_Tick); 
    } 

    private Runnable Timer_Tick = new Runnable() { 
     public void run() { 
       if(Functions.getServiceStatus(getBaseContext()) != "No service") 
       { 
        if(empid.equals(Functions.getLoginEmpID(getBaseContext()))) 
        { 
         getData(empid); 
        } 
       } 
     } 
    }; 
    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 
     try 
     { 
      accursor.close(); 
      taskcursor.close(); 
      task.close(); 
      comment.close(); 
      aircraft.close(); 
      assignment.close(); 
     } 
     catch(Exception e) 
     { 
      Log.e("ViaNetError", "Unable to close cursors."); 
     } 

     if(cam != null) 
     { 
      cam.release(); 
      cam = null; 
     } 
    } 


    public void getData(final String empid) 
    { 
     Log.e("Testing", "Getting data for emp: " + empid); 
     assignment = new DbAdapter_Assignment(getBaseContext()); 
     assignment.open(); 
     task = new DbAdapter_Task (getBaseContext()); 
     task.open(); 
     comment = new DbAdapter_Comment (getBaseContext()); 
     comment.open(); 

    } 
    } 
+0

可能想看看這個:http://stackoverflow.com/questions/4302286/android-simultaneous-db-operations-database-is-locked – 2012-03-05 17:37:47

+0

您是否使用多個DbHelper? – 2012-03-05 17:39:04

+0

我真的不明白你在做什麼,但getData重新分配'assignment','task'和'comment'而不關閉以前的值。如果爲以前打開的每個變量編寫'if(assignment!= null){assignment.close()} [...]'會發生什麼? – louiscoquio 2012-03-05 19:13:05

回答

0

SQLite是告訴你的數據庫在其他線程已經打開。你必須以線程安全的方式使用SQLite。

您可以在打開數據庫和計時器的問題中添加代碼嗎?

2

我與這個完全相同的問題爭論了很長時間,隨機使用我的應用程序打開數據庫將得到一個「數據庫被鎖定」沒有時間或原因。掙扎了好幾個月後,這是我的解決方案。

1)使用類似於普通方法的方法在類中創建dbopenhelper。

2)在APPLICATION類中創建該類的一個實例。

3)打開應用程序類的onCreate中的數據庫,並永不關閉它。

4)通過應用程序類擁有的dbhelper副本運行所有查詢。

我很擔心從不關閉數據庫,但我的研究顯示Android開發人員(IE Google Googles)的許多實例都暗示了這一點。

希望它對你有好處,因爲它對我有用。

+0

我試過這種方法但不工作在我的情況下,請看看我的問題[鏈接在這裏](http://stackoverflow.com/questions/13859840/application-crashes-on-installation-with-error-sqlite3-exec -failed到設置同步) – MobileEvangelist 2012-12-17 10:07:40