1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        京東APP鴻蒙版開發(fā)實踐,有點牛逼哦!

        共 21826字,需瀏覽 44分鐘

         ·

        2021-06-23 20:54

        京東鴻蒙版來了?


        背景


        隨著鴻蒙2.0的發(fā)布,華為部分手機用戶迎來鴻蒙時代,京東作為華為鴻蒙OS的合作APP,首次投入鴻蒙應(yīng)用商用版開發(fā),目前已上架V10.0.2版本。


        鴻蒙OS特性


        2021年6月3日,華為舉行了鴻蒙OS2.0發(fā)布會。鴻蒙OS帶來了全新桌面及用戶體驗,如桌面圖標(biāo)支持上滑呼出快捷卡片,原子化能力能通過鴻蒙設(shè)備間流轉(zhuǎn)實現(xiàn)快速分享、顯示,以及統(tǒng)一控制中心(手勢:右上角下滑)、服務(wù)中心(手勢:屏幕左下角或右下角向側(cè)上方滑動)等。


        Android工程鴻蒙化


        01
        背景



        為了利用上鴻蒙的特性,我們開發(fā)者需要盡快的將App鴻蒙化。但是將整個App鴻蒙化的工作量是特別龐大的,那么有沒有一種方式既能利用鴻蒙的特性也能快速適配呢,答案是有的,那就是混合包開發(fā)模式,整個App基本上沒有大的修改,只需要新增鴻蒙相關(guān)模塊用來實現(xiàn)鴻蒙相關(guān)特性即可。京東App-鴻蒙版能夠做到快速適配上線,并擁有鴻蒙特性,就是利用了這種開發(fā)模式。下面我們將以京東App-鴻蒙版為例,具體介紹下相關(guān)流程。


        02
        Android工程改造



        1. 我們需要依賴鴻蒙的一個兼容包(包文件可以聯(lián)系我們?nèi)〉?,將我們現(xiàn)有的Application繼承自HarmonyApplication,僅需編譯依賴,不需要真正打進App中。

          compileOnly files('libs/abilityshell_ide_java.jar')

         

        2. 在AndroidManifest.xml中,向根節(jié)點下增加。

         <uses-feature android:name="zidane.software.ability" android:required="false" />

          

        3. 向application節(jié)點下新增子節(jié)點。

          <meta-data android:name="permZA" android:value="true" />  <meta-data android:name="multiFrameworkBundle" android:value="true" />

          

        自此已經(jīng)可以構(gòu)建出鴻蒙需要的apk包了,大家也可以通過配置編譯變體等形式,構(gòu)建鴻蒙版本的apk包。

        注意:鴻蒙包中混入的apk必須要是64位的。


        03
        配置鴻蒙工程


        1.在鴻蒙工程中entry module中的build.gradle里,增加混入apk文件配置。

           legacyApkOptions{     legacyApk rootProject.file('android_entry.apk').absolutePath //混入apk的存放路徑     signConfig{         storeFile rootProject.file('xxx.keystore')   //混入apk所用簽名文件     }  }


          整體配置如下圖 :



        2. 簽名改造,我們需要根據(jù)Android apk的簽名來做鴻蒙應(yīng)用簽名的申請,需要將.keystore或.jks格式的簽名文件轉(zhuǎn)換成.p12文件,簽名秘鑰和別名保持不變。具體轉(zhuǎn)換步驟,大家可以自行搜索。

        參考:在轉(zhuǎn)換.p12文件時,我們遇到了問題,由于我們Android的簽名格式是.keystore,轉(zhuǎn)出來的.p12文件有問題無法申請鴻蒙應(yīng)用證書,經(jīng)過和華為方面溝通,我們將鴻蒙應(yīng)用的簽名秘鑰和別名保持和Android的一致,解決了打包問題。

        3. 配置文件增加屬性,在鴻蒙工程的每個feature module的config.json app節(jié)點下,增加originalName,表示混入的apk包名,同時要將bundleName的值也改成一致。

        4. 在entry模塊下,新建一個空的Ability類并配置在config.json里作為啟動入口,如:

          "abilities": [{   "skills": [{     "entities": ["entity.system.home"],     "actions": ["action.system.home"]   }],   "orientation": "portrait",   "visible": true,   "name": "com.xxx.xxx.xx.EntryAbility",   "icon": "$media:icon",   "description": "$string:mainability_description",   "label": "$string:app_name",   "type": "page",   "launchType": "standard" }],

         

        自此已經(jīng)可以構(gòu)建出包含原有Android功能的鴻蒙包了。


        Android-鴻蒙互調(diào)用


        01
        從Android啟動鴻蒙組件



        我們需要集成鴻蒙的一個jar包(可以聯(lián)系我們獲得此文件),來實現(xiàn)從Android啟動鴻蒙的組件。如:

        Intent intent = new Intent();ComponentName componentName = new ComponentName("your harmony app's bundleName name","your ability's full name");intent.setComponent(componentName);intent.putExtras(bundle);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);AbilityUtils.startAbility(context, intent);


        02
        鴻蒙模塊調(diào)用Android



        1. 鴻蒙啟動Android組件

        鴻蒙里本身是支持啟動Android組件的,只需要在Intent里增加一個flag

        Intent.FLAG_NOT_OHOS_COMPONENT


        如:

          Intent intent = new Intent();        Operation operation = new Intent.OperationBuilder()                .withDeviceId("")                .withBundleName("your android app’s packagename")                .withAbilityName("your android app’s activity fullname")                .withFlags(Intent.FLAG_NOT_OHOS_COMPONENT)                .build();        intent.setOperation(operation);        startAbility(intent);

          

        2. 鴻蒙模塊調(diào)用Android現(xiàn)有能力

        在Android包里,已經(jīng)有了很多現(xiàn)有功能,如埋點收集、用戶登錄態(tài)獲取、定位、地址等等,在鴻蒙模塊里需要用到這些功能時,我們?yōu)榱斯?jié)省時間暫時沒有再去開發(fā)一遍鴻蒙版,我們利用了Java的反射技術(shù)來搞定。經(jīng)過驗證,在Android中反射鴻蒙以及鴻蒙中反射Android都是可以的。


        03
        獲取當(dāng)前是否為鴻蒙系統(tǒng)



        在有些場景下,我們需要知道當(dāng)前系統(tǒng)的運行環(huán)境是不是鴻蒙系統(tǒng),可以使用以下代碼段來實現(xiàn)。

        private static final String HARMONY_OS = "harmony";/*** check the system is harmony os** @return true if it is harmony os*/public static boolean isHarmonyOS() {    try {        Class clz = Class.forName("com.huawei.system.BuildEx");        Method method = clz.getMethod("getOsBrand");        return HARMONY_OS.equals(method.invoke(clz));    } catch (ClassNotFoundException e) {        Log.e(TAG, "occured ClassNotFoundException");    } catch (NoSuchMethodException e) {        Log.e(TAG, "occured NoSuchMethodException");    } catch (Exception e) {        Log.e(TAG, "occur other problem");    }    return false;}


        鴻蒙OS特性+購物應(yīng)用場景開發(fā)


        鴻蒙OS打破了設(shè)備間的壁壘,對用戶及應(yīng)用開發(fā)者來說,形成了超級終端。超級終端包含手機、大屏、平板,未來或許會有更多的設(shè)備加入,設(shè)備間協(xié)同合作讓購物體驗變得優(yōu)質(zhì)。每個設(shè)備不再是孤立的個體,而是基于鴻蒙操作系統(tǒng)的智慧終端,即便用戶拿著不同的設(shè)備,也可以有很好的體驗。通過一鍵流轉(zhuǎn)實現(xiàn)跨設(shè)備間的數(shù)據(jù)傳輸,從而實現(xiàn)無縫的購物體驗。


        01
        流轉(zhuǎn):直播間FA



        介紹

        流轉(zhuǎn)泛指多設(shè)備間的分布式操作,打破設(shè)備界限,多設(shè)備聯(lián)動,使用戶應(yīng)用程序可分可合、可流轉(zhuǎn)。流轉(zhuǎn)按照體驗可分為跨端遷移和多端協(xié)同。流轉(zhuǎn)支持免安裝運行FA。京東App-鴻蒙版本中的直播FA就利用了流轉(zhuǎn)能力,將當(dāng)前手機的直播流轉(zhuǎn)至TV端,做到無縫銜接,并支持通過手機端控制TV端直播顯示的功能。效果如下:


           

        開發(fā)

        我們以京東App-鴻蒙版中直播FA的流轉(zhuǎn)開發(fā)經(jīng)驗進行介紹,如何具備流轉(zhuǎn)能力。


        1.權(quán)限要求

        由于使用到了分布式能力,我們需要先把權(quán)限配置好,在對應(yīng)的module的config.json下,增加以下權(quán)限:

        ohos.permission.GET_DISTRIBUTED_DEVICE_INFOohos.permission.DISTRIBUTED_DATASYNCohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE


        同時在Ability里,需要增加動態(tài)權(quán)限申請。

        requestPermissionsFromUser(       new String[]{SystemPermission.DISTRIBUTED_DATASYNC},         Constants.PermissionCode.PERMISSION_DISTRIBUTED_DATASYNC);


        2.關(guān)鍵接口



        3.功能實現(xiàn)

        a. 通過流轉(zhuǎn)服務(wù)注冊管理器,將當(dāng)前FA注冊,注冊時可以指定流轉(zhuǎn)的過濾條件,如設(shè)備類型、目標(biāo)設(shè)備等等:



        b. 當(dāng)需要流轉(zhuǎn)時,我們通過流轉(zhuǎn)服務(wù)注冊管理器獲取當(dāng)前滿足條件的設(shè)備列表:



        系統(tǒng)會自動查找設(shè)備,將滿足條件的設(shè)備自動展示出來供用戶選擇,當(dāng)用戶點擊某個設(shè)備后,就會回調(diào)IContinuationDeviceCallback的onDeviceConnectDone方法,獲取到目標(biāo)設(shè)備的Id后,就可以啟動目標(biāo)設(shè)備的FA。

        c. 啟動遠(yuǎn)程FA

        需要注意的是,在啟動對端設(shè)備上FA時,我們要確保對端設(shè)備的分布式能力已經(jīng)被初始化。



        02
        FA近場分享:商詳FA



        介紹

        FA近場分享能力依賴于華為分享服務(wù),可以快速實現(xiàn)FA分享的功能。較單純的使用分布式FA流轉(zhuǎn)功能,為開發(fā)者免除了設(shè)備發(fā)現(xiàn)功能,并且沒有了同賬號同網(wǎng)絡(luò)等限制條件。在京東App-鴻蒙版中,商詳FA就使用了此功能實現(xiàn)了FA的近場分享,并且能夠做到免安裝打開商詳頁面。下圖分別是A向B發(fā)送商詳FA 和 B接收商詳FA。




          

        開發(fā)

        我們將以在京東App-鴻蒙版中的相關(guān)開發(fā)經(jīng)驗介紹下如何進行FA近場分享的開發(fā)。

        工作原理圖示:



        由于功能依賴華為分享服務(wù),我們首先要引入IDL文件。


        1. 導(dǎo)入IDL文件

        在商詳FA module中java同級目錄,創(chuàng)建idl目錄,并創(chuàng)建包名com.huawei.hwshare.third,在此包名下創(chuàng)建IHwShareCallback.idl和 IHwShareService.idl文件,文件具體內(nèi)容如下:

        IHwShareCallback.idl:interface com.huawei.hwshare.third.IHwShareCallback {
            [oneway] void notifyState([in] int state);
        }IHwShareService.idl:sequenceable ohos.interwork.utils.PacMapEx;
        interface com.huawei.hwshare.third.IHwShareCallback;
        interface com.huawei.hwshare.third.IHwShareService {
            int startAuth([in] String appId, [in] IHwShareCallback callback)    int shareFaInfo([in] PacMapEx pacMapEx);
        }



        2. 對分享能力進行封裝

        以下是我們在商詳FA中封裝好的代碼,大家可以直接使用。

        package com.xxx.xxx.xxx;import com.huawei.hwshare.third.HwShareCallbackStub;import com.huawei.hwshare.third.HwShareServiceProxy;import ohos.aafwk.ability.IAbilityConnection;import ohos.aafwk.content.Intent;import ohos.app.Context;import ohos.bundle.ElementName;import ohos.eventhandler.EventHandler;import ohos.eventhandler.EventRunner;import ohos.interwork.utils.PacMapEx;import ohos.rpc.IRemoteObject;import ohos.rpc.RemoteException;import ohos.hiviewdfx.HiLog;import ohos.hiviewdfx.HiLogLabel;public class ShareFaManager {   private static final HiLogLabel LABEL_LOG = new HiLogLabel(30xD000F00"ShareFa");     private static final String LOG_FORMAT = "%{public}s: %{public}s";    // FA的圖標(biāo) byte[] len < 32768 非必須,不傳默認(rèn)取應(yīng)用圖標(biāo)    public static final String HM_FA_ICON = "ohos_fa_icon";    // FA的名字 String len < 1024 非必須,不傳默認(rèn)取應(yīng)用名    public static final String HM_FA_NAME = "ohos_fa_name";    // ability類名 String len < 1024 必須    public static final String HM_ABILITY_NAME = "ohos_ability_name";    // 包名 String len < 1024 必須    public static final String HM_BUNDLE_NAME = "ohos_bundle_name";    // FA類型 int 暫時只有0 非必須,默認(rèn)為0    public static final String SHARING_FA_TYPE = "sharing_fa_type";    // FA卡片展示圖 byte[] len < 153600 必須    public static final String SHARING_THUMB_DATA = "sharing_fa_thumb_data";    // FA卡片展示信息 String len < 1024 必須    public static final String SHARING_CONTENT_INFO = "sharing_fa_content_info";    // 攜帶的額外信息,可帶到被拉起的FA String len < 10240 非必須    public static final String SHARING_EXTRA_INFO = "sharing_fa_extra_info";    private static final String TAG = "ShareHmFaManager";    private static final String SHARE_PKG_NAME = "com.huawei.android.instantshare";    private static final String SHARE_ACTION = "com.huawei.instantshare.action.THIRD_SHARE";    private static final long UNBIND_TIME = 20*1000L;    private Context mContext;    private String mAppId;    private PacMapEx mSharePacMap;    private static ShareFaManager sSingleInstance;    private HwShareServiceProxy mShareService;    private boolean mHasPermission = false;    private EventHandler mHandler = new EventHandler(EventRunner.getMainEventRunner());    //服務(wù)綁定回調(diào)    private final IAbilityConnection mConnection = new IAbilityConnection() {        @Override        public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {            HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "onAbilityConnectDone success.");            mHandler.postTask(()->{                mShareService = new HwShareServiceProxy(iRemoteObject);                try {                    //華為分享認(rèn)證授權(quán)                    mShareService.startAuth(mAppId, mFaCallback);                } catch (RemoteException e) {                    HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "startAuth error.");                }            });        }        @Override       public void onAbilityDisconnectDone(ElementName elementName, int i) {           HiLog.info(LABEL_LOG, LOG_FORMAT, TAG, "onAbilityDisconnectDone.");           mHandler.postTask(()->{               mShareService = null;               mHasPermission = false;            });        }    };    private Runnable mTask = () -> {        if (mContext != null && mShareService != null) {            mContext.disconnectAbility(mConnection);            mHasPermission = false;            mShareService = null;        }    };    //華為分享認(rèn)證授權(quán)回調(diào)    private final HwShareCallbackStub mFaCallback = new HwShareCallbackStub("HwShareCallbackStub") {        @Override        public void notifyState(int state) throws RemoteException {            mHandler.postTask(()->{                HiLog.info(LABEL_LOG, LOG_FORMAT, TAG, "notifyState: " + state);                if (state == 0) {                    mHasPermission = true;                    if (mSharePacMap != null) {                       shareFaInfo();                    }                }            });        }    };    /**     \* 單例模式獲取ShareFaManager的實例對象     *     \* @param context 程序Context     \* @return ShareFaManager實例對象     */    public static synchronized ShareFaManager getInstance(Context context) {        if (sSingleInstance == null && context != null) {            sSingleInstance = new ShareFaManager(context.getApplicationContext());        }        return sSingleInstance;    }    private ShareFaManager(Context context) {        mContext = context;    }    private void shareFaInfo() {        if (mShareService == null) {            return;        }        if (mHasPermission) {            HiLog.info(LABEL_LOG, LOG_FORMAT, TAG, "start shareFaInfo.");            try {                mShareService.shareFaInfo(mSharePacMap);                mSharePacMap = null;            } catch (RemoteException e) {                HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "shareFaInfo error.");            }        }        // 不使用時斷開        mHandler.postTask(mTask, UNBIND_TIME);    }    /**     \* 開始分享     *     \* @param appId 開發(fā)者聯(lián)盟網(wǎng)站創(chuàng)建鴻蒙服務(wù)/鴻蒙應(yīng)用時生成的appid     \* @param pacMap 服務(wù)信息載體     */    public void shareFaInfo(String appId, PacMapEx pacMap) {        if (mContext == null) {            return;        }        mAppId = appId;        mSharePacMap = pacMap;        mHandler.removeTask(mTask);        shareFaInfo();        bindShareService();    }    /**     \* 綁定華為分享服務(wù)     */    private void bindShareService() {            if (mShareService != null) {            return;        }        HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "start bindShareService.");        Intent intent = new Intent();        intent.setBundle(SHARE_PKG_NAME);        intent.setAction(SHARE_ACTION);        intent.setFlags(Intent.FLAG_NOT_OHOS_COMPONENT);        mContext.connectAbility(intent, mConnection);    }    }


        3.開始分享

        我們將參數(shù)進行組裝,調(diào)用ShareFaManager的shareFaInfo方法即可自動的完成FA分享功能。如我們將商詳FA進行分享:



        注意:

        1. 使用時要主要傳遞的數(shù)據(jù)不要超過限定的大小,否則會分享失敗并導(dǎo)致程序崩潰。

        2. 在對端接收到分享后,我們需要將自定義的參數(shù)取出來,從Intent中取sharing_fa_extra_info即可。

        Ps:針對遠(yuǎn)距離的場景,華為也給出了解決方案,通過暢連即可分享購物鏈接。值得注意的是,此時好友還可以通過屏幕共享在商品頁面進行涂鴉互動。


        03
        服務(wù)卡片:搜索卡片



        用戶上滑 App 圖標(biāo)即可生成萬能卡片 ,在桌面呈現(xiàn)更豐富的信息,卡片信息支持實時更新,減少了 App 加載的時間,如目前京東app,用戶上滑 App 圖標(biāo)可打開快捷搜索入口。


        介紹

        FA卡片是FeatureAbility的Page模板的一種界面展示形式。FA卡片常用于嵌入到其他應(yīng)用中作為其界面的一部分顯示,并支持基礎(chǔ)的交互功能。卡片使用方作為卡片展示的宿主負(fù)責(zé)顯示卡片,卡片使用方的典型應(yīng)用就是桌面應(yīng)用??ㄆ褂梅絻H限系統(tǒng)應(yīng)用。

        當(dāng)FA規(guī)格小于10M時,可以支持免安裝運行。系統(tǒng)最大支持500個卡片,相同名稱的卡片實例最大是32個。

        通過服務(wù)卡片的一些特點,如定時更新、免安裝運行等,可以很好的進行快捷入口的引導(dǎo)。如我們可以在卡片上展示活動商品,并定期更新,用戶可以免安裝的打開活動詳情,當(dāng)用戶產(chǎn)生進一步購買欲望時,用戶可下載整個App進行下單。





        開發(fā)

        卡片的開發(fā)支持JS和Java兩種方式。在京東App-鴻蒙版中的搜索FA里,我們加入了FA卡片,可以直達搜索。下面我們將以此為例進行開發(fā)步驟的講解。

        1.卡片配置

        首先要在搜索FA的config.json中配置forms節(jié)點,比如:



        我們給SearchAbility節(jié)點下添加forms節(jié)點,就表示這個卡片的創(chuàng)建及管理由SearchAbility來負(fù)責(zé)。

        注意:必須要設(shè)置label屬性,必須是資源形式的且不能是包名。

        屬性解釋:



        2. 實現(xiàn)卡片相關(guān)回調(diào)

        在SearchAbility中,復(fù)寫以下幾個方法:



        創(chuàng)建:在創(chuàng)建卡片時,我們可以從Intent中獲取當(dāng)前要創(chuàng)建卡片的Id,如:



        這是一個很簡單的卡片,我們沒有對卡片中的視圖設(shè)置任何數(shù)據(jù)和事件,那么點擊卡片后,打開的就是負(fù)責(zé)管理卡片的Ability。如果需要設(shè)置數(shù)據(jù)和事件,可以使用以下方式

        1. 創(chuàng)建ComponentProvider;

        2. 通過ComponentProvider設(shè)置對應(yīng)View的數(shù)據(jù),以及點擊事件,目前能夠支持的事件有START_ABILITY和START_SERVICE兩類;

        3. 將ComponentProvider對象合并入ProviderFormInfo中。



        更新:當(dāng)觸發(fā)了更新卡片方法時,我們可以進行數(shù)據(jù)更新,并將最新的數(shù)據(jù)更新到卡片View上。



        刪除:當(dāng)卡片使用方將卡片刪除,我們可能需要將對應(yīng)卡片在App內(nèi)的相關(guān)持久化數(shù)據(jù)進行刪除。



        3.配置EntryCard目錄

        配置EntryCard目錄,以便讓系統(tǒng)能夠識別出服務(wù)卡片,并展示在服務(wù)中心的推薦里。新建應(yīng)用時可以勾選自動生成,如果是之前IDE創(chuàng)建的工程,則需要手動補充上。

        1)在工程根目錄下創(chuàng)建EntryCard目錄;

        2) EntryCard目錄下,創(chuàng)建一個文件夾,取名為擁有卡片的FA工程名,如我們的搜索FA擁有服務(wù)卡片,搜索FA的工程名叫searchfeature,那我們就創(chuàng)建一個文件夾,名字就叫做searchfeature; 

        3)在searchfeature目錄下創(chuàng)建base/snapshot兩級目錄,在其中放置我們的卡片圖片,其命名方式為formname-dimensions,如搜索卡片的卡片名稱配置的是search_card,尺寸是2*2的,那么這個圖片就命名為search_card-2x2.png。


        鴻蒙App打包及上架


        01
        打包構(gòu)建



        通過以上配置,我們已經(jīng)可以進行鴻蒙App的構(gòu)建了。目前鴻蒙App分為兩種構(gòu)建形式,debug和release,可以通過DevEco工具自帶的編譯任務(wù)或者使用gradle的assembleDebug signReleaseApp任務(wù)進行構(gòu)建。



          其中debug模式構(gòu)建方式出來的產(chǎn)物是多個目標(biāo)設(shè)備的多個.hap文件,每個FA都會構(gòu)建出各自的.hap文件;release會構(gòu)建出一個.app文件,我們需要將此文件進行上架發(fā)布。 



        安裝及運行

        1. 開發(fā)者無法安裝.app安裝包,此文件只能用于上架應(yīng)用市場。

        2. 通過adb shell bm get -udid獲取設(shè)備UDID后,錄入到開發(fā)者中心,并生成證書文件,我們就可以安裝.hap包。

        3. 安裝時可以將文件push到手機某個目錄下(如sdcard/hmphone),然后使用adb shell bm install -p /sdcard/hmphone/進行安裝,每次安裝可以先刪除之前文件。

        注意:由于我們無法安裝驗證.app包,我們要保證在debug和release兩種構(gòu)建模式下,我們的代碼不會發(fā)生改變。


        02
        應(yīng)用上架及發(fā)布


        1.如果還沒有在開發(fā)者中心創(chuàng)建鴻蒙應(yīng)用的話,需要先新增一個鴻蒙應(yīng)用,包名和之前Android的包名保持一致,并關(guān)聯(lián)到同一個項目中。 



        2. 選擇我們創(chuàng)建的鴻蒙應(yīng)用,在【應(yīng)用信息】頁面中,將應(yīng)用安裝與升級修改為如下圖所示。


         

        3. 在【版本信息】頁面中,點擊【版本/升級】創(chuàng)建新版本,在新版本頁面中的【軟件版本】模塊下,上傳我們構(gòu)建的.app軟件包后并勾選,在當(dāng)前頁面填入相關(guān)信息后即可提交審核,待審核通過后,在應(yīng)用市場上就會出現(xiàn)了。 



        后續(xù)規(guī)劃


        鴻蒙OS為消費者建立便捷的購物超級終端模式提供了可能,隨著鴻蒙生態(tài)的豐富,人們的購物形式也會隨之出現(xiàn)新的改變。京東將從用戶角度出發(fā),結(jié)合鴻蒙OS,讓更多的用戶在更多的設(shè)備和場景享受京東的優(yōu)質(zhì)服務(wù),敬請期待……


        —  —

        點這里??關(guān)注我,記得標(biāo)星呀~

        長按進入小程序,進行打卡簽到


        (更多精彩值得期待……)

        鴻蒙最近熱文:
        華為鴻蒙系統(tǒng)是安卓套殼?直接看代碼
        HarmonyOS完全升級攻略:消費者公測&內(nèi)測&線下升級
        給力!華為鴻蒙操作系統(tǒng)入門到精通
        鴻蒙HarmonyOS,真的來了!
        萌新第一次用鴻蒙跑hello world
        華為鴻蒙系統(tǒng)深度研究 (PPT演示)
        HarmonyOS到底是不是Android套皮?

        2T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,人工智能,考研,軟考,英語,等等。在公眾號內(nèi)回復(fù)「資源」,即可免費獲??!回復(fù)「社群」,可以邀請你加入讀者群!


        ??給個「在看」,是對我最大的支持??

        瀏覽 69
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            黄片免费网站 | 国产精品成人a区在线观看 | 国产21在线 | 国户精品久久久久久久久久久久 | 欧美日韩一二三四区 | 久久久噜噜久久久精品久久5. | 中文字幕亚洲有码 | free性欧美派对对狂欢hd | 绿帽社视频一区自拍 | 黑人操日本 |