I have an navigation drawer Activity in which I have made 3 fragments using ViewPager. Each of the fragment has an edit Text, Image button and RecyclerView. The RecyclerView is getting data from a local SQLite database.
On opening the app, I get a Log trace that application skipped XX frames.
(Usually 30-50 frames). Is it normal ? If not, then what should I do? Can fragments be made using background thread like AsyncTask? Or should I populate RecyclerView in background thread?
Is it normal?
Nope. Check out Choreographer (start at line 619) if you are eager to find out what's happening behind the scenes.
what should I do? Can fragments be made using background thread like AsyncTask?
You can't do anything with Views on a background Thread since that would cause a CalledFromWrongThreadException, but what you definitely can and should do is moving all performance-heavy operations like DB read/write to worker Threads. Check out the AsyncTask and AsyncTaskLoader chapter from "Android Developer Fundamentals Course", it will give you a good start on background processing.
Also note that the LoaderManager from the support library is not deprecated.
Related
I have an ImageView. When user presses button I want to change image (it is animation-list) and run this animation. I used to use setImageResource, but it blocks UI thread and causes lags. I can't predict what image I would set befor user presses button. I tried to preload drawables but it causes OOM, because I have about 30 xmls with animation-list. How can I solve It? To sum up, I want to fastly change image in my ImageView and then start frame animation on it.
I think you are performing a fetch operation on the UI thread for the image(either from storage or network call). That is what is causing the lag.
You might look into using a library to load up your images. There is one that is really easy to implement called Picasso. It's been around for a while too, so it should be easy to see some examples.
I am trying to make an App which is going to display Some Images and Videos. So I am planning to add a splash screen of around 2seconds. After 2 seconds the user will be taken to the Main Screen of the App.
I want to start the loading of the Images, Video when then user is at the splash screen itself so that the user should wait for the least time when he is at the Main Screen.
So the loading will be started at the Splash Screen and then after two second the user will be taken to main screen irrespective of the completion of the loading.
Now since this involves two activities should I use a Async task or should I Use a service with an Async Task(For the callback of completion of code) within it?
Which one would be better. Also in Android 8.0 are there any restriction in using Services?
I think using a Async Task between two screens may cause Memory leak if not coded properly.
Any help would be really grateful.
EDIT: My app is having one more feature hence cannot make the user wait in the Splash Screen till the loading is over.
It is not very good to use AsyncTask for sharing results between 2 activities, because AsyncTack created in Splash activity will be destoyed (stopped) when switched to Main activity. Better to use service in this case and Main screen will subscribe for result.
So basically you want to start the download in the splash screen and continue the download in the activity that follows. In this way, you still have to implement a loading animation. In your case, I would recommend finishing your splash screen, as soon as everything is downloaded. In that way, you don't have to download anything anymore inside the app's lifecycle.
AsyncTasks continue to run even after switching to a new activity. You can try the following flow:
1. Splash screen
2. Trigger Async Task
3. Main Activity
4. Show Images/Videos
The only catch is, you will not be able to fix a time for #2 to complete to be able to start #4. This is the nature of AsyncTasks. You can workaround by using the OnPostExecute within AsyncTask.
Example: OnPostExecute call another method that will enable a button. Users can click on the button to view Images/Videos. But then, this might not be a good user experience to see some button suddenly getting enabled.
In that case I would rather create some Singleton with own Handler (that works in separate Thread), that will be started at Splash screen. After Main screen will start, it should ask that Singleton about respective data or should sign himself for receiving that data.
I am working on an app in which i have two Fragments hosted in one Activity. The acitivity layout has a bottom bar which has buttons that switch the two fragments.
In those fragments there are Threads that do some internet work and then update their layout.
Hieararchy:
Activity
Fragment 1
Thread 1
Fragment 2
Thread 2
The problem
The problem is that when, say Thread 1 starts doing some work, the user clicks the button to switch to Fragment 2, the Thread continues to run in the background, and when it is done with it's network task and tries to update the view (in the now not visible Fragment 1), the app crashes because getActivity() or getContext() now returns null.
EDIT: The thread uses getActivity() and getContext() a lot, not only for updating layout, but also for saving SharedPreferences, etc. I can add an inspection (if(!stopped) for example) to every line that uses Context, but i thought there is a better way than wrapping every step in an if condition.
So how do I kill either the Thread or Fragment completely? I don't need the background work running when the fragments are switched, I only need it to run when the fragment is visible.
I have tried both Thread.interrupt() and removing the fragment (instead of replacing) using getSupportFragmentManager.remove(Fragment fragment). Did not work.
Thanks in advance :)
You may check in your thread whether getActivity() is null and in this case do not perform UI update. A better aprach would be to stop your download once a user switches to another fragment - how to do it depends on what HTTP client you are using. With HttpURLConnection it should suffice to call disconnect().
Instead of using Thread consider using AsyncTask which has support for being cancelled. For examples search SO, here is one: Ideal way to cancel an executing AsyncTask.
I am using fragments to display the information to the user.
Question is. Four of the fragments need to load a lot of information before they are displayed. How can i show a spinning progress bar (not locking the UI-thread) while i fetch the data for the fragment?
Should i create a fragment called ProgressBar that only contains a progress bar. Then show this fragment while i load the new fragment in another thread?
Seems a bit silly to have the progress bar in each of the fragments or is this the normal approach?
I think it would suffice to display indeterminate progress similar to how ListFragment does it out of the box. Don't think of it as loading the fragment though. You're waiting for the fragment's data to load. The Fragment loads immediately, displays an indeterminate progress bar, then registers a callback that will later fire and populate its UI with the retrieved data.
you should put in your fragment life cycle callback while you doing lost of stuff
I think onCreateView just create progress bar use asyn task for long running task then stop progrss bar this is general way i think people used.
thanks
I think you can have a seperate <view> in each of the fragment to show progress in each fragment. This way it will not freeze the other fragment and also it will not freeze the user. Fragments are useful only if the users are not halted.
I have taken over an Android project from a past employee and am wondering if there is an easy tool to use for profiling an Android application. I have a LinearLayout with a ProgressBar spinner inside of it. Now I am running a network call on a different thread while that spinner is showing. I use a translate animation to show the entire LinearLayout and when the network call returns on the other thread I hide the LinearLayout. Now this works great but I see that the spinner kind of stops spinning while it is showing. Now it kind of looks like if I interact with the screen, such as trying to scroll, the spinner will continue to spin. For a standard ProgressBar spinner do I need to set some command on the spinner to keep it spinning? Any information on this would be great.
Thanks
You could use StrictMode to detect expensive calls that are being done on the UI Thread.
Why not try implementing your network call in an AsyncTask? In the onPostExecute method implementation you can do whatever is necessary on the UI (i.e hide your progressBar, etc.).
Or, if you are using the compatibility / support library, or targeting Honeycomb or later, use a Loader instead.