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?
Related
I have several Activities and each of them has its own AsyncTask which sends requests to a server and catches its responses. These days if AsyncTask is in execution I have a ProgressDialog which blocks User from navigation to another Activities. I want to get rid of the ProgressDialog and substitute it with ProgressBar view so user can switch between Activities. My concern is about the following: what if AsyncTaskFirst started in ActivityFirst and user navigates to ActivitySecond where AsyncTaskSecond is starting also, couldn't it happen the response from the first request will take ground in ActivitySecond so I'll miss it in ActivityFirst? If it is impossible, that's fine. If it is - how to handle such a case? Thank you very much in advance.
If the AsyncTask begun execution in the first Activity then it's execution of the postExecute method should be expected to affect the first Activity and not the second unless you've explicitly set it up otherwise.
I assume your AsyncTask has some kind of reference to the Activity, so it can update the progress bar.
If this is so, then all you have to do is add a method in the AsyncTask:
public void setHandler(MyTaskHandler handler) {
this.handler = handler;
}
When you start a new activity, call this method and pass on the new activity.
Then when the AsyncTask calls the Activity's update progress method, it will use the current Activity regardless of where the task was started from.
BTW: It might be better to use fragments and not activities, if it's the same component only different parts of the display. Then you do not have this problem at all, because the activity remains the same. See these guides about fragments:
http://developer.android.com/training/basics/fragments/index.html
http://developer.android.com/guide/components/fragments.html
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 a Async Task that creates a HashMap to create a Adapter to populate ListView. I have a progress dialog that shows during doInBackground method.In onPostExecute() method, I dismiss the progress dialog and call a method that populates my listview with the list of items saved in doInBackground method.
This works fine. But I noticed something strange:
The issue I see is, if I lock the screen when the progress dialog is about to be dismissed (in onPostExecute), the listview does not display, even though it has non-empty items in it. I verified it in logcat messages and when I debugged.
Is there a possibility that a screen lock (I do this my pressing power button once) blocking UI thread? How can I resolve the issue and make sure ListView displays its items?
Code for onResume():
#Override
protected void onResume(){
super.onResume();
if(MyAdapter !=null){
pull_listView.setAdapter(MyAdapter);//pull_listView is listview
MyAdapter.notifyDataSetChanged();//MyAdapter is the adapter
}
}
This situation illustrates the downside of using AsyncTask to do background processing. In some cases, an IntentService may be a better choice, especially if you think the background work is going to take some time. An AsyncTask ties the background work to the current Activity, while an IntentService is completely decoupled.
The Android training class Running in a Background Service shows you how to set up an IntentService, request work, and notify your Activity when the work is done. Passing data from the IntentService to the Activity is a bit more complicated, but there are options.
onStop() will be called when your screen goes out as per the Activity Lifecycle. You could override onStart() or onResume() and put a check in there to see if your data has been populated. If not, populate. You may even want to overide 'onStop()' to save data if the screen goes out.
Edit
In this particular situation, I would think onResume() or onStart() would be fine but onResume() is usually the safest because it is guaranteed to get called before the Activity is shown as illistrated in the link I gave. What kiind of a check you want to use is up to you and depends on how you handle evrything. However, if your AsyncTask is an inner class of your Activity class the you could simply create a boolean member variable, say boolean isDone=false; change this to true in your doInBackground() or onPostExecute() then your onResume() knows the data Is loaded. If its false then you can try to get data again. Hope this makes sense and can help
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.
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.