I'm writing an application for Android, which should get some data from the server as soon as it launches.
Between the start of the application and the response from the server (or timeout, if the server is down), the application should display a "waiting" animation.
Thereafter, the normal panel should be shown (if the server responded) or an error dialog box be displayed (if the server didn't respond).
What is the correct place to put this logic into?
MainActivity.onCreate or some other place?
if you want the data loaded only when the app starts for the first time, onCreate() is the right place. if you want to re-loaded every time the app comes into focus (i.e., the foreground), then onResume() is the right place. take a look at documentation on the activity lifecycle for details.
you'll want to take a look into AsyncTask, or Loader+AsyncTaskLoader to understand the right pattern for doing something in the background then updating the UI with the result.
As Jeffrey suggested at first you have to determine when you want to connect to the server? Depending on this you should connect to server in onCreate or onResume.
Now you must remember one thing that you can't do heavey tasks in your manin GUI thread. Else there is a good chance of ANR. So you have to implement this feature in a different thread. For this you can use different Thread, Handler or AsyncTask. You can find a nice doc here
I think it is a suitable situation to use AsyncTask. So here is an example with AsyncTask
private class ServerCommunication extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// show the connecting screen
// or you can do this before calling asyncTask
}
#Override
protected Void doInBackground(Void... params) {
// communicate with server
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// show the second screeen
}
}
and call it using
ServerCommunication pcd = new ServerCommunication();
pcd.execute();
This is just for suggesting the structure. You can definitely use neccessary paramenters or other method also.
Related
So from what I've read, Android's AsyncTask is a great way to asynchronously load information from the Internet. However, I don't want to block up the UI and prevent the user from interacting with it.
A basic description of my problem.
Currently, I am using websockets in order to send/receive data from a web server. On events like a user entering the room, a song being added or removed from a playlist, a song being upvoted or downvoted, or one song ending and another one beginning, the UI must be updated in order to indicate changes. But ideally, these changes will be occurring very frequently, which means that constantly blocking the UI in order to refresh it would be cumbersome and annoying.
How would I update my UI without interrupting the user in their activities? Would AsyncTask suffice?
The asyncTask does not block the UI. It runs on a separate thread to send / receive the data from the web, and then returns the results. When you receive the results back, you can update the UI as you choose.
Your UI will not be stopped while the asyncTask is performing its background work. You can try it out by by building one in your activity and simply sleeping for some amount of time (let's say five seconds) in the doInBackground method. You will see that your UI is still functional during that five seconds.
Edit: You can do just about anything with the results you get back and it won't interrupt your UI either. If that's not the case, you'll probably want to look at optimizing what you are doing with your in memory objects. Anything not stored in memory should probably be retrieved or written to disk, database, or internet endpoint with an AsyncTask. As the commenter points out above, this is not the only way to use other threads, but it's easy and will probably work if you're making a reasonable web request and expect users to have a decent connection. You will just want to make sure you have timeouts and exceptions covered so that your app doesn't crash if the task takes longer than expected.
public class LoadCommentList extends AsyncTask<Integer, Integer, List<Comment>> {
private String commentSubject;
public LoadCommentList(commentSubject){
this.commentSubject = commentSubject;
}
// Do the long-running work in here
protected List<Comment> doInBackground(Integer... params) {
// the data producer is a class I have to handle web calls
DataProducer dp = DataProducer.getInstance();
// here, the getComments method makes the http call to get comments
List<Comment> comments = dp.getComments(commentSubject);
return comments;
}
// This is called each time you call publishProgress()
protected void onProgressUpdate(Integer... progress) {
// setProgressPercent(progress[0]);
}
// This is called when doInBackground() is finished
protected void onPostExecute(List<Comment> comments) {
// calls a method in the activity to update the ui
updateUI(comments);
}
}
There are cleaner examples actually using the Integer... params for example, but this is just something I had handy as an example.
I don't know where you read that but asyn task are worst way to make web service call this days. You should use Retrofit for service call, it is 8 Times faster and handle UI update smoothly.
Read more about this here :-
http://googleweblight.com/?lite_url=http://instructure.github.io/blog/2013/12/09/volley-vs-retrofit&ei=qR4bQU5c&lc=en-IN&s=1&m=260&host=www.google.co.in&ts=1465531978&sig=APY536z0v15lfX3G6KY4nls4wf1kzttJdA
What happens if some activity lifecycle events occur while a method is executing?
My activity has some methods where JSON text files (few tens of Kb) are written to disk, for example. Is it wrong designed?
Or, in general, consider the case where there are two instructions to be executed: the first performs an important operation, the second updates some data based on the result from the first.
Something like:
value=performOperationAndYeldResult();
updateAppData(value);
What happens if the lifecycle event occurrs after the first call and before the second, or while it's executing?
I put "long" operations in services but I cannot create a service for every critical data update all over the app. I think I am missing something so I fear for nothing. Maybe the resumed or restarted activity continues operations so they get completed.
Anyway I ask here: Are methods completed, or continued?
new PerformOperationAsyncTask(someValue);
private class PerformOperationAsyncTask extends AsyncTask<Object, Void, Object> {
protected Long doInBackground(Object... values) {
//this is taking place in secondary thread
Object returnValue = performOperationAndYeldResult(values[0]);
return returnValues;
}
protected void onPostExecute(Object result) {
//this is taking place in the UI thread
updateAppData(value);
}
}
In my application I need to call two web-services to fetch the records from server on app start. I did that in Asynch Task and on splash screen but its not running fine. It waits for the aynsch task to complete his operation first then its moving to next activity.
I want my app should call webservice in background on app startup without blocking the user to move next activity.
any help would be appreciated.
**call Asyn server call wherever you need**
getServerResponse();
"startnewactivity" here
finish current activity here
**Asyn server call**
public void getServerResponse(){
new AsyncTask<Void, Void, Object>() {
#Override
protected Object doInBackground(Void... params) {
//write your server response code here
return null;
}
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
}
}.execute();
}
You can use an IntentService and fetch the details and store it.
Or You can use a Service, bind it with the activity and send the data when you have retrieved it.
Additionally you can navigate to the 2nd activity and call the AsyncTask to fetch the details and update the UI when done.
If the data retrieved is global and used by multiple activities then store it in the Application class and add a stateChangeListener and get notified when its updated from a background service or AsyncTask.
Using an Async task you can run the web service call in a background thread and your UI thread wouldn't be blocked and you can call the next activity in background using the runonuithread but it makes seamless solution. So its better to wait finish the background process first
I have use the v4 support lib for FragmentTabHost
The requirement is that when I am switching tab one to another & another one, that is calling
onCreateView() & onActivityCreated() every time.
That's why my code performance is slow.
So, any other solutions? how to increase performance in fragment tab?
Sounds like a design smell.
Redesign your code so that heavy work is done asynchronously. Fragments should be able to be built quickly. If there is any large processing that needs to be done to in order for a Fragment to display useful information, that work should be done beforehand or asynchronously after the Fragment is created and the Fragment should be notified to update its content when the work is complete.
First thing which you should take care of is to watch about calculations / loading a big set of data should be places on a different worker thread than main UI thread. The best option to do that (in my opinion) is to use AsyncTask. You can use something like this in your Fragment :
private class LoadData extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute(){
super.onPreExecute();
// this is the place where you can show
// progressbar for example to indicate the user
// that there is something which is happening/loading in the background
}
#Override
protected void doInBackground(Void... params){
// that's the place where you should do
// 'the heavy' process which should run on background thread
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute();
// you should update your UI here.
// For example set your listview's adapter
// changes button states, set text to textview and etc.
}
}
This is the way you can make your tabs work faster.Hope this will help you! : )
I found a solution for that. I inserted all websevices & database transaction code in on create. because oncreate in not calling every time untill the ondestroy not call. & the other one solution is also available we can use
fragment.show();
& fragment.hide(); method
As an addition to Android-Developer: if you already are using AsyncTask, remember that even when you use multiple AsyncTask's, they are executed in the background, but all sequentially! If you want more threads to handle your tasks, check out this post, which perfectly explains how to achieve that! Running multiple AsyncTasks at the same time -- not possible?
HI,
Im trying to show a ProgressDialog while the activity is loading.
my problem is that although i completed all the work in the activity
it takes a long time for the activity to load, i suspect this is because i use
multiple views with multiple listviews with custom array adapters inside a viewflipper.
it takes a long time for the UI to show.
how would i go about checking that all the UI inside the activity finished loading?
or is there a way to preload all the activity and the UI?
Thanks,
Use Asynctask
new DownloadTask().execute();
private class DownloadTask extends AsyncTask<String, Void, Object> {
protected void doInBackgroind(Void... arg0){
//Do time Consuming Processing
publishProgres()
return null;
}
protected void onProgressUpdate(Void... arg0){
}
protected void onPostExecute(Void... result){
log.i("AvtivityInfo", "activity finished loading...");
}
}
If you think you need a ProgressDialog because your activity is opening too slowly, you have much bigger problems. Android is likely to kill off your activity with an activity-not-responding error.
You can either get sophisticated and use Traceview to find your performance issue, or you can just experiment. For example, you can skip setting adapters in your ListViews, to confirm that the problem indeed lies there.
Jorgesys had the right answer in his now-deleted entry, from what I can tell. I suspect that loading your adapters is taking the time, perhaps in database queries, and you need to move some of that into AsyncTasks.