# 核心代码逻辑介绍
- [核心代码说明](#section17354153553419)
## 核心代码说明
核心逻辑都在DataHandlerAbility.java中, 代码流程如下:
1. JS页面拉起后,会向Java侧请求模板配置数据。
JS代码:
```
async requestTemplate() {
// This function requests the JSON configuration used for display from Java.
let action = utils.makeAction(ACTION_MESSAGE_CODE_GET_TEMPLATE, {});
let result = await FeatureAbility.callAbility(action);
let resultJson = JSON.parse(result);
if (resultJson.code == 0) {
let template = JSON.parse(resultJson.data);
this.parseJson(template.template);
}
}
```
JAVA代码:
```
private boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply) {
switch (code) {
case ACTION_MESSAGE_CODE_GET_TEMPLATE: {
reply.writeString(getWriteTemplateString());
break;
}
default: {
reply.writeString("service not defined");
return false;
}
}
return true;
}
```
2. Java侧读取模板配置文件:配置文件的路径在DataHandlerAbility的getTemplate中指定,文件来源可以是本地资源,也可以从网络路径读取。
```
private ZSONObject getTemplate() {
// source indicates whether the JSON configuration file is from a local file or an online file.
final String source = "local";
// configDir indicates the directory.
final String configDir = SampleDeviceDataHandler.EXAMPLE_TEMPLATE_FILE_DIR + "/" + productName;
// configPath indicates the URL of the JSON configuration file. You can change it corresponding
// to your product name or device ID.
final String configPath = configDir + "/" + productName + "_" + language + ".json";
ZSONObject result = null;
if (LOCAL.equals(source)) {
try {
Resource resource = abilityContext.getResourceManager().getRawFileEntry(configPath).openRawFile();
byte[] tmp = new byte[1024 * 1024];
int reads = resource.read(tmp);
if (reads != -1) {
String jsonString = new String(tmp, 0, reads, StandardCharsets.UTF_8);
result = ZSONObject.stringToZSON(jsonString);
}
} catch (IOException e) {
HiLog.error(LABEL_LOG, "Failed to open the template from the local file.");
}
} else {
try {
URL url = new URL(configPath);
URLConnection urlc = url.openConnection();
urlc.connect();
try (InputStream is = urlc.getInputStream();
InputStreamReader isReader = new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(isReader)) {
StringBuilder sb = new StringBuilder();
String str;
while ((str = reader.readLine()) != null) {
sb.append(str);
}
result = ZSONObject.stringToZSON(sb.toString());
}
} catch (IOException e) {
HiLog.error(LABEL_LOG, "Failed to open the template from the URL.");
}
}
if (result != null) {
// iconUrl is icon's prefix path. Here we use /common/productName in js module. You can change it into your
// cloud url. All icons file must be under iconUrl.
result.put("iconUrl", SampleDeviceDataHandler.EXAMPLE_RESOURCE_DIR + "/" + productName);
// deviceIcon is the product icon's file name. It must be under iconUrl.
result.put("deviceIcon", "/" + productName + ".png");
// logoIcon is the product logo's file name. It must exist under iconUrl.
result.put("logoIcon", "/logo.png");
}
return result;
}
```
3. JS读取到页面配置后,会向Java侧请求设备数据。
JS代码:
```
async getData() {
let action = utils.makeAction(ACTION_MESSAGE_CODE_GET_DATA, {});
await FeatureAbility.callAbility(action);
}
```
JAVA代码:
```
private boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply) {
switch (code) {
case ACTION_MESSAGE_CODE_GET_DATA: {
deviceDataHandler.getData();
break;
}
default: {
reply.writeString("service not defined");
return false;
}
}
return true;
}
```
4. Java侧进行初始化设备数据,调用BaseDeviceDataHandler\#initProfileData返回设备所有profile数据。
```
NetworkDeviceDataHandler(String deviceId, DeviceDataCallback deviceDataCallback) {
super(deviceId, deviceDataCallback);
dataModel = fanDataModel;
mainHandler = new EventHandler(EventRunner.getMainEventRunner());
mainHandler.postTask(() -> initProfileData(0, "", dataModel.recoverData()));
}
```
例如:模板样例智能电风扇的数据初始化如下。
```
private final DeviceDataModel fanDataModel = new DeviceDataModel() {
@Override
public Map recoverData() {
dataMap.put("switch/on", 0);
dataMap.put("windMode/mode", 0);
dataMap.put("windGear/gear", 0);
dataMap.put("shutdown/mode", 0);
return dataMap;
}
}
```
5. JS界面加载完毕后,事件响应如下:页面点击事件触发后会调用到BaseDeviceDataHandler\#modifyDeviceProperty,发送到设备端,此时UI不会有任何变化。等设备产生响应后,再触发BaseDeviceDataHandler\#onDeviceDataChange回调变化后的数据到UI层,界面会自动刷新。
例如:模板样例智能电风扇发送消息给设备端的逻辑如下。
```
private void sendMessage(String message, HashMap tmpMap) {
CommonInfo commonInfo = new CommonInfo();
commonInfo.setSessionId(sessionId);
HiLog.error(LABEL_LOG, "sessionId " + sessionId);
NetConfigApi.getInstance().sendMessage(commonInfo, message, (code, controlMessage, str) -> {
if (code == 0) {
HiLog.info(LABEL_LOG, "Message sent successfully " + message);
dataMap.putAll(tmpMap);
mainHandler.postTask(() -> onDeviceDataChange(dataMap));
} else {
HiLog.error(LABEL_LOG, "Failed to send message, code = " +
code + " control message = " + controlMessage);
}
});
}
```
> **说明:**
>当前模板只提供了从手机发送消息到设备侧的功能,暂不支持从设备侧发送消息到手机,相关能力后续将逐步更新。