Categories
discuss

What is the exact use of fastify-plugin

I new to fastify framework for node.js, and I’m asking for what is the exact use of fastify-plugin
because I can’t get the the idea behind it. I tried some code with or without the plugin and I can’t notice the difference. except for some behavior like :

1- I can override the decorator I initiate and wrapped it with fastify-plugin.

2- I can use and share the decorator with other registered plugins.

Answer

The concept is this one:

  • every register call will create an encapsulated context
  • every register + fastify-plugin will not create an encapsulated context: you will stay in the same context where the register was called

An encapsulated context you will use:

  • all the hooks in the context and in its parent
  • all the decorators in the context and in its parent

Here a visualization:

encapsulation

so, if you add an onRequest hook in the root node (the blue one), all the routes will execute that hook.

if you add the onRequest hook in the green one instead, ONLY the routes defined in that context will use that hook.

Categories
discuss

R8: NullPointerException during IR Conversion

I have a problem when trying to generate a release version of my app. It gives a strange error

C:Usersrshal.gradlecachestransforms-2files-2.16c326691eb00442622017dd95f96e92ajetified-firebase-config-19.1.3-runtime.jar: R8: NullPointerException during IR Conversion
> Task :app:minifyProdReleaseWithR8 FAILED

I have been using firebase analytics and firebase remote config without problems. And also I had no issue this R8 minimization. Recently I have integrated google-speech-api and after that, I am not able to use R8.

I did not have this problem until I integrated google-speech-api in the app. I know that google-speech-api is not officially supported on Android. Maybe that is the core issue. Before that, I had an issue with firebase-config dependency. It is not compatible with the google-speech-api library I think. I solved that issue with this Gradle configuration

implementation('com.google.firebase:firebase-config', {
    exclude group: 'com.google.protobuf' // google-cloud-speech causes this. see  https://github.com/firebase/firebase-android-sdk/issues/1143
})

I have followed this fix.

Now I am stuck with this error that I showed above.

I have tried different versions on R8 as suggested here

This is gradle build log

> Task :app:minifyProdReleaseWithR8
R8: Missing class: org.apache.logging.log4j.spi.ExtendedLoggerWrapper
R8: Missing class: org.eclipse.jetty.npn.NextProtoNego$ClientProvider
R8: Missing class: javax.servlet.ServletContextListener
R8: Missing class: org.jboss.marshalling.ByteOutput
R8: Missing class: java.lang.ClassValue
R8: Missing class: org.eclipse.jetty.alpn.ALPN$ClientProvider
R8: Missing class: org.jboss.marshalling.ByteInput
R8: Missing class: org.eclipse.jetty.alpn.ALPN$ServerProvider
R8: Missing class: org.eclipse.jetty.npn.NextProtoNego$ServerProvider
R8: Library class android.net.http.AndroidHttpClientConnection implements program class org.apache.http.HttpInetConnection
R8: Library class android.net.http.AndroidHttpClientConnection implements program class org.apache.http.HttpConnection
C:Usersrshal.gradlecachestransforms-2files-2.16c326691eb00442622017dd95f96e92ajetified-firebase-config-19.1.3-runtime.jar: R8: NullPointerException during IR Conversion

> Task :app:minifyProdReleaseWithR8 FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:minifyProdReleaseWithR8'.
> com.android.tools.r8.CompilationFailedException: Compilation failed to complet

this is build.gradle file

this is top-level Gradle file

Answer

Answering my own question because it turned out to be an R8 bug and after me reporting it, they solved the issue. Which is great.

Full bug report and how to apply fix is here

Short version:

change gradle configuration to this

buildscript {
repositories {
    maven {
        url 'https://storage.googleapis.com/r8-releases/raw'
    }
}
    dependencies {
        classpath 'com.android.tools:r8:1.6.88'          // Must be before the Gradle Plugin for Android.
        classpath 'com.android.tools.build:gradle:3.6.2'
     }
}

I have encountered this bug when implementing Google Speech API in my android app. For anyone who might need it, this is my final groguard configuration

-keep class com.google.api.gax.** {*;}
-keep class com.google.cloud.** {*;}
-keep class com.google.api.services.translate.** {*;}
-keep class com.google.api.client.util.** {*;}
-keep class com.google.api.client.googleapis.** {*;}
-keep class com.google.cloud.speech.v1.stub.** {*;}
-keep class io.grpc.** {*;}
-keep class com.google.auth.oauth2.** {*;}
-keep class com.google.auth.** {*;}
Categories
discuss

How to measure the execution time of an asynchronous function in nodejs?

I’m trying to get the execution/response time of an asynchronous function that executes inside a node-fetch operation, like the following

async function getEditedData() {      
       var a = await fetch(`https://api.example.com/resorce_example`);
       var b = await a.json();
       // Some aditional treatment of the object obtained (b)
       console.log("End of the asynchronous function")
}

I Used the library perf_hooks like this, but the execution time shows before

const hrtime = require ('perf_hooks').performance.now ;
var start = hrtime ();
   getEditedData();
var end   = hrtime ();
console.log (end - start);

I found the async_hooks library https://nodejs.org/api/perf_hooks.html#perf_hooks_measuring_the_duration_of_async_operations , but I can´t understand how it works. I am a basic in javascript/nodejs

