Android应用中SQLite数据填充进度条的实现方案咨询
如何在Android中结合第三方进度条跟踪SQLite数据填充进度?
我希望在Android应用中实现一个进度条,用于跟踪SQLite数据库的数据填充进度,完成后显示“100%”或提示数据加载完成。计划使用第三方进度条库。以下是我从HTML页面获取数据并写入SQLite的类代码,请问如何结合它实现进度条?
public class articoli extends AppCompatActivity { String htmlresultart; Integer DaDoveParto = 0; Integer DoveMiFermo = 0; Integer QuanteRighe = 0; Integer QuantiCampi = 0; String appCAMPOart = ""; String[] appBODYart = new String[9]; DataBaseHandler myDB; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_articoli); myDB = DataBaseHandler.getInstance(this); myDB.delete(); getHTMLArticoli(); } private void getHTMLArticoli(){ Ion.with(getApplicationContext()) .load("WEPPAGEIP") .asString() .setCallback(new FutureCallback<String>() { @SuppressLint("SetTextI18n") @Override public void onCompleted(Exception e, String result) { htmlresultart = result; htmlresultart = htmlresultart.replace("</td>", "\n"); getBodyArticoli(); } }); } private void getBodyArticoli(){ DaDoveParto = Integer.valueOf(String.valueOf(htmlresultart.indexOf("TBLCRP"))); DoveMiFermo = Integer.valueOf(String.valueOf(htmlresultart.indexOf("</form>"))); if(DaDoveParto == 0){ Toast.makeText(this,"NESSUN DATO TROVATO",Toast.LENGTH_SHORT).show(); }else { Integer i; Integer j; Integer CONTACAMPO = 0; for( i = DaDoveParto ; i <= DoveMiFermo ; i++){ if( htmlresultart.substring(i, i + 4).equals("<td>")){ i += 4; for (j = i; j <= DoveMiFermo ; j++){ if(htmlresultart.substring(j, j + 1).equals("\n")){ appBODYart[CONTACAMPO] = htmlresultart.substring(i, i + (j - i)); if(appBODYart[CONTACAMPO].equals("(null)")){ appBODYart[CONTACAMPO] = ""; } CONTACAMPO += 1; if(CONTACAMPO.equals(QuantiCampi)){ CONTACAMPO = 0; myDB.insertArtServer(appBODYart[0], appBODYart[1], appBODYart[2], appBODYart[3], appBODYart[4], appBODYart[5], appBODYart[6], appBODYart[7], appBODYart[8]); } break; } } } } } } }
解决方案:一步步整合进度条
咱们分步骤来实现这个需求,既要保证进度条能实时更新,又要避免UI线程阻塞导致ANR:
1. 先在布局文件中添加第三方进度条
打开activity_articoli.xml,添加你选择的第三方进度条(以常见的圆形进度条为例),同时搭配一个文本显示当前进度:
<!-- 替换为你使用的第三方进度条全类名 --> <com.yourpackage.ThirdPartyProgressBar android:id="@+id/progress_bar" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true"/> <TextView android:id="@+id/progress_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/progress_bar" android:layout_centerHorizontal="true" android:text="0%"/>
2. 在Activity中初始化进度条相关变量
在articoli类中添加进度条和文本的实例变量,并在onCreate中完成初始化:
public class articoli extends AppCompatActivity { // 原有的变量... private ThirdPartyProgressBar mProgressBar; private TextView mProgressText; private int mInsertedCount = 0; // 已插入的数据条数 private int mTotalCount = 0; // 总数据条数 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_articoli); // 初始化进度条组件 mProgressBar = findViewById(R.id.progress_bar); mProgressText = findViewById(R.id.progress_text); // 原有代码... } }
3. 先统计总数据条数
在解析HTML并插入数据前,先遍历一次内容统计总条数(每条对应9个字段),这样才能计算精准的进度百分比:
private void getBodyArticoli(){ DaDoveParto = Integer.valueOf(String.valueOf(htmlresultart.indexOf("TBLCRP"))); DoveMiFermo = Integer.valueOf(String.valueOf(htmlresultart.indexOf("</form>"))); if(DaDoveParto == 0){ Toast.makeText(this,"NESSUN DATO TROVATO",Toast.LENGTH_SHORT).show(); return; } // 第一步:统计总数据条数 int totalTdCount = 0; for(int i = DaDoveParto ; i <= DoveMiFermo ; i++){ if(htmlresultart.substring(i, i + 4).equals("<td>")){ totalTdCount++; i += 4; // 跳过<td>标签,避免重复统计 } } // 每条数据对应9个字段,计算总条数 mTotalCount = totalTdCount / 9; mInsertedCount = 0; // 第二步:开始解析并插入数据 Integer i; Integer j; Integer CONTACAMPO = 0; for( i = DaDoveParto ; i <= DoveMiFermo ; i++){ if( htmlresultart.substring(i, i + 4).equals("<td>")){ i += 4; for (j = i; j <= DoveMiFermo ; j++){ if(htmlresultart.substring(j, j + 1).equals("\n")){ appBODYart[CONTACAMPO] = htmlresultart.substring(i, i + (j - i)); if(appBODYart[CONTACAMPO].equals("(null)")){ appBODYart[CONTACAMPO] = ""; } CONTACAMPO += 1; if(CONTACAMPO.equals(9)){ // 这里直接用9,对应你的9个字段数组 CONTACAMPO = 0; // 插入数据后更新计数和进度 mInsertedCount++; updateProgress(); myDB.insertArtServer(appBODYart[0], appBODYart[1], appBODYart[2], appBODYart[3], appBODYart[4], appBODYart[5], appBODYart[6], appBODYart[7], appBODYart[8]); } break; } } } } // 所有数据插入完成后,更新进度为100%并提示 runOnUiThread(() -> { mProgressBar.setProgress(100); mProgressText.setText("100%"); Toast.makeText(articoli.this, "数据加载完成", Toast.LENGTH_SHORT).show(); }); }
4. 实现进度更新方法(确保在UI线程执行)
UI操作必须在主线程执行,所以我们封装一个方法来安全更新进度:
private void updateProgress() { if(mTotalCount == 0) return; int progress = (int) (((float)mInsertedCount / mTotalCount) * 100); runOnUiThread(() -> { mProgressBar.setProgress(progress); mProgressText.setText(progress + "%"); }); }
5. 优化:将数据库插入放到后台线程(可选但推荐)
如果数据量很大,直接在UI线程插入会导致界面卡顿甚至ANR,建议用AsyncTask(Java)或协程(Kotlin)处理后台任务,这里给一个AsyncTask的示例:
private class InsertDataTask extends AsyncTask<Void, Integer, Void> { @Override protected Void doInBackground(Void... voids) { // 把getBodyArticoli中的解析和插入逻辑移到这里 // 每次插入一条数据后调用publishProgress(progress)更新进度 return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); int progress = values[0]; mProgressBar.setProgress(progress); mProgressText.setText(progress + "%"); } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); mProgressBar.setProgress(100); mProgressText.setText("100%"); Toast.makeText(articoli.this, "数据加载完成", Toast.LENGTH_SHORT).show(); } }
然后在getHTMLArticoli的回调中启动这个任务:
@Override public void onCompleted(Exception e, String result) { htmlresultart = result; htmlresultart = htmlresultart.replace("</td>", "\n"); new InsertDataTask().execute(); }
内容的提问来源于stack exchange,提问作者user9827495
相关产品推荐
相关产品推荐

