在不冻结应用程序的情况下更新 UI 个线程
Update UI Thread while without freezing application
我的代码有问题,我是 Android 世界的新手,我需要有关 AsyncTask 的帮助 class...
我有一个方法应该在 CSV 文件中搜索行,然后关于它找到了多少行它应该将特定的行添加到 TableLayout 多亏了一个 Map 指示要添加哪些视图以及以什么顺序添加它们.
该方法如我所愿地工作,但问题是由于计算冻结了我的应用程序,我想做一些事情来向用户表明发生了什么事。
我阅读了有关使用 AsyncTask 的内容,但我知道 AsyncTask 正在后台线程中进行计算,您无法通过后台线程UI更新
希望你能理解我(我是法国人,所以我的英语差不多^^)
这是我的代码:
private void addModifLinesToView(TableLayout view, String ressource, Map<String,Object> ViewVal, List<List<View>> listeViews) throws IOException {
try {
CSVFile csvBT = new CSVFile(new FileInputStream(Environment.getExternalStorageDirectory()+"/"+folder_main+"/"+imported_data+"/"+ressource));
List<String[]> tableauVals = csvBT.findLines(indicePoste.getText().toString());
int numLigne = 0;
//pour chaque ligne trouvée dans le csv
for (String[] s : tableauVals) {
numLigne++;
if (view.getId() == tableauBT.getId())
{
numLigneBT++;
}
List<View> actualViews = new ArrayList<>();
List<View> dividers = new ArrayList<>();
TableRow row = new TableRow(getApplicationContext());
row.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
//creation des separateurs
for (int i = 0; i < ViewVal.size()+1; i++) {
View divider = new View(getApplicationContext());
divider.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.MATCH_PARENT));
divider.setBackgroundColor(Color.BLACK);
dividers.add(divider);
}
//delimiter a gauche de la ligne
row.addView(dividers.get(0),
new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.MATCH_PARENT));
ArrayList<String> listeModeles;
for ( Map.Entry<String,Object> entry : ViewVal.entrySet()) {
if (entry.getKey().contains("EditText")) {
EditText et = new EditText(getApplicationContext());
actualViews.add(et);
et.setMaxWidth(0);
et.getBackground().mutate().setColorFilter(getResources().getColor(android.R.color.darker_gray), PorterDuff.Mode.SRC_ATOP);
et.setHighlightColor(getResources().getColor(R.color.gris));
et.setPadding(3, 3, 3, 7);
et.setGravity(Gravity.CENTER);
et.setTextColor(Color.BLACK);
et.setSingleLine();
et.setInputType((int) entry.getValue());
et.setImeOptions(EditorInfo.IME_ACTION_DONE);
//pour mettre la taiile du text en SP
et.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
} else if (entry.getKey().contains("Spinner")) {
Spinner spin = new Spinner(getApplicationContext());
actualViews.add(spin);
spin.getBackground().setColorFilter(getResources().getColor(R.color.noir), PorterDuff.Mode.SRC_ATOP);
spin.setPadding(3, 3, 3, 3);
spin.setGravity(Gravity.CENTER);
spin.setPopupBackgroundResource(R.color.blanc);
ByteArrayInputStream bais = new ByteArrayInputStream((byte[])entry.getValue());
listeModeles = listerModeles(bais);
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_spinner_item, listeModeles);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin.setAdapter(adapter);
} else if (entry.getKey().contains("TextView"))
{
TextView tv = new TextView(getApplicationContext());
actualViews.add(tv);
tv.setText(Integer.toString(numLigne));
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
tv.setMaxWidth(0);
tv.setPadding(3, 3, 3, 7);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(Color.BLACK);
tv.setSingleLine();
}
}
for (int j = 0; j < actualViews.size(); j++) {
row.addView(actualViews.get(j),
new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.MATCH_PARENT, 1f));
row.addView(dividers.get(j + 1),
new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.MATCH_PARENT));
}
view.addView(row);
//separateur horizontal
View dividerH = new View(getApplicationContext());
dividerH.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
3));
dividerH.setBackgroundColor(Color.BLACK);
view.addView(dividerH, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
3));
listeViews.add(actualViews);
}
}
catch (ArrayIndexOutOfBoundsException | FileNotFoundException e) {
e.printStackTrace();
}
}
I read something about using AsyncTask but I know that AsyncTask is doing computing in a background thread and that you can't update UI through background thread
不,您可以更新 UI,但不能从 doInBackground()
代码更新。您可以在从 onPostExecute()
完成繁重工作后更新 UI,或者如果您想在后台计算期间更新,请将该工作委托给在 [=17= 上运行的 AsyncTask 的 onProgressUpdate()
方法] 线。然后在需要时从 doInBackground()
调用该方法。
当您处于非UI 线程时,您不能直接接触UI 元素,但有多种解决方法。例如,参见 this question.
如果您正在使用 AsyncTask
,最好的方法是覆盖 AsyncTask
的 onPostExecute()
方法。此方法在 UI 线程中执行(而 run()
在后台线程中执行)。
请检查documentation,还有一个例子:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
您的方法 addModifLinesToView
应该从 doInBackground
调用。
您只需要添加 publishProgress
调用,在该方法上您可以向用户显示您正在处理哪个文件。
我的代码有问题,我是 Android 世界的新手,我需要有关 AsyncTask 的帮助 class...
我有一个方法应该在 CSV 文件中搜索行,然后关于它找到了多少行它应该将特定的行添加到 TableLayout 多亏了一个 Map 指示要添加哪些视图以及以什么顺序添加它们.
该方法如我所愿地工作,但问题是由于计算冻结了我的应用程序,我想做一些事情来向用户表明发生了什么事。
我阅读了有关使用 AsyncTask 的内容,但我知道 AsyncTask 正在后台线程中进行计算,您无法通过后台线程UI更新
希望你能理解我(我是法国人,所以我的英语差不多^^)
这是我的代码:
private void addModifLinesToView(TableLayout view, String ressource, Map<String,Object> ViewVal, List<List<View>> listeViews) throws IOException {
try {
CSVFile csvBT = new CSVFile(new FileInputStream(Environment.getExternalStorageDirectory()+"/"+folder_main+"/"+imported_data+"/"+ressource));
List<String[]> tableauVals = csvBT.findLines(indicePoste.getText().toString());
int numLigne = 0;
//pour chaque ligne trouvée dans le csv
for (String[] s : tableauVals) {
numLigne++;
if (view.getId() == tableauBT.getId())
{
numLigneBT++;
}
List<View> actualViews = new ArrayList<>();
List<View> dividers = new ArrayList<>();
TableRow row = new TableRow(getApplicationContext());
row.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
//creation des separateurs
for (int i = 0; i < ViewVal.size()+1; i++) {
View divider = new View(getApplicationContext());
divider.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.MATCH_PARENT));
divider.setBackgroundColor(Color.BLACK);
dividers.add(divider);
}
//delimiter a gauche de la ligne
row.addView(dividers.get(0),
new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.MATCH_PARENT));
ArrayList<String> listeModeles;
for ( Map.Entry<String,Object> entry : ViewVal.entrySet()) {
if (entry.getKey().contains("EditText")) {
EditText et = new EditText(getApplicationContext());
actualViews.add(et);
et.setMaxWidth(0);
et.getBackground().mutate().setColorFilter(getResources().getColor(android.R.color.darker_gray), PorterDuff.Mode.SRC_ATOP);
et.setHighlightColor(getResources().getColor(R.color.gris));
et.setPadding(3, 3, 3, 7);
et.setGravity(Gravity.CENTER);
et.setTextColor(Color.BLACK);
et.setSingleLine();
et.setInputType((int) entry.getValue());
et.setImeOptions(EditorInfo.IME_ACTION_DONE);
//pour mettre la taiile du text en SP
et.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
} else if (entry.getKey().contains("Spinner")) {
Spinner spin = new Spinner(getApplicationContext());
actualViews.add(spin);
spin.getBackground().setColorFilter(getResources().getColor(R.color.noir), PorterDuff.Mode.SRC_ATOP);
spin.setPadding(3, 3, 3, 3);
spin.setGravity(Gravity.CENTER);
spin.setPopupBackgroundResource(R.color.blanc);
ByteArrayInputStream bais = new ByteArrayInputStream((byte[])entry.getValue());
listeModeles = listerModeles(bais);
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_spinner_item, listeModeles);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin.setAdapter(adapter);
} else if (entry.getKey().contains("TextView"))
{
TextView tv = new TextView(getApplicationContext());
actualViews.add(tv);
tv.setText(Integer.toString(numLigne));
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
tv.setMaxWidth(0);
tv.setPadding(3, 3, 3, 7);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(Color.BLACK);
tv.setSingleLine();
}
}
for (int j = 0; j < actualViews.size(); j++) {
row.addView(actualViews.get(j),
new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.MATCH_PARENT, 1f));
row.addView(dividers.get(j + 1),
new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.MATCH_PARENT));
}
view.addView(row);
//separateur horizontal
View dividerH = new View(getApplicationContext());
dividerH.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
3));
dividerH.setBackgroundColor(Color.BLACK);
view.addView(dividerH, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
3));
listeViews.add(actualViews);
}
}
catch (ArrayIndexOutOfBoundsException | FileNotFoundException e) {
e.printStackTrace();
}
}
I read something about using AsyncTask but I know that AsyncTask is doing computing in a background thread and that you can't update UI through background thread
不,您可以更新 UI,但不能从 doInBackground()
代码更新。您可以在从 onPostExecute()
完成繁重工作后更新 UI,或者如果您想在后台计算期间更新,请将该工作委托给在 [=17= 上运行的 AsyncTask 的 onProgressUpdate()
方法] 线。然后在需要时从 doInBackground()
调用该方法。
当您处于非UI 线程时,您不能直接接触UI 元素,但有多种解决方法。例如,参见 this question.
如果您正在使用 AsyncTask
,最好的方法是覆盖 AsyncTask
的 onPostExecute()
方法。此方法在 UI 线程中执行(而 run()
在后台线程中执行)。
请检查documentation,还有一个例子:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
您的方法 addModifLinesToView
应该从 doInBackground
调用。
您只需要添加 publishProgress
调用,在该方法上您可以向用户显示您正在处理哪个文件。