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.
Related
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.
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?
I have an activity that lets a user upload a photo to the web and instead of having them wait indefinitely for the image to upload I have it being done in an asynctask that handles the image upload. When the user presses the button to upload the image the I have the activity that uploads the image close and the app goes back to the earlier activity which has its own downloading process. What Im trying to figure out is what to do in the asynctask onPostExecute to get the download process in the other activity to run again. I tried just using this:
#Override
protected void onPostExecute(String result){
if(result!=null){
Main.DownloadManager.startDownloading();
}else if(result==null){
Toast.makeText(getBaseContext(),"Upload failed",timetoshow).show();
}
}
But I get no response in the main activity because I know Im not actually calling the running activity but just calling the method.....somewhere thats not instantiated or running....or at least thats what I think this does. So I guess my question is how can I pass the message to run the startDownloading() method from the asynctask of the closed activity in the currently running Main activity. Any help would be super much appreciated.
EDIT:
I was able to solve this by implementing one of the solutions bellow:
#Override
protected void onPostExecute(String result){
if(result!=null){
CustomContextClass.*Main*.DownloadManager.startDownloading();
}else if(result==null){
Toast.makeText(getBaseContext(),"Upload failed",timetoshow).show();
}
}
You may use a static method in DownloadManager
private static instance;
public void onCreate() {
instance = this;
}
public static void startDownloading() {
instance.downloadNow();
}
onProgressUpdate() of AnsycTask will tell you about the progress .so here you can decide hewhat data you want to send to next activity . in next activity deal with remaining not downloaded portion . thinks depends on server side implementation of data chunk .
your complete requirement will be required for more suggestions.
Having processes hanging around from a dead Activity is dangerous, as it has a high potential to cause leaks. Why not start the AsyncTask in the Activity you intend to show progress? That would make the most sense.
you can do something like below, if I'm not mistaken I think the AsyncTask has written DownloadManager class.
I hope you have the AsyncTask written as a InnerClass similar to this in that class.
private class InitTask extends AsyncTask<String, String, String> {....
Also you should have to have a getter to return InitTask object,
public InitTask getInitTask(){
return new InitTask();
}
So in the other class, you can call this like below,
new YourOtherClass().getInitTask().execute();
How can I make loading page in android? I want it when my application starts.
Like the loading pages in games?
Could You help me with that?
There are loads of examples in the internet, search by "splash screen"
http://www.anddev.org/viewtopic.php?t=815
One way of doing it would be to set your contentview in onCreate() then do all the loading in an async task and when that finishes load the 'real' layout in the onPostExecute. Check out http://developer.android.com/reference/android/os/AsyncTask.html
That way you load your "real" layout when it actually finishes loading rather than picking a generic time to switch views. This is of course assuming that you want a loading page and not a splash screen. If you want that, checkout the other answers.
Here's a quick example... Say you have a file called Hello.java .. You'd set your content view to your loading layout in OnCreate() then call this class with something like.. new DownloadFilesTask().execute(); put this private class in it...
private class DownloadFilesTask extends AsyncTask<String, String, String> {
protected Long doInBackground(String... params) {
//grab stuff from the server, compute pi to 100000 places etc.
}
public void onPostExecute(String result) {
//this will now switch us to our real layout, you can now do all your fancy UI stuff! :)
setContentView(R.layout.reallayout);
}
}
Basically this is multithreading the easy way. onPostExecute runs back on the UI thread (your main one) while doInBackground does everything on a separate thread so no black screens! I'd really urge you not to use Runnable in this situation.
You mean a splash screen right? a simple google search would reveal a lot :)
This piece of work helped me to make a splash screen.
Rather than copy and pasting the code, try to understand how he uses Threading with a time limit to achieve this target.
Error
05-12 11:56:45.793: ERROR/AndroidRuntime(505): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
what i have done
i have a list view inside my activity and i need to populate the listview by doing the following:
mylistview.setAdapter(new CustomAdapter());
now there is already too much pressure on my UI thread so , thought of calling this method inside a AsynTask.
Another problem
there is a progress dialog that shows in my acitivity when the user clicks the button to populate the listview. when i put everything inside one thread the progress dialog does not show. i had asked a question on stackoverflow about why the progress dialog does not show and i had got a reply saying that i need to put all the extra tasks inside another thread.
i have also read the updating UI in android given on android developer website:
but over there all we do is make a new runnable and post the runnable to the Handler of the UI thread so that when the UI is free, the runnable will be executed.
But how does the above solve my purpose? i mean the UI thread is still executing the instructions.
The only way i can take the load of the UI thread is if i make another thread and put all the work over there... but android does not allow this?
what is wrong with my understanding(if there is anything wrong)? How do i solve this problem
thank you in advance.
Android does allow you to put the extra work in a different thread AND publish the results on the UI thread, using AsyncTask. Add the UI update stage in the onPostExecute() method of the AsyncTask and you should be good-to-go. onPostExecute() is performed on the UI thread, the example in the AsyncTask Documentation is a great one.
Also, if you build your application properly, and don't use graphics a lot, there should not be too much work for the UI thread during the application run. Move everything that doesn't absolutely bound to the UI on a separate thread. AsyncTask is a very convenient way to do it.
AsyncTask is the correct way to solve your problem. Where you are running into difficulty is exactly what to put into the AsyncTask. Call mylistview.setAdapter(); from the onProgressUpdate or onPostExecute methods. So do something like this:
void setProgress(Integer progress){ myprogressbar.setValue(progress); }
void setAdapter(CustomAdapter result){ mylistview.setAdapter(result); }
private class LongRunningTask extends AsyncTask<String, Integer, CustomAdapter> {
protected Long doInBackground(String... urls) {
CustomAdapter res = null;
// do all the work to BUILD the custom adapter, calling publishProgress() as progress gets made
publishProgress(<progress value>);
return res;
}
protected void onProgressUpdate(Integer... progress) {
setProgress(progress);
}
protected void onPostExecute(CustomAdapter result) {
setAdapter(result);
}
}
That should fix the threading issue and let you set the progress bar.