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]);