Categories
discuss

Live Data: Candidate resolution will be changed soon

In same cases Android studio displays warning message when I call observe method of LiveData object

viewModel.emailValidationResult.observe(viewLifecycleOwner, {onEmailChanged(it)})

Candidate resolution will be changed soon, please use fully qualified name to invoke the following closer candidate explicitly:

public open fun observe(owner: LifecycleOwner, observer: Observer<in Int?>): Unit defined in androidx.lifecycle.LiveData

As I understand it’s happened after updating kotlin 1.4 What does it actually mean ?

Answer

It means that the extension in androidx is not needed anymore.

Simply remove its import import androidx.lifecycle.observe.

It will be actually deprecated in androidx. Read more reasoning there.

EDIT:

Please note the “issue” from Erik Hoogendoorn

This change causes values from the observed LiveData object to be interpreted as nullable(since the converted lambda syntax is based on nullable Java code). This was not the case for the Kotlin extension and causes a loss in functionality for the user. In my opinion this change should be reverted and a different solution found.

I’m curious if they will rename & retain the helper or come up with another solution.

Categories
discuss

Android 11 (API level 30) onTaskRemoved fired in Foreground service when app go to background

I tried to test app that I work with on android 11 (got it on Pixel 3 XL). I receive strange behaviour when app goes to background: onTaskRemoved fired on Foreground service and looks like app killed and restarted.

Info about Foreground service: in Manifest:

<service
    android:name=".MyFS"
    android:foregroundServiceType="mediaProjection"
    android:enabled="true"
    android:exported="false"/>

in FS class onStartCommand -> return START_STICKY;

Additional info: App using “camera” & “microphone” and I tried to add this two to android:foregroundServiceType=”mediaProjection|camera|microphone” but it didn’t help.

Also interesting that onTaskRemoved fired just on first time that app goes to Background, if I back to app and click “home” second time onTaskRemoved not called.

Please help me to understand from were it comes. Thanks

PS: Is it related? Before onTaskRemoved I can see in the full logcat this:

2020-10-05 09:33:19.866 1463-1524/? D/EventSequenceValidator: onIntentFailed during UNKNOWN.
    java.lang.Throwable: EventSequenceValidator#getStackTrace
        at com.google.android.startop.iorap.EventSequenceValidator.logWarningWithStackTrace(EventSequenceValidator.java:260)
        at com.google.android.startop.iorap.EventSequenceValidator.onIntentFailed(EventSequenceValidator.java:130)
        at com.android.server.wm.LaunchObserverRegistryImpl.handleOnIntentFailed(LaunchObserverRegistryImpl.java:147)
        at com.android.server.wm.LaunchObserverRegistryImpl.lambda$KukKmVpn5W_1xSV6Dnp8wW2H2Ks(Unknown Source:0)
        at com.android.server.wm.-$$Lambda$LaunchObserverRegistryImpl$KukKmVpn5W_1xSV6Dnp8wW2H2Ks.accept(Unknown Source:2)
        at com.android.internal.util.function.pooled.PooledLambdaImpl.doInvoke(PooledLambdaImpl.java:264)
        at com.android.internal.util.function.pooled.PooledLambdaImpl.invoke(PooledLambdaImpl.java:201)
        at com.android.internal.util.function.pooled.OmniFunction.run(OmniFunction.java:97)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.os.HandlerThread.run(HandlerThread.java:67)
        at com.android.server.ServiceThread.run(ServiceThread.java:44)
2020-10-05 09:33:19.866 1463-1524/? D/EventSequenceValidator: dec AccIntentStartedEvents to 2
2020-10-05 09:33:19.870 27662-27662/: t:main onTaskRemoved here.

Answer

For me, changing the activity launch mode away from singleInstance resolved the problem and onTaskRemoved is no longer called. I had 2 activities declared in the manifest with singleInstance. After changing them to singleTop the problem went away.

Change

        android:launchMode="singleInstance"

to

        android:launchMode="singleTop"

or remove it altogether

Obviously there are valid reasons for having singleInstance and this is still unexpected behaviour but for now it’s a valid workaround.

