JD APP Hongmeng version development practice is a little awesome!
Today
The following article comes from Jingdong retail technology, by Hou Weihao and di Cailin
Here comes Jingdong Hongmeng version ~
background
With the release of Hongmeng 2.0, some mobile phone users of Huawei have ushered in the Hongmeng era. As a cooperative APP of Huawei Hongmeng OS, jd.com has invested in the development of commercial version of Hongmeng application for the first time, and has been put on the shelf v10.0 Version 0.2.
Hongmeng OS features
On June 3, 2021, Huawei held Hongmeng OS2 0 press conference. Hongmeng OS has brought a new desktop and user experience. For example, the desktop icon supports sliding up and calling out quick cards, and the atomization ability can realize rapid sharing and display through the circulation between Hongmeng devices, as well as the unified control center (gesture: sliding in the upper right corner), service center (gesture: sliding in the lower left corner or the lower right corner of the screen to the upper side), etc.
Android engineering hongmenghua
01
background
In order to take advantage of the features of shanghongmeng, our developers need to turn the App into Hongmeng as soon as possible. However, the workload of turning the whole App into Hongmeng is particularly huge. Is there a way to make use of Hongmeng's features and adapt quickly? The answer is yes, that is, the mixed package development mode. There are basically no major modifications to the whole App, so you only need to add Hongmeng related modules to realize Hongmeng related features. JD App Hongmeng version can adapt online quickly and has the characteristics of Hongmeng, which makes use of this development mode. Next, we will take JD App Hongmeng version as an example to introduce the relevant processes.
02
Android engineering transformation
-
We need to rely on a compatible package of Hongmeng (the package file can be obtained by contacting us) and inherit our existing Application from HarmonyApplication. We only need to compile the dependency without really entering the App.
compileOnly files('libs/abilityshell_ide_java.jar')
2. On Android manifest XML, add to the root node.
<uses-feature android:name="zidane.software.ability" android:required="false" />
3. Add a child node under the application node.
<meta-data android:name="permZA" android:value="true" /> <meta-data android:name="multiFrameworkBundle" android:value="true" />
Since then, we can build the apk package needed by Hongmeng. You can also build the apk package of Hongmeng version by configuring compilation variants and other forms.
Note: apk mixed in Hongmeng package must be 64 bit.
03
Configure Hongmeng project
1. Build in entry module in Hongmeng project Add apk file configuration to gradle.
legacyApkOptions{ legacyApk rootProject.file('android_entry.apk').absolutePath //Storage path of mixing apk signconfig {storefile rootproject. File ('xxx. Keystore ') / / signature file used for mixing APK}}
The overall configuration is shown in the figure below:
2. For signature transformation, we need to apply for Hongmeng application signature according to the Android apk signature keystore or The signature file in jks format is converted into p12 file, signature key and alias remain unchanged. Specific conversion steps, you can search by yourself.
Reference: in conversion p12 file, we encountered a problem, because our Android signature format is keystore, turn it out p12 file has a problem and cannot apply for Hongmeng application certificate. After communicating with Huawei, we kept the signature secret key and alias of Hongmeng application consistent with Android, and solved the packaging problem.
3. Add attributes to the configuration file, in the config. Of each feature module of Hongmeng project Under the JSON app node, add originalName to indicate the mixed apk package name. At the same time, change the value of bundleName to be consistent.
4. Under the entry module, create an empty Ability class and configure it in config JSON as the startup entry, such as:
"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" }],
Since then, Hongmeng package containing the original Android functions can be built.
Android Hongmeng intermodulation
01
Launch Hongmeng component from Android
We need to integrate a jar package of Hongmeng (you can contact us to obtain this file) to launch Hongmeng's components from Android. For example:
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
Hongmeng module calls Android
1. Hongmeng starts Android components
Hongmengli itself supports the startup of Android components. It only needs to add a flag in Intent
Intent.FLAG_NOT_OHOS_COMPONENT
For example:
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. Hongmeng module calls Android's existing capabilities
In the Android package, there are many existing functions, such as buried point collection, user login status acquisition, location, address, etc. when these functions need to be used in the Hongmeng module, in order to save time, we didn't develop the Hongmeng version again for the time being. We used the reflection technology of Java to do it. After verification, it is possible to reflect Hongmeng in Android and Android in Hongmeng.
03
Get whether it is currently Hongmeng system
In some scenarios, we need to know whether the running environment of the current system is Hongmeng system, which can be realized by using the following code snippet.
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;}
Hongmeng OS features + shopping application scenario development
Hongmeng OS has broken the barriers between devices and formed a super terminal for users and application developers. Super terminals include mobile phones, large screens and tablets. In the future, more devices may join. The collaborative cooperation between devices will make the shopping experience high-quality. Each device is no longer an isolated individual, but an intelligent terminal based on Hongmeng operating system. Even if users hold different devices, they can have a good experience. Data transmission between devices is realized through one key flow, so as to realize seamless shopping experience.
01
Circulation: live broadcast room FA
introduce
Circulation generally refers to the distributed operation between multiple devices, breaking the boundaries of devices and multi device linkage, so that user applications can be separated, combined and circulated. Flow can be divided into cross end migration and multi end collaboration according to experience. Circulation supports installation free operation of FA. The live broadcast FA in JD App Hongmeng version makes use of the circulation ability to transfer the live broadcast of the current mobile phone to the TV terminal, achieve seamless connection, and support the function of controlling the live broadcast display of the TV terminal through the mobile terminal. The effect is as follows:
development
We will introduce how to have the circulation ability based on the circulation development experience of live broadcast FA in JD App Hongmeng version.
1. Authority requirements
Due to the use of distributed capabilities, we need to configure the permissions in the config. Of the corresponding module JSON, add the following permissions:
ohos.permission.GET_DISTRIBUTED_DEVICE_INFOohos.permission.DISTRIBUTED_DATASYNCohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE
At the same time, dynamic permission application needs to be added in Ability.
requestPermissionsFromUser( new String[]{SystemPermission.DISTRIBUTED_DATASYNC}, Constants.PermissionCode.PERMISSION_DISTRIBUTED_DATASYNC);
2. Key interfaces
3. Function realization
a. Register the current FA through the circulation service registration manager. When registering, you can specify the circulation filter conditions, such as equipment type, target equipment, etc
b. When circulation is needed, we can obtain the list of devices that currently meet the conditions through the circulation service registration manager:
The system will automatically find the device and automatically display the devices that meet the conditions for users to choose. When users click a device, they will call back the ondeviconnectdone method of icontinuity devicecallback. After obtaining the Id of the target device, they can start the FA of the target device.
c. Start remote FA
It should be noted that when starting FA on the peer device, we should ensure that the distributed capability of the peer device has been initialized.
02
FA near field sharing: see FA for details
introduce
FA's near-field sharing capability depends on Huawei's sharing service, which can quickly realize the function of FA sharing. The simple use of distributed FA circulation function eliminates the device discovery function for developers, and there are no restrictions such as the same account and the same network. In JD App Hongmeng version, the business details FA uses this function to realize the near-field sharing of FA, and can open the business details page without installation. The following figure shows the detailed FA of the sender A to B and the detailed FA of the receiver B.
development
We will introduce how to develop FA near-field sharing based on the relevant development experience in JD App Hongmeng version.
Working principle diagram:
Since the function depends on Huawei's shared services, we must first introduce IDL files.
1. Import IDL file
In the business details FA module, create the java peer directory, create the idl directory, and create the package name com huawei. hwshare. Third, create ihwsharecallback under this package name idl and ihwshareservice idl file. The specific contents of the file are as follows:
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. Encapsulate sharing capabilities
The following is the code we encapsulated in the commercial detail FA, which you can use directly.
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(3, 0xD000F00, "ShareFa"); private static final String LOG_FORMAT = "%{public}s: %{public}s"; //FA icon , byte [] len < 32768 , not required, not transmitted. The default is the application icon , public , static , final , string , HM_FA_ICON = "ohos_fa_icon"; / / the name of FA is string len < 1024, which is not required and is not passed. By default, the application name is public static final string HM_FA_NAME = "ohos_fa_name"; / / ability class name: String len < 1024 must be public static final string HM_ABILITY_NAME = "ohos_ability_name"; / / Package Name: String len < 1024 public static final string HM_BUNDLE_NAME = "ohos_bundle_name"; / / FA type # int # temporarily only 0 # not required, the default is 0 # public # static # final # string sharing_ FA_ TYPE = "sharing_fa_type"; / / FA card display diagram {byte [] len < 153600} public} static} final} string SHARING_THUMB_DATA = "sharing_fa_thumb_data"; / / FA card display information: String len < 1024; must be public static final string SHARING_CONTENT_INFO = "sharing_fa_content_info"; / / additional information carried can be brought to the pulled FA string len < 10240 non mandatory 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()); / / service binding callback {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 {/ / Huawei shares authentication authorization} 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; } }; / / Huawei shared authentication authorization callback {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(); } } }); } }; / * * \ * obtain the instance object of sharefamanager in singleton mode * \ * @ param # context # program context \ * @ return # sharefamanager instance object * / public # static # synchronized # sharefamanager # getInstance(Context # context) {if (singleinstance = = 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."); }} / / disconnect mhandler when not in use postTask(mTask, UNBIND_TIME); } / * * \ * start sharing * \ * @ param # appid the appid \ * @ param # pacmap # service information carrier * / public # void # shareFaInfo(String # appid, pacmapex # pacMap) {if (mcontext = = null) { return; } mAppId = appId; mSharePacMap = pacMap; mHandler.removeTask(mTask); shareFaInfo(); bindShareService(); } / * * \ * bind Huawei shared service * / private void bindshareservice() {if (msharservice! = 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. Start sharing
We assemble the parameters and call the sharefanfo method of ShareFaManager to automatically complete the FA sharing function. If we will share with you:
be careful:
1. When using, the data to be transferred should not exceed the limited size, otherwise the sharing will fail and cause the program to crash.
2. After the peer receives the sharing, we need to take out the customized parameters and get sharing from Intent_ fa_ extra_ Info.
Ps: for long-distance scenarios, Huawei has also provided a solution to share shopping links through Changlian. It is worth noting that at this time, friends can also interact with graffiti on the product page through screen sharing.
03
Service card: search card
The user can generate a universal card by sliding the app icon, presenting richer information on the desktop. The card information supports real-time update, reducing the time of app loading. For example, at present, the user can open a quick search entry by sliding the app icon on JD app.
introduce
FA card is an interface display form of the Page template of featurability. FA cards are often embedded in other applications, displayed as part of their interfaces, and support basic interactive functions. As the host of card display, the card user is responsible for displaying cards. The typical application of the card user is desktop application. Card users are only available for system applications.
When the FA specification is less than 10M, it can support installation free operation. The system supports up to 500 cards, and the maximum number of card instances with the same name is 32.
Through some features of the service card, such as regular update, installation free operation, etc., you can guide the quick entrance very well. For example, we can display the activity goods on the card and update them regularly. Users can open the activity details without installation. When users have a desire to buy further, users can download the whole App to place an order.
development
Card development supports JS and Java. In the search FA in JD App Hongmeng edition, we have added FA card, which can directly search. Next, we will take this as an example to explain the development steps.
1. Card configuration
First, search the config. Of FA Configure the forms node in JSON, for example:
We add the forms node under the SearchAbility node, which means that SearchAbility is responsible for the creation and management of this card.
Note: the label attribute must be set. It must be in the form of resources and cannot be a package name.
Attribute interpretation:
2. Implement card related callback
In SearchAbility, copy the following methods:
Create: when creating a card, we can obtain the Id of the current card to be created from Intent, such as:
This is a very simple card. We do not set any data and events for the view in the card. After clicking the card, the Ability responsible for managing the card will be opened. If you need to set data and events, you can use the following methods
1. Create ComponentProvider;
2. Set the data of the corresponding View and click events through ComponentProvider. At present, the supported events are START_ABILITY and start_ Two types of service;
3. Merge the ComponentProvider object into ProviderFormInfo.
Update: when the update card method is triggered, we can update the data and update the latest data to the card View.
Delete: when the card user deletes the card, we may need to delete the relevant persistent data of the corresponding card in the App.
3. Configure EntryCard directory
Configure the EntryCard directory so that the system can recognize the service card and display it in the recommendation of the service center. When creating an application, you can check auto generate. If it is a project created by IDE before, you need to add it manually.
1) Create the EntryCard directory under the project root directory;
2) Under the EntryCard directory, create a folder named FA project with card. For example, if our search FA has service card and the project searching FA is called searchfeature, we will create a folder named searchfeature;
3) Create a base/snapshot two-level directory under the searchfeature directory and place our card pictures in it. The naming method is formname dimensions. For example, search is configured for the card name of the search card_ If the size of the card is 2 * 2, the picture will be named search_card-2x2.png.
Hongmeng App packaging and shelves
01
Package build
Through the above configuration, we can build Hongmeng App. At present, Hongmeng App is divided into two construction forms, debug and release, which can be built through the compilation task of DevEco tool or by using gradle's assemblydebug signreleaseapp task.
The product of debug mode construction is multiple of multiple target devices hap file, each FA will build its own hap file; release will build one app file, we need to publish this file on the shelf.
Installation and operation
1. The developer cannot install app installation package. This file can only be used in the application market.
2. After obtaining the device UDID through adb shell bm get -udid, enter it into the developer center and generate the certificate file, we can install it hap package.
3. During installation, you can push the file to a directory of the mobile phone (e.g. sdcard/hmphone), and then use adb shell bm install -p /sdcard/hmphone / to install. You can delete the previous file before each installation.
Note: because we can't install verification app package, we need to ensure that our code will not change under the two construction modes of debug and release.
02
Application launch and release
1. If you haven't created a Hongmeng application in the developer center, you need to add a Hongmeng application first. The package name is consistent with the previous Android package name and associated with the same project.
2. Select the Hongmeng application we created, and on the [application information] page, modify the application installation and upgrade as shown in the figure below.
3. On the [version information] page, click [version / upgrade] to create a new version, and upload the software we built under the [software version] module on the new version page After the app package is and checked, fill in the relevant information on the current page and submit it for approval. After it is approved, it will appear in the application market.
Follow up planning
Hongmeng OS makes it possible for consumers to establish a convenient shopping super terminal mode. With the enrichment of Hongmeng ecology, people's shopping forms will also change. From the perspective of users, jd.com will combine Hongmeng OS to enable more users to enjoy jd.com's high-quality services in more devices and scenes. Please look forward to
- end -
(more highlights are worth looking forward to...)