Flutter 120fps issue - android

scenario:
have an application in flutter with a hard-coded list of 20 cards after a release build of this on my 120 fps devices it still feels like 60 fps how to fix it while the native android counterpart has a smooth render at 120 fps.
have tries the above scenario will the scrolling based widget both builder-based and normal ones.
Is it a flaw in flutter that it doesn't render at 120 fps.

On Android phones with 120hz display by default is chosen the wrong display mode (e.g. 60hz instead 120hz). This can easily be corrected, then performance on phones like Oneplus 8T or Galaxy S20+ is great.
Import flutter_displaymode library:
flutter_displaymode: ^0.3.0-nullsafety.0
Add this to your root widget (stateful):
class _YourAppState extends State<YourApp> {
#override
void initState() {
setOptimalDisplayMode();
super.initState();
}
Future<void> setOptimalDisplayMode() async {
final List<DisplayMode> supported = await FlutterDisplayMode.supported;
final DisplayMode active = await FlutterDisplayMode.active;
final List<DisplayMode> sameResolution = supported.where(
(DisplayMode m) => m.width == active.width
&& m.height == active.height).toList()..sort(
(DisplayMode a, DisplayMode b) =>
b.refreshRate.compareTo(a.refreshRate));
final DisplayMode mostOptimalMode = sameResolution.isNotEmpty
? sameResolution.first
: active;
/// This setting is per session.
/// Please ensure this was placed with `initState` of your root widget.
await FlutterDisplayMode.setPreferredMode(mostOptimalMode);
}
}
Note, that right now there are no 120hz iPhones, so there is no need to execute them.

You must profile your performance metrics. check out this https://flutter.dev/docs/perf/rendering/ui-performance

Please try this, you can use media query for sizing your widget.
MediaQuery.of(context).size

Related

Cannot get video feed from Mavic 2 Enterprise Dual in Mobile SDK

I'm trying and failing to get a camera-feed on the Mavic Enterprise 2 dual, using the Mobile SDK. I am connected to the drone, and my app runs fine and displays the video with both the Mini2 and Air 2S. I am on MSDK 4.16.4.
It seems like the problem video-data listener, defined in activity onCreate, is never called. Here is the snippet of relevant code. On the Mini2 and Air2S (with R1-N1 controller), the video-data-listener is called. On the ME2 Dual (with the controller that came with the drone), the video-data-listener is never called.
textureView.surfaceTextureListener = FakeTextureView(
codecCallback = {
mCodecManager = it
primaryVideoFeed.addVideoDataListener { videoBuffer, size ->
freshFrameAvailable = true
mCodecManager?.sendDataToDecoder(videoBuffer, size)
}
},
applicationContext = applicationContext
)
Is there some extra step required for ME2 Dual that I'm missing?

Expo-image-picker crashes app after using launchCameraAsync() on Android

I'm using expo-image-picker to allow the user to pick and take pictures. Choosing an image from the library works as expected but when using the camera, after taking the picture the app crashes.
Here is my code:
const take = async () => {
let result = await ImagePicker.launchCameraAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
quality: 1,
});
console.log(result.uri);
if (!result.cancelled) {
setImageUri(result.uri);
}
};
I think I have all the required permissions and the problem seems to occur only on older android devices with limited memory. Any ideas?
There is no good and easy solution.
What is happening is, when you launch the camera, it launches as a new Activity, leaving your app mainActivity in background.
From Android P (9) and on, the OS can kill your background activity. There is even a website just about whose implementation is worse for devs: https://dontkillmyapp.com/
Possible solutions:
Be prepared to crash. Save all states and navigation stack on local-storage, launchCamera. The app will restart, you will restore all the screen/navigation/data/etc, and get photo using the ImagePicker.getPendingResultAsync.
Change lib to expo-camera or react-native-vision-camera as they use the camera on mainActivity but needs boring reimplementation, and don' t look as good as the manufacturer native cameras.

Flutter Dart - isolate stops working when screen is off

I have code to refresh data from server which I need to run even when screen is off. I tried to do this with an isolate:
static void isolateFunc(SendPort mainSendPort) async{
String _answer = "";
while(true){
Socket socket = await Socket.connect(ipAddress, port, timeout: Duration(seconds: 5));
socket.add(utf8.encode("connection test"));
socket.listen((List<int> event) {
_answer = utf8.decode(event);
});
socket.close();
await Future.delayed(Duration(seconds: 5));
}
}
This works fine when screen is on. But after switching off the screen it refreshs maybe for 5 times normally, then it refreshs for a few times each 30 sesconds(even when the delay is set to 5 seconds) and then it just stops. I am calling the isolate from initState like this:
#override
void initState() {
super.initState();
anotherRefresher();
ReceivePort recievePort = ReceivePort();
Isolate.spawn(isolateFunc, recievePort.sendPort);
}
Battery optimalisation in android settings is off. I do not understand this :/ Any ideas how to deal with this please?
After some time I found that, there is no way how to keep running dart code in the background without setting it as background or foreground process. Both Android and iOS will always restrict your code to increase battery life. Even turning off battery optimisation will not help. So to keep dart code running even when screen is off, you need to set up background or foreground process. For this you can do some platform native coding and connect it through platform channels or use plugins. Since I don't know Swift or Kotlin, I decided to find some plugins. I have tried more of them and after some time I can say that plugin flutter_background_service is one of the best. Or based on your needs you can find another plugins or try to code it by yourself. Wish you good luck :)

