2012-07-26 88 views
0

我必須將大型的在線csv(30k + rows)文件導入到我的應用程序的數據庫中。我怎麼能在另一個線程或一個asynctask中做到這一點?Android如何在另一個線程上執行db插入?

我正在處理這段代碼。它繼續onCreate

final ProgressDialog Dialog = ProgressDialog.show(
      this, "Updating schedule", "This may take a few minutes...", true, false); 

    Thread thread = new Thread(new Runnable() { 
     public void run() { 
      DatabaseHandler db = new DatabaseHandler(MainActivity.this); 

      //**How do I begin transaction here?** 

      URL myURL; 
      try { 
       myURL = new URL("http://www.meralco.com.ph/pms/pms.csv"); 

       BufferedReader so = new BufferedReader(new InputStreamReader(myURL.openStream())); 
       while (true) { 
        String output = so.readLine(); 
        if (output != null) { 
         String[] sched = output.split(","); 
         db.addRow(sched[INDEX_SIN], sched[INDEX_CITY], 
           sched[INDEX_START_DATE], sched[INDEX_START_TIME], 
           sched[INDEX_END_DATE], sched[INDEX_END_TIME], 
           sched[INDEX_DETAILS], sched[INDEX_REASON]); 
        } 
        else { 
         break; 
        } 
       } 

       //**How do I close transaction here?** 
       so.close(); 
      } 
      catch (MalformedURLException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


      runOnUiThread(new Runnable() { 
       public void run() { 
        while (!Dialog.isShowing()); 
        Dialog.dismiss(); 
       } 
      }); 
     } 

    }); 
    thread.start(); 

DatabaseHandler.java

public class DatabaseHandler{ 

public static final String KEY_SIN = "sched_sin"; 
public static final String KEY_CITY = "sched_city"; 
public static final String KEY_START_TIME = "sched_start_time"; 
public static final String KEY_START_DATE= "sched_start_date"; 
public static final String KEY_END_TIME = "sched_end_time"; 
public static final String KEY_END_DATE = "sched_end_date"; 
public static final String KEY_DETAILS = "sched_details"; 
public static final String KEY_REASON = "sched_reason"; 
public static final String KEY_ROWID = "_id"; 

private static final String TAG = "DatabaseHandler"; 
private SQLiteDatabase mDb; 

private static final String DATABASE_NAME = "schedule_database"; 
private static final String DATABASE_TABLE = "schedule"; 
private static final int DATABASE_VERSION = 1; 

private static final String DATABASE_CREATE = 
    "create table " + DATABASE_TABLE + " (" + KEY_ROWID + " integer primary key autoincrement, " 
    + KEY_SIN +" text not null, " + KEY_CITY + " text not null, " 
    + KEY_START_DATE +" text not null, " + KEY_START_TIME + " text not null, " 
    + KEY_END_DATE +" text not null, " + KEY_END_TIME + " text not null, " 
    + KEY_DETAILS +" text not null, " + KEY_REASON + " text not null);"; 

private final Context mCtx; 

public DatabaseHandler(Context ctx) { 
    this.mCtx = ctx; 

    // create or open the database 
    DatabaseHelper helper = new DatabaseHelper(ctx); 
    this.mDb = helper.getWritableDatabase(); 
} 

public void addRow(String sin, String city, String start_date, String start_time, 
     String end_date,String end_time, String details, String reason) 
{ 
    // this is a key value pair holder used by android's SQLite functions 
    ContentValues values = new ContentValues(); 

    values.put(KEY_SIN, sin); 
    values.put(KEY_CITY, city); 
    values.put(KEY_START_DATE, start_date); 
    values.put(KEY_START_TIME, start_time); 
    values.put(KEY_END_DATE, end_date); 
    values.put(KEY_END_TIME, end_time); 
    values.put(KEY_DETAILS, details); 
    values.put(KEY_REASON, reason); 

    // ask the database object to insert the new data 
    try 
    { 
     this.mDb.insert(DATABASE_TABLE, null, values); 
    } 
    catch(Exception e) 
    { 
     Log.e("DB ERROR", e.toString()); // prints the error message to the log 
     e.printStackTrace(); // prints the stack trace to the log 
    } 
} 

public ArrayList<ArrayList<Object>> getAllRowsAsArrays() 
{ 
    // create an ArrayList that will hold all of the data collected from 
    // the database. 
    ArrayList<ArrayList<Object>> dataArrays = new ArrayList<ArrayList<Object>>(); 

    // this is a database call that creates a "cursor" object. 
    // the cursor object store the information collected from the 
    // database and is used to iterate through the data. 
    Cursor cursor; 

    try 
    { 
     // ask the database object to create the cursor. 
     cursor = this.mDb.query(
       DATABASE_TABLE, 
       new String[]{KEY_ROWID, KEY_SIN, KEY_CITY, KEY_START_DATE, KEY_START_TIME, KEY_END_DATE, KEY_END_TIME, KEY_DETAILS, KEY_REASON}, 
       null, null, null, null, null 
     ); 

     // move the cursor's pointer to position zero. 
     cursor.moveToFirst(); 

     // if there is data after the current cursor position, add it 
     // to the ArrayList. 
     if (!cursor.isAfterLast()) 
     { 
      do 
      { 
       ArrayList<Object> dataList = new ArrayList<Object>(); 

       dataList.add(cursor.getLong(0)); 
       dataList.add(cursor.getString(1)); 
       dataList.add(cursor.getString(2)); 
       dataList.add(cursor.getString(3)); 
       dataList.add(cursor.getString(4)); 
       dataList.add(cursor.getString(5)); 
       dataList.add(cursor.getString(6)); 
       dataList.add(cursor.getString(7)); 
       dataList.add(cursor.getString(8)); 

       dataArrays.add(dataList); 
      } 
      // move the cursor's pointer up one position. 
      while (cursor.moveToNext()); 
     } 
    } 
    catch (SQLException e) 
    { 
     Log.e("DB Error", e.toString()); 
     e.printStackTrace(); 
    } 

    // return the ArrayList that holds the data collected from 
    // the database. 
    return dataArrays; 
} 

private static class DatabaseHelper extends SQLiteOpenHelper { 

    DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     Log.i(TAG, "Creating DataBase: " + DATABASE_CREATE); 
     db.execSQL(DATABASE_CREATE); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w(TAG, "Upgrading database from version " + oldVersion + " to " 
       + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE); 
     onCreate(db); 
    } 
} 
} 