Categories
discuss

Access this.$root in Vue.js 3 setup()

In Vue 2, you can access this.$root inside the created hook. In Vue 3, everything that would have gone inside the created hook now goes in setup().

In setup() we don’t have access to this, so, how can we access anything on the root instance?

Say, I set a property on the root instance:

const app = createApp(App).mount('#app');

app.$appName = 'Vue3';

I can access this from mounted() with this.$root.$appName, how can I do this in setup()?


UPDATE

I can access it if I import it:

import app from '@/main';
...
setup() {
    console.log(app.$appName) // Vue3

But, this is a hassle if I have to do this for every file.


UPDATE 2

Another workaround is to use provide() inside App.vue and then inject() in any other components:

setup() {
    provide('$appName', 'Vue3')
setup() {
    inject('$appName') // Vue3

Answer

It seems you need provide / inject. In your App.vue:

import { provide } from 'vue';

export default {
  setup() {
    provide('appName', 'vue3')
  }
} 

Or provide it with your app:

const app = createApp(App);
app.mount('#app');

app.provide('appName', 'Vue3');

And then in any child component where you want to access this variable, inject it:

import { inject } from 'vue'

export default {
  setup() {
    const appName = inject('appName');
  }
}
Categories
discuss

Invalid version number: Version number may be negative or greater than 255

I am getting below error when I try to access a page in my application.

SEVERE: Servlet.service() for servlet [jsp] threw exception
java.lang.IllegalArgumentException: Invalid version number: Version number may be negative or greater than 255
    at com.ibm.icu.util.VersionInfo.getInstance(VersionInfo.java:191)
    at com.ibm.icu.impl.ICUDebug.getInstanceLenient(ICUDebug.java:65)
    at com.ibm.icu.impl.ICUDebug.<clinit>(ICUDebug.java:69)

I assume that it is due to some version mismatch. How can I trace the issue? The application is not mavenized and hence I am not sure how to check the issue. Atleast if I know which jarfile is giving issue then it will be good.

Answer

The problem is resolved as I downgraded my java version.

Categories
discuss

Is there a cleaner way to call multiple toggles & elements during a click event listener with vanilla JavaScript?

I have multiple toggles being called at the same time during a click /eventListener and it works but I’m wondering if there is a cleaner way to write the code where it doesn’t look so repetitive.

Here is a snippet of the code I’m trying to refactor/clean up. Any help or point in the right direction is greatly appreciated. Thanks!

document.getElementById("menu-toggle").addEventListener("click", mobileMenuToggle);

function mobileMenuToggle() {
    var hideMenu = document.getElementById("mobile-menu-container");
        hideMenu.classList.toggle("hide-menu");

    var hideMenuIcon = document.getElementById("menu-toggle");
        hideMenuIcon.classList.toggle("hide-menu-icon");

    var closeMenuIcon = document.getElementById("close-menu-toggle");
        closeMenuIcon.classList.toggle("show-close-icon");

    var closeMenuIcon = document.getElementById("container-bg-toggle");
        closeMenuIcon.classList.toggle("show-icon-bg");
}

Answer

Few other options

  1. To make it more concise, you can get rid of references, which you are not reusing

    function mobileMenuToggle() {
      document.getElementById("mobile-menu-container").classList.toggle("hide-menu");
      document.getElementById("menu-toggle").classList.toggle("hide-menu-icon");
      document.getElementById("close-menu-toggle").classList.toggle("show-close-icon");
      document.getElementById("container-bg-toggle").classList.toggle("show-icon-bg");
    }
    
  2. In case if these elements are nested, You can just write a css rule and do one toggle

    #mobile-menu-container.hide-menu .menu-toggle {
      display:none;
    }
    
    #mobile-menu-container.hide-menu .close-menu-toggle {
      display:block;
    }
    

    And you can just toggle the parent container alone

     function mobileMenuToggle() {
       document.getElementById("mobile-menu-container").classList.toggle("hide-menu");
     }
    
  3. In case if you are using jquery, you can use the jquery toggle, which is bit short

    $('#mobile-menu-container').toggleClass('hide-menu');
    
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..