Ways of loading bitmap/drawable to view async in android - android

I've got activity that has to do many things before it is visible. In proccess of loading view I have to load up bitmap/drawable that consume some time and prevents from other actions that could be done in that time. So i decide to move it to another thread. I've used Async Task, but this is not solid way of loading things. There are situations where task starts 1-2 sec after my view is shown! Is there anothe way to load bitmap/drawable that will not consume so much time and will allow to assign it to ImageView?

It is likely that you are still blocking your UI thread before executing the task. Use a logger to verify when your task is being executed.
If the task does take up a lot of time to execute then the bitmaps you are loading may be too large, in which case you should look at the down-sampling the images you are loading using the inSampleSize option with BitmapFactory.

AsyncTask runs tasks from a thread pool which might already be fully in use so it might have to keep the tasks in queue until a thread frees up to run new task. Though I doubt this is the cause of the problem.
You should maybe consider displaying a progress indicator before the actual view you want to show to make sure all tasks are done before the user sees them.
Edit
you could also use task.get(); after running all the other tasks to wait for the bitmap loader to complete before showing anything... but do try to keep the UI responding!

Related

Loading Animations while app gather's data

I'm working with an app that grabs a decent amount of data upon start each time since I need to immediately know things like location and weather fcst in the area.
In my mind I see a loading animation that smoothly moves around for 3 to 7 seconds while everything runs so there isn't just a blank screen or a static title image.
BUT:: I'm running into issues with getting animations or images to load before all of the data is searched for. And I only want the animation to run as long as data is loading. So I have the application switch to a new activity as soon as everything is loaded.
Is there a way to for the animation to run before things are done or do I need to somehow set everything up as an async task. And then how do I pass the async task to the next activity?
So I found an answer to my own question after reading some books. In short, the loading screen that i was looking for uses a splash screen with asynchronous tasks. Either AsyncTask directly or you can implement a service solution.
Extra: I noticed that if you run an async task which starts a GoogleAPIClient, onConnected executes on a pool thread or something, point being you can do UI work on the main thread again without wrapping back to AsyncTask.

Espresso + Picasso + Spoon

Picasso is using threads for loading images in the background. Even when loading from assets, there'a a slight delay until it shows up, which causes the pictures not to appear on a capture with spoon. I could add a 1s sleep in the test, but I was wondering if there was a better way.
I tried to set a Downloader or a RequestHandler to return the image synchronously, but I think I need to set a ExecutorService that uses the main thread or an AsyncTask (such that espresso will wait). With retrofit, we can use AsyncTask.THREAD_POOL_EXECUTOR with MainThreadExecutor but I'm not sure how to do it for picasso.
As a workaround, I wrapped picasso in an ImageUtil which won't be used during instrumentation:
DebugModule {
#Provide
ImageUtil imageUtil() {
if (isTest) {
return TestImageUtil();
} else {
return PicassoImageUtil();
}
}
}
Any suggestions?
update: in picasso's code, attempting to use an Executor instead of ExecutorService, I got stuck on service.shutdown().
I'm going to give you the general method for waiting on asynchronous tasks using espresso, because you can be sure that this will come up again.
You shouldn't use thread sleeping to wait for things to happen. This can cause flakiness, and causes your tests to be less efficient. Espresso was designed with avoiding sleep calls in mind.
You also shouldn't force something to be on the main thread that isn't normally on the main thread. If this causes an ANR your test could fail because of the unexpected dialog pop-up. There could also be a real bug that only happens while multi-threading, but now that you're forcing something to execute on the main thread, your tests could miss it.
You're on the right track swapping out a different wrapper for Picasso for testing. What you need is a way to hook on to when the request gets started (right before it goes off the main thread), and when the request gets finished. Swapping out a wrapper is one way to do accomplish that.
To get notified of when the request is finished, you can use the callback version of the into method.
Now that you have the entry and exit points of your asynchronous task, you can use the CountingIdlingResource to keep your test from moving on until the task is finished. It's as simple as incrementing the counter before the task starts, and decrementing it when it finishes.
Here's a great example of how to use that class: https://android.googlesource.com/platform/frameworks/testing/+/android-support-test/espresso/sample/src/androidTest/java/android/support/test/testapp/AdvancedSynchronizationTest.java?autodive=0%2F%2F

AsyncTask pause and resume

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.

Is using runOnUiThread inside AsyncTask inefficient and bad?

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.

What is the need of Asynchronous Task

We have to use Asynchronous Task to start our new Activity on Tab Click event but in the ListView or any view we can directly can start the new activity Why?
http://developer.android.com/reference/android/os/AsyncTask.html
AsyncTask enables proper and easy use
of the UI thread. This class allows to
perform background operations and
publish results on the UI thread
without having to manipulate threads
and/or handlers.
An asynchronous task is defined by a
computation that runs on a background
thread and whose result is published
on the UI thread.on the UI thread.
Basically you want to avoid that the loading process/device hangs when loading loads of data to the list initially, that's why you make it async, outside the UI thread, so the user can use the app while data is loading in the background.
Starting an activity is faster than loading lots of initial data into a long list view, especially if it's remote data from a remote server. Therefore the app you're looking at is probably using this here.
If you want to perform some task in background at the same time you want to do another task at the forground.
http://developer.android.com/reference/android/os/AsyncTask.html
This link surely will help you.
You just try this one will help you.
http://xoriant.com/blog/mobile-application-development/android-async-task.html

Categories

Resources