I have a Main activity with a few methods.
GetTopics: calls REST API and returns JSON results
BindTopics: displays the results from GetTopics on the screen
There are a few others with similar functionality, but I'm sure I can fit the solution to these across all methods.
Question: What is the proper way to run these in separate threads? Should both of them be in the same thread? Should I call BindTopics once GetTopics is complete?
Either way, doesn't the UI get built prior to the async threads are completed? If so, how do I update the UI?
Any help is appreciated.
The answer to all your questions is AsyncTask
I would load it in a progress dialog with an AsyncTask. You will need to declare the handler to update controls in the UI thread.
Example:
private Handler handler = new Handler();
final ProgressDialog pd = new ProgressDialog(this);
pd.setTitle("Getting topics..");
pd.setMessage("Please while topics are retrieved");
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setIndeterminate(true);
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
GetTopics();
return null;
}
#Override
protected void onPreExecute() {
pd.show();
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
BindTopics();
pd.dismiss();
handler.post(new Runnable() {
public void run() {
// update UI
// remove loading view
// load details of topics
}
});
super.onPostExecute(result);
}
}.execute();
You want to create your UI (with some sort of loading screen), then start an AsyncTask to download the data and display it.
There is a basic blog post about AsyncTasks here: http://android-developers.blogspot.co.uk/2009/05/painless-threading.html
In the AsyncTasks doInBackground method you would call GetTopics. Then in the onPostExecute method you would call BindTopics and display the data. In the onPostExecute method you can check to see if the data downloaded properly before attempting to display it.
The main use of threads for me were when my app had to download large amount of data from ftp server. But while downloading I wanted that the user still can use my app. If I had written the download code in main thread, the user could not use the app and all buttons would not work. The main idea of thread is to divide time of CPU usage for each thread.
If you wish more then one task to be preformed simultaneously you have to use Threads.
Related
I'm trying to develop an application to understand android, application delete's default browser's history. Every thing is working fine, I'm using AsyncTask to accomplish the task with ProgressDialog
Here is how I'm deleting the History
ProgressDialog pd;
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(HistoryClean.this, "Loading..",
"Please Wait", true, false);
}//End of onPreExecute method
#Override
protected Void doInBackground(Void... params)
{
Browser.clearHistory(getContentResolver());
return null;
}//End of doInBackground method
#Override
protected void onPostExecute(Void result)
{
pd.dismiss();
}//End of onPostExecute method
}.execute((Void[]) null);//End of AsyncTask anonymous class
But instead of ProgressDialog I want to implement CircularProgress which it can display the progress value like 10% , 90%....
Some times History may gets deleted faster and some times it may be slow, how to address this problem and dynamically update the CircularProgress bar with Progression Values.
Thanks in advance.
The best two library i found on the net are on github
https://github.com/Todd-Davies/ProgressWheel
https://github.com/f2prateek/progressbutton?source=c
Hope that will help you
AsyncTask has method onProgressUpdate(Progress... values) that you can call each iteration for example or each time a progress is done during doInBackground() by calling publishProgress(Progress...).
Refer to the docs for more details
I am developing an Android application and when it launches :
1) I make an HTTP Request to my server to send a small JSON file.
2) Open a webView to show a URL.
When the server is running properly there is absolutely no problem and everything goes smoothly.
HOWEVER , if for any reason the server is down , the HTTP request literally hangs and i need to wait till there is an HTTP timeOut which is around 30seconds till i actually see the webView with the URL loading.
I read that i shouldn't make any networking inside the UI thread and i should use another thread for that.
In BlackBerry , that i have already developed the application for , this is as simple as that :
new Thread(){
public void run(){
HttpConnection hc =
(HttpConnection)Connector.open("http://www.stackoverflow.com");
}
}.start();
I just start a new thread and inside i make the requests and all the necessary networking. That way , even when my server is not reachable the webView is loaded immediately without making the user wait and sense that the app is actually hanging.
How could i do exactly the same in Android , easiest way possible ?
Why not to use the same method as you use it for BlackBerry?
new Thread() {
public void run() {
new URL("http://www.stackoverflow.com").getContent();
}
}.start();
Use AsyncTask, it's the simplest way to do that. For more details:
http://developer.android.com/reference/android/os/AsyncTask.html
In icecream sandwich and above you are not allowed to use any web cal in UI thread. However you may use threads, but best way proposed by android is to use Async task. A very simple example is as follow.
"AsyncTask < Parameters Type, Progress Value Type, Return Type >"
class MyAsyncTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
// Runs on UI thread- Any code you wants
// to execute before web service call. Put it here.
// Eg show progress dialog
}
#Override
protected String doInBackground(String... params) {
// Runs in background thread
String result = //your web service request;
return result;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String resp) {
// runs in UI thread - You may do what you want with response
// Eg Cancel progress dialog - Use result
}
}
While I'm updating my database I want to display a progress dialog. My problem is that the ProgressDialog is getting late to appear,after 4-5 seconds, then appears and disappears very fast, it stays on screen few milliseconds almost you can't see it, then new data are shown in the list immediately. This makes me think that the ProgressDialog is waiting for database to be updated(it doesn't take much, about 4,5 seconds) and then it shows on the screen but is dismissing very fast. I would like the ProgressDialog appear immediately I press the 'Update' button and stay on the screen about 4-5 seconds.
class MyAsyncTask extends AsyncTask<Void, Void, Void>{
ProgressDialog myprogsdial;
#Override
protected void onPreExecute(){
myprogsdial = ProgressDialog.show(MyActivity.this, null, "Upgrade", true);
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
RefreshDataBase();
}
});
return null;
}
#Override
protected void onPostExecute(Void result){
myprogsdial.dismiss();
}
}
When I call it, new MyAsyncTask().execute();
Ok I think that this
runOnUiThread(new Runnable() {
is causing this behavior.
doInBackground() executes your code in a new thread to the main UI thread. You are then putting the code to execute in this thread back into the main one causing the progress dialog to be delayed at the end and then in postExecute() it gets closed immediately.
A good asyntask tutorial can be found here.
You must not use runOnUiThread. What you're basically did is:
Started new non-ui thread
From this new non-ui thread you posted a long running task to UI thread.
Exited from non-ui thread.
Your ui thread now executes long-running operation (RefreshDataBase) and blocks the UI.
You should call RefreshDataBase() directly. And if this method touches UI, you have to refactor it.
I have solved it, using this answer of Vladimir Ivanov.
I have separated the functionality by the appearance.
I have kept the functionality(downloading new data) in doInBackground() and in onPostExecute() I updated the list: get the new adapter,called setListAdaper() and notifyDataSetChanged.
Of course, I quit using runOnUiThread(). Thanks to all for hints.
I am developing an application which is having four tabs. In each tabs I have implemented each separate functions. I would like to implement threads for each tabs to make the program more efficient. Can anybody suggest the way to implement threads in tabbed activity?
You could put the running function either using the java Thread class or the doInBackground method by extending an AsyncTask class.
Ref: http://developer.android.com/reference/android/os/AsyncTask.html
I am not seeing the advantage to having each tab run in its own thread. The advantage to threading in Android would be to do time consuming work in the background, which would prevent the UI from locking up. What is it that each tab will be doing?
You can have threads to do background work in each tabbed Activity, but if you are planning on updating the UI, it must be done in the 'primary', or UI, thread.
On the android documentation there is a great article about "painless threading" you might wanna try from there. I would recommend not to take an approach for each tab instead try to keep in background those task that might block your UI thread (like downloading or parsing).
Here is a small snipped that might help you
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.adapter = new PersonAdapter(this, R.layout.main_item, new ArrayList<Person>());
setListAdapter(this.adapter);
ListView listView=(ListView)findViewById(R.id.section);
sectionAdapter=new SectionAdapter(this,R.layout.section_item,sections);
listView.setAdapter(sectionAdapter);
//execute the filling section task in background
progressDialog = ProgressDialog.show(MainFeedActivity.this,
"Please wait...", "Retrieving data ...", true);
new SectionTask().execute();
new FeedTask().execute();
}
private class SectionTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
//ProcessInformation Here Background Thread you can do downloading and parsing
}
#Override
public void onPostExecute(Void result){
//Update your UI here [UI Thread]
}
Be careful though there is a AsyncTask limit
I've got an Android activity which grabs an RSS feed from a URL, and uses the SAX parser to stick each item from the XML into an array. This all works fine but, as expected, takes a bit of time, so I want to use AsyncActivity to do it in the background. My code is as follows:
class AddTask extends AsyncTask<Void, Item, Void> {
protected void onPreExecute() {
pDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Retrieving data ...", true);
}
protected Void doInBackground(Void... unused) {
items = parser.getItems();
for (Item it : items) {
publishProgress(it);
}
return(null);
}
protected void onProgressUpdate(Item... item) {
adapter.add(item[0]);
}
protected void onPostExecute(Void unused) {
pDialog.dismiss();
}
}
Which I call in onCreate() with
new AddTask().execute();
The line items = parser.getItems() works fine - items being the arraylist containing each item from the XML. The problem I'm facing is that on starting the activity, the ProgressDialog which i create in onPreExecute() isn't displayed until after the doInBackground() method has finished. i.e. I get a black screen, a long pause, then a completely populated list with the items in. Why is this happening? Why isn't the UI drawing, the ProgressDialog showing, the parser getting the items and incrementally adding them to the list, then the ProgressDialog dismissing?
I suspect something is blocking your UI thread after you execute the task. For example, I have seen folks do things like this:
MyTask myTask = new MyTask();
TaskParams params = new TaskParams();
myTask.execute(params);
myTask.get(5000, TimeUnit.MILLISECONDS);
The get invocation here is going to block the UI thread (which presumably is spinning off the task here...) which will prevent any UI related stuff in your task's onPreExecute() method until the task actually completes. Whoops! Hope this helps.
This works for me
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(viewContacts.this);
dialog.setMessage(getString(R.string.please_wait_while_loading));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
It is because you used AsyncTask.get() that blocks the UI thread "Waits if necessary for the computation to complete, and then retrieves its result.".
The right way to do it is to pass Activity instance to your AsyncTask by constructor, and finish whatever you want to do in AsyncTask.onPostExecution().
If you subclass the AsyncTask in your actual Activity, you can use the onPostExecute method to assign the result of the background work to a member of your calling class.
The result is passed as a parameter in this method, if specified as the third generic type.
This way, your UI Thread won't be blocked as mentioned above. You have to take care of any subsequent usage of the result outside the subclass though, as the background thread could still be running and your member wouldn't have the new value.