Answer

You could simply store Date.now() in some variable and then check Date.now() when your Promise resolves (or rejects) and subtract to find the difference. For example:

const simulateSomeAsyncFunction = new Promise((resolve, reject) => {
  console.log('Initiating some async process, please wait...')
  const startTime = Date.now();

  setTimeout(() => {
    resolve(Date.now() - startTime);
  }, 3000);
});

simulateSomeAsyncFunction.then(msElapsed => {
  console.log(`Async function took ${msElapsed / 1000} seconds to complete.`);
});

Note: You could write code that achieves the same thing and appears to be synchronous by using await/async since that is just “syntactic sugar” built on top of Promises. For example:

const simulateSomeAsyncFunction = () => {
  console.log('Initiating some async process, please wait...');

  return new Promise((resolve, reject) => {
    setTimeout(resolve, 3000);
  });
};

// Await is required to be called within an async function so we have to wrap the calling code in an async IIFE
(async() => {
  const startTime = Date.now();

  await simulateSomeAsyncFunction();

  const msElapsed = Date.now() - startTime;

  console.log(`Async function took ${msElapsed / 1000} seconds to complete.`);
})();
Categories
discuss

MediaBrowserService with ExoPlayer and PlayerControlView – How to access to the player instance from the UI (PlayerControlView)?

I am currently working on a part of an app which has video and audio functionality, and started refactor the code base recently. The goal is to integrate MediaSession/ MediaController and MediaBrowserService/ MediaBrowser framework.

We use ExoPlayer and PlayerControlView more specific, the PlayerView for both video and audio components, and it requires the reference to the player instance for the PlayerControlView:

/**
   * Sets the {@link Player} to control.
   *
   * @param player The {@link Player} to control, or {@code null} to detach the current player. Only
   *     players which are accessed on the main thread are supported ({@code
   *     player.getApplicationLooper() == Looper.getMainLooper()}).
   */
  public void setPlayer(@Nullable Player player) {...

However, under the android developers post and the documentation of MediaBrowserService, the player instance should be contained under the service. In addition, the only way for the client site (MediaBrowser and MediaController) to talk to service it through the connect() method and MediaBrowserConnectionCallback, which makes passing the instance of the player to the PlayerControlView (or the other way around) not possible.

I have tried using the various callbacks such as the MediaSessionCompat.Callback, but neither of the SimpleExoPlayer or the PlayerControlView are Parcelable.

In the traditional service, we uses Binder to access the methods we declared within the service and do something like:

boolean attachPlayerControlView(PlayerControlView playerControlView) {
            if (player != null) {
                playerControlView.setPlayer(player);
                return true;
            }
            return false;
        }

However, this seems no possible with the MediaBrowserService/ MediaBrowser framework. I checked the answer to this question, which indicates that using [sendCommand] is a way to call custom methods. But it also requires the parameters to be Parcelable.

To sum up, my question is, is there a way to have the PlayerControlView access to the instance of SimpleExoPlayer or the other way around under the MediaBrowserService framework.

Many thanks ahead for any answer or comments.

Answer

In addition, the only way for the client site (MediaBrowser and MediaController) to talk to service it through the connect() method and MediaBrowserConnectionCallback, which makes passing the instance of the player to the PlayerControlView (or the other way around) not possible.

According to my understanding, this is not correct. You can always bind to MediaBrowserService in a traditional way i.e using IBinder to access Service. (Though I am not sure if this is the correct approach or not, otherwise I have to create a static MediaPlayer instance in Service).

I have faced a similar issue with Video Playback using MediaPlayer. I have bound to MediaBrowserService using IBinder and then fetched the MediaPlayer instance. In your service provide a method that returns a reference to MediaPlayer. Something like this:

private MediaPlayer mediaPlayer;

@Override
public IBinder onBind(Intent intent) {
    if (intent.getAction().equals("YOUR_INTENT")) {
        return new LocalBinder();
    }
    return super.onBind(intent);
}

public class LocalBinder extends Binder{
    public AudioService getService(){
        return AudioService.this;
    }
}

public MediaPlayer getMediaPlayer() {
    return mediaPlayer;
}

In your Activity/Fragment then bind to MediaBrowserService using IBinder. In my implementation, I have used MediaPlayer, but I think in similar ways it can be used for Exoplayer.

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{

private MediaPlayer mediaPlayer;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private boolean isServiceBounded;
private boolean isSurfaceReady;

private ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        isServiceBounded = true;
        mediaPlayer = ((AudioService)service).getMediaPlayer();
        if (isSurfaceReady) {
            mediaPlayer.setDisplay(surfaceHolder);
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        isServiceBounded = false;
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    surfaceView = findViewById(R.id.surfaceView);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    bindService(new Intent("YOUR_INTENT"), serviceConnection, BIND_AUTO_CREATE);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    surfaceHolder = holder;
    isSurfaceReady = true;
    if (mediaPlayer != null) {
        mediaPlayer.setDisplay(holder);
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    isSurfaceReady = false;
    if (mediaPlayer != null) {
        mediaPlayer.setDisplay(null);
    }
    surfaceHolder = null;
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unbindService(serviceConnection);
}

}

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..