2012-07-26 92 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

相关问题