編輯 另外,我使用beginTransaction()endTransaction因爲我不能使用它的線程裏面有問題。

public final class DownloadFile extends AsyncTask<Void, Long, Boolean> { 

private Context context; 
private ProgressDialog progressDialog; 

public DownloadFile (Context context) { 
    this.context = context; 
} 

/* 
* @see android.os.AsyncTask#onPreExecute() 
*/ 
@Override 
protected void onPreExecute() { 
    try { 
     progressDialog = ProgressDialog.show(context, "", "message", true); 
    } catch (final Throwable th) { 
     //TODO 
    } 
} 

protected Boolean doInBackground(Void... arg0) { 
    DatabaseHandler db = new DatabaseHandler(context); 

      //**How do I begin transaction here?** 

     URL myURL; 
     try { 
      myURL = new URL("http://www.meralco.com.ph/pms/pms.csv"); 

      BufferedReader so = new BufferedReader(new InputStreamReader(myURL.openStream())); 
      while (true) { 
       String output = so.readLine(); 
       if (output != null) { 
        String[] sched = output.split(","); 
        db.addRow(sched[INDEX_SIN], sched[INDEX_CITY], 
          sched[INDEX_START_DATE], sched[INDEX_START_TIME], 
          sched[INDEX_END_DATE], sched[INDEX_END_TIME], 
          sched[INDEX_DETAILS], sched[INDEX_REASON]); 
       } 
       else { 
        break; 
       } 
      } 

      //**How do I close transaction here?** 
      so.close(); 
      return true; 
     } 
     catch (MalformedURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      return false; 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      return false; 
     } 
} 

protected void onPostExecute(Boolean result) { 
    progressDialog.dismiss(); 
} 
} 

回答

0

下面是爲我工作的代碼:它

public void beginTransaction(){ 
    this.mDb.beginTransaction(); 
} 

public void endTransaction(String sql){ 
    this.mDb.endTransaction(); 
} 
0

像下面說的方法是不確定的......。我注意到使用Threads代替AsyncTask時下載速度更快,所以我選擇了前者。正如@JoxTraex指出的那樣,我使用了一個csv解析器(在這種情況下,我使用OpenCSV的閱讀器)而不是一個完整的工作模塊。它消除了我在每個逗號分裂的問題,即使一個雙引號中包含了一個值。

Thread downloadThread = new Thread(new Runnable() { 

    public void run() { 

     db = new DatabaseHandler(MainActivity.this); 
     db.beginTransaction(); 

     try { 
      URL url = new URL(csvFileName); 

      Log.i("dl", "start"); 

      InputStream input = url.openStream(); 
      CSVReader reader = new CSVReader(new InputStreamReader(input)); 

      String [] sched; 
      while ((sched = reader.readNext()) != null) { 
       if(sched[INDEX_CITY].equals("")) sched[INDEX_CITY]="OTHERS"; 
       try { 

        db.addRow(sched[INDEX_SIN], sched[INDEX_CITY], 
          sched[INDEX_START_DATE], sched[INDEX_START_TIME], 
          sched[INDEX_END_DATE], sched[INDEX_END_TIME], 
          sched[INDEX_DETAILS], sched[INDEX_REASON]); 
       } catch (IndexOutOfBoundsException e) { 
        db.addRow(sched[INDEX_SIN], sched[INDEX_CITY], 
          sched[INDEX_START_DATE], sched[INDEX_START_TIME], 
          sched[INDEX_END_DATE], sched[INDEX_END_TIME], 
          "", sched[INDEX_REASON]); 
        //e.printStackTrace(); 
       } 
      } 
      input.close(); 
      Log.i("dl", "finished"); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
      db.endTransaction(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      db.endTransaction(); 
     } 
     Log.d("Count", ""+db.count()); 
     db.setTransactionSuccessful(); 
     db.endTransaction(); 

     writeUploadDateInTextFile(); 

    } 

}); 

在我的數據庫處理類,

public void beginTransaction(){ 
    this.mDb.beginTransaction(); 
} 

public void endTransaction(String sql){ 
    this.mDb.endTransaction(); 
} 
+0

閱讀的CSV文件會比一個完整的工作代碼塊更有效的參考。 – JoxTraex 2012-07-26 07:59:32

+0

@JoxTraex因此,最好使用像[OpenCSV](http://opencsv.sourceforge.net/)這樣的csv解析器,然後使用它返回的'List '將它保存到數據庫中? – yojoannn 2012-07-26 08:12:44

相關問題