I have build a plugin which performs machine learning tasks on an image and this takes up to a minute (or event more). During this time when the plugin is working, the flutter UI freezes and the OS shows an error asking whether we should wait or just kill the app.
I got 2 problems:
Flutter UI hangs even though the plugin is of course async
The plugin doesn't allow delayed result e.g. from a coroutine (I get this error: E/DartMessenger(15585): java.lang.IllegalStateException: Reply already submitted)
You can use Isolates, as quoted from this medium article on isolates:
If you have a computation to perform that’s so enormous it could
cause you to drop frames if it were run in the main isolate, then you
can use Isolate.spawn() or Flutter’s compute() function.
more info:
https://flutter.dev/docs/development/packages-and-plugins/background-processes
https://youtu.be/vl_AaCgudcY
Related
I had an issue to run my ui test
#Test
fun firstUi() {
onView(withId(R.id.home_profile_tab)).perform(click())
onView(withId(R.id.enter)).perform(click())
onView(withId(R.id.tvCountryCode)).check(matches(withText("+964")))
}
This test run and passed
But the issue is, after running test and reaching to first line, the firs perform(click)) executed after around 90 seconds, and it is almost constant and every time it takes 90 seconds
But after that (90sec) other lines executed and test completed around 4 seconds and passed successfully
Base on android documentation:
Each time your test invokes onView(), Espresso waits to perform the
corresponding UI action or assertion until the following
synchronization conditions are met:
The message queue is empty.
There are no instances of AsyncTask currently executing a task.
All developer-defined idling resources are
idle.
So how and where can I investigate more to detect to root cause of issue???
Or what I'm doing wrong???
With the help of this post I found what was my issue
I live in iran and most of services because on sanctions are banned here
So I looked in Frames, so I found that some AsyncTask are exist for some sdk, that are trying to send request to their server, but because of ban they couldn't
So they keep retrying, maybe after 90sec without a successful request call they give up, and Espresso requirements meet to continue running tests
My Solution was using VPN, so sdk can successfully make request to their servers
My test suite runs fine on iOS, the app has many background processes running that prevent large portions of the tests from working in synchronized mode. The desynced commands run properly on the iOS simulator, but when I run them on the android emulator it is as if I never called await device.disableSynchronization().
The tests still hang and the console logs:
The app is busy, due to:
- Enqueued timers
- Animations running on screen
Any ideas about how to fix this?
Further review shows the error message:
The app has not responded to the network requests below:
The odd thing is the listed network request has been completed. The request upon which the app purportedly has not responded is a button push that navigates to a new screen which incurs a somewhat lengthy network request. After the network request completes other processes continually run necessitating the disabled synchronization. Since Detox is still waiting on some response from the app about the button tap, it does not move on to the next, desynchronized, actions. Is there any way to ensure that Detox receives the response of this .tap()?
A deeper investigation reveals that this is likely caused by a lingering animation that, for whatever reason device.disablesynchronization() ignores on Android builds. I am now working on mocking this file based on the out-of-date documentation provided by wix.
I have made setup of Jenkins in my system. I am not able to execute 2 or more job at same time.
It is running one after another. Is there any way to run multiple jobs at the same time in different projects.
i.e Consider I have 2 projects Android & iOS. Once I start a job from Android it will take 10 mins. While the android job is running, I am not able to execute job from iOS. It is waiting for Android to complete.
You don't need a plugin to execute jobs simultaneously as long as the jobs themselves are independent.
What you do need to do is make sure you have multiple executors that can take jobs from the queue.
If you click on a node in the build executor panel then hit 'configure', you can set the number of executors to be more than one. By default jenkins has only one Build executor, 'Master'.
Be careful doing this if your jobs rely on one another or share resources. If that is the case, then you are better served by using a slave executor.
I am trying to optimize a complex data updater and parser for my Android app. The server provides three interface functions. The parser requires the data from all those three functions.
When the download of the data is finished, the parser can start. It consists of many different independent tasks which can be parallelized.
I was thinking of using Futures or FutureTasks for processing the data.
So basically, this is the procedure:
create Task-1, Task-2, Task-3 for downloading the data
wait for the downloads to be finished
create Task-1,..., Task-N for parsing the data
wait for the parser to be finished
call a callback to signal that process is done.
My first question: is it possible to create Futures with asynchronous functions, which use callbacks to return the data (network framework)?
Second question: are there any drawbacks in using Futures or FutureTasks respectively in this scenario or are there any better solutions to achieve that?
Thank you.
Basically you are Trying to achieve the following.
Step 1 - User from UI starts 1,2,... n download tasks.
Step 2 - Once each of the task is completed, new thread should be started to process it.
Step 3 - Once all n Tasks are completed, UI should be updated ... may be with a success dialog.
This can be achieved easily by using Async Task. I am going to tell you the approach and not the code sample.
Things to note about Async Task
Before 1.6, Async Task handles all background operations with a single additional thread.
After 1.6 till 3.0 .. it was changed, so that a pool of thread had begun to be used. And operations could be processed simultaneously.
Since Honeycomb default behavior is switched back to use of a single worker thread (one by one processing).
How to implement your requirement
For your requirement, you can use the method (executeOnExecutor) to run simultaneous tasks (1 till n tasks) if you wish (there two different standard executors: SERIAL_EXECUTOR and THREAD_POOL_EXECUTOR).
The way how tasks are enqueued also depends on what executor you use. In case of a parallel one you are restricted with a limit of 10 (new LinkedBlockingQueue(10)). In case of a serial one you are not limited (new ArrayDeque()).
So the way your tasks are processed depends on how you run them and what SDK version you run them on. As for thread limits, we are not guaranteed with any, yet looking at the ICS source code we can say that number of threads in the pool can vary in range 5..128.
When you start too many tasks (like 100s or more) with default execute method serial executor is used. Since tasks that cannot be processed immediately are enqueued you get OutOfMemoryError (thousands of tasks are added to the array backed queue).
Exact number of tasks you can start at once depends on the memory class of the device you are running on and, again, on executor you use.
So by following this approach, once all the tasks are completed, you can use a handler to update the UI.
Hope this helps.
I am using libDispatch (GCD) opensource on Android platform.
So, most of the complex time consuming tasks are being done through NDK (where i am using libDispatch).
For some calls, I am using dispatch_async(get_main_queue)...This is where the problem is coming...
I am able to run tasks in the concurrent queues but not on main queue.
Since this requires dispatch_main() to be called which we cannot do on here as Java thread will be blocked in that case.
So, is it possible to run the Java UI on some secondary thread and hook the dispatch_main() to serve the dispatch_main_queue here?
OR : Do I need to keep serving the main_queue from JAva main UI thread through JNI ?
Look into _dispatch_main_queue_callback_4CF which is the function you can call to drain the main queue. It will return like a normal sensible function after executing the queued operations, instead of killing the thread like dispatch_main.
Note that you'll need to call _dispatch_main_queue_callback_4CF on a regular basis from your Java UI thread, possibly each iteration. The official Cocoa implementation uses _dispatch_queue_wakeup_main() which uses mach messages to kick the main thread out of any sleep states so it can guarantee the callback function is called quickly, but you'd have to do some work to enable that and build your own libDispatch port. In reality on Android I don't think the main UI thread is ever put to sleep while your app is active so it shouldn't be an issue.
There is a ticket open on the libDispatch site at https://libdispatch.macosforge.org/trac/ticket/38 to make _dispatch_main_queue_callback_4CF a public function. The ticket is marked "Accepted" but no word on if/when that will happen.