My Android application is running very slow and lagging much. I have PHP API on my server and my application requests data through HTTP.
Though, the problem is that sometimes I should wait for few seconds before I can see the result. I have all calculations done in the main thread in onCreate (parsing XML, adding controls) and downloading data from HTTP server in AsyncTask.
How to optimize my program to make it faster? I want it to load activity first and only then, in background, download and parse data. How is it possible? Sorry for newbieship.
what did you mean by lagging ? Will you elaborate more on the issue.
One suggestion that remove parsing XML from OnCreate and move it to AsysnTask. The reason for this is as you are doing time consuming operation in UI Main thread which will impact the activity to be shown.
Create thread to perform HTTP related operations and parse the response on the same thread and while doing the parsing operation show dialog.
Dismiss the dialog when parsing got completed and then show the activity which you want to display.
In the doInBackground() method in AsyncTask add the data parsing and create the data objects then in onPostExecute update the ui elements.
The reason to do something like that is for the application to be responsive in all this time and just make small jobs on the ui thread so as not to freeze.
You can instatiate your views to a default state an add a progress somewhere on top to indicate that the activity is currently loading. For example you can create an empty ListView or a Button that cannot be selected and when the parsing is done then you should set the adapter to the list and make the button back to selectable again.
All this things can be implemented according to what you want the user to be able to do in the time of his waiting.
Related
Say I have main activity that contains a list (never mind if it is a ListView or RecyclerView). Each time the activity is created it has in its onResume method a query for data from parse. The thing is the parse query I use calls findInBackground method so my list in main activity is always zero since by the the time the activity is constructed the query hasn't finish yet. when I use find (and not find in background) I see in android studio logcat a sentence like the follwoing : "to many operation on main thread".
What do u think I should do?
Thank u in advance
Expansive operations like this should be done on a seperate thread in the background, so the main (animation) thread will not be blocked, causing your app to lag. The findInBackground() method will do the same as find(), but on a different thread 'in the background'. When the job is done, it will call the FindCallback and pass the result so you can update your list.
Untill this is done you could show a intermediate ProgressBar in front of your empty list to indicate that the data is loading.
I have a activity that show one listview. In the activity I have a one AsyncTask (named here of AsListView) to get values from internet and fill some informations in each item of the listview. Work fine.
Now I created a button in ActionBar to show one image from streetview. To do this I have implemented another AsyncTask (named here of AsImage) to get image from google and show in a DialogFragment, but is necessary wait the execution of all AsListView Threads. It spends long time depending of the number of items in the list.
To execute AsImage rapidily, I cancel all AsListView tasks, but it's not good for me (user loss informations). The ideal soluction is set AsListView tasks to wait while AsImage execute. When AsImage finish I set AsListView tasks to continue execution. But I know that is not possible handle the control of execution of AsynkTasks.....
Some solution?
You can try to synchronize the AsyncTasks using a CountDownLatch.
Otherwise if you want you can use Threads instead of AsyncTasks and set their priorities, but there is a reason android made the AsyncTask class so I recommend you use it.
I know it sounds crazy that someone is using runOnUiThread inside AsyncTask. Somehow, it is working for me but I wanna know if it is an acceptable and robust approach or not. Here is the scenario:
I have an app in which after successful login, user is rendered to next screen. In this new screen, 3 different methods are loading different types of data from a web server. These methods are:
getMembersForList() : It loads the list of community members and shows it in a listview.
getProfileData() : It loads the profile of logged in user and shows his name , image etc on the screen.
getNotificationCounts : It loads the count of new notifications for the user.
I applied 3 different approaches for it :
(1) Calling all 3 methods simply in onCreate i.e. no exclusive thread is being used for any of the methods . In this case , the transition from login screen to this screen becomes very slow and black screen shows up for some time before this activity shows up.
(2) Calling getMembersForList() on UI thread and the other 2 methods on exclusive threads. In this case transition becomes fast and list shows up quickly but Notification counts and username etc. don't show up because WrongThreadException occurs saying that this thread can't touch other thread's views (TextViews for username, notification count etc. which are declared globally) . The same thing happens when I start these threads from an AsyncTask as well.
(3) Calling getMembersForList() on UI thread and then starting an AsyncTask in which the other 2 methods are being called in "runOnUiThread" inside doInBackground() method. This solves both the above issues. Now the screen transition is faster and the WrongThread exception is also not occuring.
So far the approach-(3) is working good for me but I am not sure if this is the right way to do it because runOnUiThread and AsyncTask are 2 completely opposite things. Can anyone please clear my doubts about this scenario. Thanx in advance.
Yes, use-cases like this are a big reason why the runOnUiThread() method exists in the first place. The idea is you allow your background thread(s)/AsyncTask instance(s) to run your lengthy operations in the background, and then provide a simple hook that they can use to update the interface when they have the result (or at arbitrary intervals, as different pieces of the result become available).
As long as that's what you're doing, then your usage is fine. What you want to avoid doing is performing a lengthy operation on the main thread, either directly or indirectly by passing in some lengthy operation from a background thread.
Of course you don't have to do it that way if you don't want to. You could use postExecute() instead. Or you could store the result somewhere and then use any sort of message-passing API to notify the main thread that the result is ready, and so on.
I would advice to run all the 3 calls in the asyncTask, and update the UI in the postExecute() of the AsyncTask after the background taks is complete, postExecute runs on UIthread so you need not call anything explicit to run them on UIthread.
I'm building a news reader for Android, where the first Activity will show a list of the latest news, combined with a thumbnail preview image.
In order to get the thumbnail I have to run a method, which increase heavily the loading time; so, I was thinking to create a separate thread to run everytime.
More specifically I'd like to load the news titles first, and then load the pictures, one by one; while doing all this I don't want the UI to be locked (for instance, if an user touches a news I want the app to load it, even if thare are some thumbnails still loading).
My question is: should I use handlers (one thread for each news) or AsyncTask (one asyncTask object for each news) to achieve this?
Thank you for your replies.
Handler Vs AsyncTask
I would use an asynctask to download all the "news links" and then have that asynctask call an asynctask to download each thumbnail and update the UI onPostExecute. Then, if the user clicks a link before it is done, you could call cancel on the main Asynctask, which would check for isCancelled() between each thumbnail asynctask and would return if it was cancelled.
No doubt that AsyncTasks are more simplified and modularized than the thread-handler architechture, but internally they perform the action in same way.Coming to your problem, I would suggest that load the news first.Your news pojo/class can be like containing two feilds, title and imageUrl.Now display the news list and start another AsyncTask that fetches the images one by one and store them in a Data Str/list.your adapter should be "notifyDataSetChanged()" every time the image is fetched from server.
This way you are allowing user to see the news first, and the images are loaded without making UI get blocked.
i wit make asynch task for loading the data and then excute a task thats populate the list when the async task is don ore while it is running
I need some suggestion on how to go about this specific android problem:
activity A passes an intent to activity B,
B reads it, makes an API call,
B receives response, parses it, and updates its views from the response
now it works fine except fr a 2 second black screen during transition from A to B
is asynctask a solution? becoz the parsing data is not much and also is there a way to update UI views frm asynctask
To echo what Lalit said, an AsyncTask will help in this case. The problem that you're having is that doing the API call during onCreate is blocking the activity from updating the UI. If you use an AsyncTask, it will allow the activity to continue rendering the view.
As you're parsing the result, you can update the UI by calling Activity.runOnUiThread() or by putting the UI code in onPostExecute.
I'm not sure if AsyncTask is the best solution for your case.
An AsyncTask is very helpful if you need to do something in background and allow the user to do something else in the mean time.
I'd sugest to just use a Thread and define a progressDialog.
If you do it this way, your user will see the loading dialog with the spinning circe and not the black screen that looks more like if the App is freezing.
Let me know if you need help with some code samples.
Marco :)