Android activity is too busy to set TextView text?
-
27-10-2019 - |
Question
i have a function that fill up my SQLite DB with entries of a http query:
try {
stringEntity = new StringEntity(SQL);
httpPost.setEntity(stringEntity);
httpResponse = httpClient.execute(httpPost);
httpEntity = httpResponse.getEntity();
bos = new ByteArrayOutputStream();
httpEntity.writeTo(bos);
data = bos.toString();
reader = new BufferedReader(
new StringReader(data));
try {
//SAVE DATA IN MY DB || WORKS
} catch(IOException e) {
e.printStackTrace();
}
} catch (IOException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}
What i try to do is to set the text of an textview on my activity before the procedure starts (in front of the first "try{.." in my code i postet). but the text won't change, because my activity is too busy to get the data ( i think.I have no other explanation..)
any suggestions?
thanks, prexx
UPDATE '' Get data from AsyncTask ''
txtAction.setText("Loading...");
AsyncTask<String, String, String> test = new cAsyncTask();
try {
data = test.execute(URL).get();
reader = new BufferedReader(
new StringReader(data));
while ((line = reader.readLine()) != null) {
//SAVE DATA IN DB || WORKS
}
}
} catch(IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
My Async Task:
class cAsyncTask extends AsyncTask<String, String, String> {
protected String doInBackground(String... urls) {
int count = urls.length;
String data = "";
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost;
StringEntity stringEntity;
HttpResponse httpResponse;
HttpEntity httpEntity;
ByteArrayOutputStream bos;
String line;
BufferedReader reader;
for (int i = 0; i < count; i++) {
httpPost = new HttpPost(urls[i].toString());
try {
stringEntity = new StringEntity(SQL);
httpPost.setEntity(stringEntity);
httpResponse = httpClient.execute(httpPost);
httpEntity = httpResponse.getEntity();
bos = new ByteArrayOutputStream();
httpEntity.writeTo(bos);
data = bos.toString();
} catch (IOException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}
}
return data;
}
protected void onProgressUpdate(String... progress) {
}
protected void onPostExecute(String result) {
String test = result;
}
Solution
Put the busy part of your code into a separated Thread.
Look at the AsyncTask utility
Call AsyncTask.execute()
just after textview.setText("foo")
and u will be fine :)
Regards
UPDATE with code sample:
txtAction.setText("Loading...");
AsyncTask<String, String, String> test = new cAsyncTask();
test.execute("http://...");
class cAsyncTask extends AsyncTask<String, String, String> {
protected String doInBackground(String... urls) {
int count = urls.length;
String data = "";
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost;
StringEntity stringEntity;
HttpResponse httpResponse;
HttpEntity httpEntity;
ByteArrayOutputStream bos;
String line;
BufferedReader reader;
for (int i = 0; i < count; i++) {
httpPost = new HttpPost(urls[i].toString());
try {
stringEntity = new StringEntity(SQL);
httpPost.setEntity(stringEntity);
httpResponse = httpClient.execute(httpPost);
httpEntity = httpResponse.getEntity();
bos = new ByteArrayOutputStream();
httpEntity.writeTo(bos);
data = bos.toString();
} catch (IOException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}
}
reader = new BufferedReader(
new StringReader(data));
String line = "";
while ((line = reader.readLine()) != null) {
//SAVE DATA IN DB || WORKS
}
return data;
}
protected void onPostExecute(String result) {
String test = result;
textView.setText("Done!");
}
}
The key is to put all busy code into the doInBackGround
method which will runs in a separate thread. All UI modification must be in the same UI thread and this could be done into the onPostExecute
method which will be executed in the same UI thread
OTHER TIPS
You could try to call invalidate() on TextView. But using asynchronous tasks is a best practice for heavy data load methods. That will not interrupt user in operation UI controls.
It has nothing to do with "too busy" but with the fact that the text will only be set when the method returns. And with your networking this will be delayed.
Btw. on Honeycomb network on UI thread will throw an Exception and kill your app.