How to get product's frontend url from backend?

I answer my question. mtns_cll's answer the question of Magento 2 get frontend store url for a path in admin works for me.

I post my solution here in case someone need it:

product frontend:

inject \Magento\Framework\Url $url

$url->getUrl('catalog/product/view', ['id' => $entityId, '_nosid' => true, '_query' => ['___store' => $storeCode]]);

product backend

inject \Magento\Framework\UrlInterface $url or use url interface inherited from parent class.

$url->getUrl('catalog/product/edit', ['id' => $entityId, 'store' => $targetStoreId]);

category frontend

inject `\Magento\Framework\Url $url

$url->getUrl('catalog/category/view', ['id' => $entityId, '_nosid' => true, '_query' => ['___store' => $storeCode]]);

category backend

inject \Magento\Framework\UrlInterface $url or use url interface inherited from parent class.

$url->getUrl('catalog/category/edit', ['id' => $entityId, 'store' => $targetStoreId]);

cms page frontend

inject Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder $rul

$url->getUrl($this->_pageModel->getIdentifier(), $targetStoreId, $storeCode );

cms page backend

inject \Magento\Framework\UrlInterface $url or use url interface inherited from parent class.

$url->getUrl(PageActions::CMS_URL_PATH_EDIT, ['page_id' => $pageId]);

cms block backend

inject \Magento\Framework\UrlInterface $url or use url interface inherited from parent class.

$url->getUrl(BlockActions::URL_PATH_EDIT, ['block_id' => $blockId]);

Add new constructor dependency to your class forntUrlModel:

function __construct(
    ...
     \Magento\Framework\UrlInterface $frontUrlModel
) {
    $this->frontUrlModel = $frontUrlModel;
}

private function getProductUrl($product, $storeCode = 'default', $categoryId = null) {
        $routeParams = [ '_nosid' => true, '_query' => ['___store' => $storeCode]];

        $routeParams['id'] = $product->getId();
        $routeParams['s'] = $product->getUrlKey();
        if ($categoryId) {
            $routeParams['category'] = $categoryId;
        }
     return $this->frontUrlModel->getUrl('catalog/category/view', $routeParams);
 }

And use DI to inject right dependency

<type name="YouClass"> 
    <arguments>
        <argument name="frontUrlModel" xsi:type="object" shared="false">Magento\Framework\Url</argument>
    </arguments>
</type>