我几个月前遇到过这个问题,现在是时候回到它了。
我将手机的calllog查询到数据库中,但填充表格大约需要30秒。它看起来像查询需要大约1秒,但人口需要永远,虽然手机只存储最后500个电话。为什么这么慢?我做错了吗?
我只在手机上测试,因为我在模拟器的calllog中只有8个项目。
final String[] projection = null;
HotOrNot infoA = new HotOrNot(Charts.this);
infoA.open();
infoA.createtable_Calls();
infoA.deleteAllEntries_Calls();
infoA.close();
final Context context = getApplicationContext();
final String selection = null;
final String sortOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, projection, selection, null, sortOrder);
while (c.moveToNext()) {
String callLogID = c.getString(c.getColumnIndex(android.provider.CallLog.Calls._ID));
int numberColumn = c.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int dateColumn = c.getColumnIndex(android.provider.CallLog.Calls.DATE);
int typeColumn = c.getColumnIndex(android.provider.CallLog.Calls.TYPE);
int durationColumn = c.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int person = c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
String number = c.getString(numberColumn);
int duration = c.getInt(durationColumn);
String personname = c.getString(person);
long callDate = c.getLong(dateColumn);
int callType = c.getInt(typeColumn);
if (duration >= 0)
{
switch (callType) {
case 1:
duration_in = duration;
duration_out = 0;
break;
case 2:
duration_out = duration;
duration_in = 0;
break;
case 3:
duration_in = 0;
duration_out = 0;
break;
}
}
//Here comes the slow part
HotOrNot info = new HotOrNot(Charts.this);
info.open();
info.pop
ulate_Calls(personname, number, String.valueOf(callType), Integer.toString(duration), Long.toString(callDate), callLogID);
info.close();
}
这是填充功能:
public long populate_Calls(String name, String phone, String type, String duration, String date, String contactid) {
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
cv.put(KEY_PHONE, phone);
cv.put(KEY_TYPE, type);
cv.put(KEY_DURATION, duration);
cv.put(KEY_DATE, date);
cv.put(KEY_CONTACTID, contactid);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}
修改:
对于Andreas Ka和twaddington的答案,我修改了SQLiteOpenHelper类中的填充方法,但不幸的是它并没有什么区别:
public long populate_Calls(String name, String phone, String type, String duration, String date, String contactid) {
ContentValues cv = new ContentValues();
try {
ourDatabase.beginTransaction();
cv.put(KEY_NAME, name);
cv.put(KEY_PHONE, phone);
cv.put(KEY_TYPE, type);
cv.put(KEY_DURATION, duration);
cv.put(KEY_DATE, date);
cv.put(KEY_CONTACTID, contactid);
ourDatabase.yieldIfContendedSafely();
ourDatabase.setTransactionSuccessful();
} finally {
ourDatabase.endTransaction();
}
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}
EDIT2: 根据Babibu和twaddington的答案发布整个代码。顺便说一句,temp_数组现在是LinkedLists,但这并没有带来时间上的差异。
final String[] projection = null;
final Context context = getApplicationContext();
final String selection = null;
final String sortOrder = android.provider.CallLog.Calls.DATE + " DESC";
lv1 = (ListView) findViewById(R.id.ListView02);
HotOrNot infoA = new HotOrNot(Calllogs.this);
infoA.open();
infoA.createtable_Calls();
infoA.deleteAllEntries_Calls();
infoA.close();
pd = ProgressDialog.show(Calllogs.this, "Please wait..", "Loading data, it may take a few" +
" seconds based on the number of data.", false, true);
Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, projection, selection, null, sortOrder);
while (c.moveToNext()) {
String callLogID = c.getString(c.getColumnIndex(android.provider.CallLog.Calls._ID));
int numberColumn = c.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int dateColumn = c.getColumnIndex(android.provider.CallLog.Calls.DATE);
int typeColumn = c.getColumnIndex(android.provider.CallLog.Calls.TYPE);
int durationColumn = c.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int person = c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
String number = c.getString(numberColumn);
int duration = c.getInt(durationColumn);
String personname = c.getString(person);
long callDate = c.getLong(dateColumn);
int callType = c.getInt(typeColumn);
if (duration >= 0)
{
switch (callType) {
case 1:
duration_in = duration;
duration_out = 0;
break;
case 2:
duration_out = duration;
duration_in = 0;
break;
case 3:
duration_in = 0;
duration_out = 0;
break;
}
}
temp_name.add(personname);
temp_num.add(number);
temp_type.add(String.valueOf(callType));
temp_dur.add(Integer.toString(duration));
temp_date.add(String.valueOf(callDate));
temp_id.add(callLogID);
} //end of while loop
HotOrNot infotemp = new HotOrNot(Calllogs.this);
infotemp.open();
for (int i=0; i<temp_name.size(); i++)
{
infotemp.populate_Calls(temp_name.get(i), temp_num.get(i), temp_type.get(i), temp_dur.get(i), temp_date.get(i), temp_type.get(i));
}
infotemp.close();
解
我发布了twaddington的解决方案,将时间从8秒减少到不到2秒:
HotOrNot infotemp = new HotOrNot(Calllogs.this);
infotemp.open();
// Get our database. You can do this however you wish, but
// it seems like since the database is contained in your `HotOrNot`
// object, it would be best to simply add a getter method to
// the class.
SQLiteDatabase db = infotemp.getDatabase();
try {
// Begin our transaction
db.beginTransaction();
// Loop over the array of calls and
// perform a db insert for each.
for (int i=0; i<temp_name.size(); i++) {
// Yield the database lock if requested. This will
// temporarily suspend our loop, but it should
// continue when the lock is opened.
db.yieldIfContendedSafely();
infotemp.populate_Calls(temp_name.get(i), temp_num.get(i),
temp_type.get(i), temp_dur.get(i), temp_date.get(i), temp_type.get(i));
}
// Mark our transaction as successful!
db.setTransactionSuccessful();
} finally {
// Always end the transaction!
db.endTransaction();
}
infotemp.close();
答案 0 :(得分:2)
对于您对SQLite数据库所做的每一个更改都是一系列复杂的 步骤发生,包括创建journal file以回滚 如果发生错误则更改。您可以将一系列更新包装在数据库中 事务强制SQLite将整个系列视为单个操作。 这会更有效率。
try {
db.beginTransaction();
while (c.moveToNext()) {
// Yield the database lock if requested
db.yieldIfContendedSafely();
// Add your code here!
// ...
// Perform the database insert
populate_Calls(...);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
答案 1 :(得分:1)
答案 2 :(得分:1)
您在浏览时插入,这会锁定您的数据库。您需要先完成while循环,然后才将其插入数据库中。只需将数据保存在同一个临时链接列表中(在您的情况下,最好是数组,因为它可以快速插入)