How do you configure local_auth in flutter correctly if you want to secure the whole app with it (e.g. bank apps)?

We have the problem that we want to protect the complete app with a fingerprint/TouchID/FaceID. I will only mention fingerprint here, which always means all biometric features of local_auth. Partly this works quite well with the function "didChangeAppLifecycleState", but only partly.
Since under iOS the app becomes inactive while the fingerprint is being queried, the query comes in a continuous loop when queried at "AppLifecycleState.resumed". Therefore we set a timestamp at "AppLifecycleState.pause" and query the fingerprint at resume only if x seconds have passed since the app was paused. We have now also set this to a slightly higher time, so that the lock does not go on immediately if you have to switch to the camera from the app. Of course there are more checks, but that's the basic idea right now.
Here is the problem that flutter takes some time to execute paused. Both iOS and Android. So if you now quickly minimize the app and open it again (because minimizing was perhaps an accident?), the fingerprint comes directly. Nothing serious, but unpleasant.
Our real problem, which I can't really understand, since I don't know how to debug it either. If the app hasn't been used for a long time, especially on a Monday after the weekend, then work colleagues have the problem that they can simply start the app without a fingerprint. So far only noticed under iOS, since the colleagues use all iOS, but does not exclude that it could happen under Android as well.
I just don't know how to fix it. Has anyone had any experience with this? Or is there a very simple way to use the fingerprint in flutter in a way that you can open the app only with fingerprint, maybe at a completely different place than "didChangeAppLifecycleState"?
Kind regards,
Jakob
As far as I understand you are using lifecycle hook to prompt for biometric verification and you are having issues. The following is the solution if I understand your query right.
First instead of using lifecycle to verify the biometric check. Can you not use initialization widget which gets called every time before opening up the app. Here is an example.
class Initialize extends StatefulWidget {
_InitializeState createState() => _InitializeState();
}
class _InitializeState extends State<Initialize> {
void initState() {
super.initState();
_initialize();
}
Future<void> _initialize() async {
final userDetails = await getUserSavedDetailsFromStroage();
await doAnyOtherTask();
final user = authService.checkIfPrevLoggedIn(authDetails);
if (user == null) {
_gotoLogin();
} else {
if (userDetails.biometricEnabled) {
final verified = await biometricService.onBiometricVerify();
if (!verified) {
_gotoLogin();
return;
}
}
authService.refreshUser();
_gotoHomePage();
}
}
#override
Widget build(BuildContext context) {
return SplashView();
}
}
And your main.dart file will pretty much look like the following, I am assuming you are using Provider package for state management.
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => AuthService.instance,
child: MaterialApp(
home: Initialize(),
title: 'App Title',
),
);
}
}
you can set a flag that local auth request is pending.
If you got a response then set the flag back to false with a Futuredelay of 150ms.
Request the local auth in your AppLifecycleState.resumed only if the request is not pending.

React native - When i lock the screen while API call loading, App process stopped

I am trying to show a large list in react native - Expo. When I lock the screen while data loading via API. App State changed from "Active" to "Inactive".
When I return to an active state, no data has been loaded. The App processes are stopped. ListEmptyComponent renders the ActivityIndicator. It is loading indefinitely. It occurs only in android build.
I tried to recall the API by AppState.
const handleAppStateChange = nextAppState => {
console.log(nextAppState);
if (nextAppState === 'active') {
console.log(JSON.stringify(Store.apiCall));
// "Store.apiCall" has data about last API Call and its status.
if (Store.apiCall.status === codes.PENDING || Store.apiCall.status === codes.ERROR) {
api(Store.apiCall.payload);
}
}
setAppState(nextAppState);
};
Still it doesn't works..
This happening because of the battery optimization features of newer Android versions. The only fix would be to ask the user to disable the battery optimization for your app by redirecting them to your app settings or you can use a node package like this one:
https://www.npmjs.com/package/react-native-disable-battery-optimizations
Also, if you dont want your device to sleep if its in active state you can use something like this:
https://www.npmjs.com/package/react-native-keep-awake
Hope this helps :)

Categories

Resources