设备上传信息代码
LinkKit.getInstance().getDeviceThing().thingPropertyPost
(Map<String, ValueWrapper> var1, IPublishResourceListener var2)
传入第一个对象是一个Map,里面存储的是上报属性的标识符和值,第二个参数是一个监听器,用来监听上报属性成功与否。
理解:首先获取一个连接工具、然后获取要上报属性的设备,再调用上报属性的方法。
有个问题:就是LinkKit虽然在前面有过初始化,传入了三元组信息,但是也是类似这样的
LinkKit.getInstance.init()
不会是同一个对象吧。
解决:使用getInstance()进行实例化,属于单例模式,一般用于比较大,复杂的对象,只初始化一次,应该还有一个private的构造函数,使得不能用new来实例化对象,只能调用getInstance方法来得到对象,而getInstance保证了每次调用都返回相同的对象。
DeviceManager也用到了单例模式,在LinkKit初始化的时候,LinkKit的init方法下,对DeviceManager也进行了初始化。
Thing接口的实现类是ThingImpl。
属性上报方法详细如下:
目前设备属性上报涉及的类和接口有:
接口:ILinkKit、IThing、IDevice、
类:LinkKit(实现ILinkKit)、DeviceManger、ThingImpl(实现IThing),DeviceImpl(实现IDevice),ClientWrapper(继承CommonDevWrapper),ServerWrapper(继承CommonDevWrapper),CommonDevWrapper(实现IDevice),TDeviceShadow、SetPropertyTask(继承DeviceAsyncTask,实现IRequestHandler ),
ThingImpl对mIDevice的初始化在getIDevice()里面,详细代码如下:
private void getIDevice(String tsl, DeviceInfo deviceInfo, Map<String, ValueWrapper> propertyValues, final IDMCallback<InitResult> listener) {
ALog.d("ThingImpl", "getIDevice() called with: tsl = [" + tsl + "], deviceInfo = [" + deviceInfo + "], propertyValues = [" + propertyValues + "], listener = [" + listener + "], isSubDev = [" + this.isSubDev + "]");
this.deviceTSL = tsl;
DefaultServerConfig config = new DefaultServerConfig();
config.mIotProductKey = deviceInfo.productKey;
config.mIotDeviceName = deviceInfo.deviceName;
config.mIotSecret = deviceInfo.deviceSecret;
config.setConnectType(ConnectType.MQTT);
DeviceBasicData basicData = new DeviceBasicData();
basicData.setProductKey(deviceInfo.productKey);
basicData.setDeviceName(deviceInfo.deviceName);
basicData.setDeviceModelJson(tsl);
basicData.setLocal(true);
basicData.setPort(5683);
config.setBasicData(basicData);
config.setPropertValues(propertyValues);
this.mIDevice = DeviceManager.getInstance().createDevice(config);
this.mIDevice.init((Object)null, new IDevListener() {
public void onSuccess(Object o, OutputParams o1) {
ALog.d("ThingImpl", "onSuccess() called with: o = [" + o + "], o1 = [" + o1 + "]");
ThingImpl.this.isTTInited = true;
InitResult initResult = new InitResult();
initResult.tsl = ThingImpl.this.deviceTSL;
listener.onSuccess(initResult);
ThingImpl.this.isIniting = false;
}
public void onFail(Object o, ErrorInfo errorInfo) {
ALog.d("ThingImpl", "onFail() called with: o = [" + o + "], errorInfo = [" + errorInfo + "]");
ThingImpl.this.isTTInited = false;
AError error = new AError();
if (errorInfo != null) {
error.setCode(errorInfo.getErrorCode());
error.setMsg(errorInfo.getErrorMsg());
}
listener.onFailure(error);
ThingImpl.this.isIniting = false;
}
});
}
调用步骤:
1、DeviceManager中的init()方法调用DeviceManager 中的initThing方法。
DeviceManager.this.initThing(params.tsl, params.deviceInfo, params.propertyValues, listener);
2、DeviceManager 中的initThing方法调用 ThingImpl中的initThing()方法
((ThingImpl)thing).initThing(tsl, info, propertiesMap, new IDMCallback<InitResult>() {
public void onSuccess(InitResult result) {
ALog.d("DeviceManager", "init onSuccess result=" + result);
if (DeviceManager.this.isDMInited.compareAndSet(false, true)) {
DeviceManager.this.isDMIniting.set(false);
if (callback != null) {
callback.onSuccess(result);
}
}
}
public void onFailure(AError error) {
ALog.d("DeviceManager", "init onFailure() called with: error = [" + error + "]");
if (DeviceManager.this.isDMInited.compareAndSet(false, false)) {
DeviceManager.this.isDMIniting.set(false);
if (callback != null) {
callback.onFailure(error);
}
}
}
});
3、ThingImpl中的initThing方法调用getDevice(),
this.getIDevice(tsl, deviceInfo, propertyValues, listener);
4、getIDevice中对mIDevice初始化和赋值
this.mIDevice = DeviceManager.getInstance().createDevice(config);
this.mIDevice.init((Object)null, new IDevListener() {
public void onSuccess(Object o, OutputParams o1) {
ALog.d("ThingImpl", "onSuccess() called with: o = [" + o + "], o1 = [" + o1 + "]");
ThingImpl.this.isTTInited = true;
InitResult initResult = new InitResult();
initResult.tsl = ThingImpl.this.deviceTSL;
listener.onSuccess(initResult);
ThingImpl.this.isIniting = false;
}
public void onFail(Object o, ErrorInfo errorInfo) {
ALog.d("ThingImpl", "onFail() called with: o = [" + o + "], errorInfo = [" + errorInfo + "]");
ThingImpl.this.isTTInited = false;
AError error = new AError();
if (errorInfo != null) {
error.setCode(errorInfo.getErrorCode());
error.setMsg(errorInfo.getErrorMsg());
}
listener.onFailure(error);
ThingImpl.this.isIniting = false;
}
});
5、怎么赋值的呢,通过DeviceManager中的createDevice()方法。好像是将设备分为服务端和客户端,客户端通过deviceWrapper = new ClientWrapper(config);
赋值,服务端通过deviceWrapper = new ServerWrapper(config);
赋值,另外,ClientWrapper类继承于CommonDevWrapper,而CommonDevWrapper实现IDevice接口。服务端同理。
6、看看属性上报方法,
public void thingPropertyPost(Map<String, ValueWrapper> params, IPublishResourceListener listener) {
ALog.d("ThingImpl", "thingPropertyPost() called with: params = [" + params + "], listener = [" + listener + "]");
if (this.mIDevice != null) {
this.mIDevice.setPropertyValue(params, true, listener);
}
}
7、mIDevice经过前面几个步骤已经不为空了,可以通过setPropertyValue()方法上报属性了。ClientWrapper是实现了IDevice接口的,我们看看ClientWrapper中的setPropertyValue()详情。然后发现另外一个实现类DeviceImpl。
DeviceImpl中的setPropertyValue()方法详情如下:
public boolean setPropertyValue(List<KeyValuePair> propertyPair, Object tag, IDevListener handler) {
ALog.d("[Tmp]DeviceImpl", "setPropertyValue propertyPair:" + propertyPair + " tag:" + tag + " handler:" + handler);
return this.mDeviceShadow.setPropertyValue(propertyPair, tag, handler);
}
好像是涉及到影子设备,进一步查看影子设备源码
设置影子设备属性方法源码如下(来自于类TDeviceShadow):
public boolean setPropertyValue(List<KeyValuePair> propertyPair, Object tag, IDevListener handler) {
SetPropertyTask task = ((SetPropertyTask)((SetPropertyTask)(new SetPropertyTask(this, (DeviceImpl)this.mImplRef.get(), this.mDeviceBasicData, handler)).setTag(tag)).setDeviceModel(this.mDeviceModel)).setProperties(propertyPair);
return (new AsyncTaskFlow()).appendTask(task).action();
}
((SetPropertyTask)((SetPropertyTask)(new SetPropertyTask(this, (DeviceImpl)this.mImplRef.get(), this.mDeviceBasicData, handler)).
setTag(tag)).setDeviceModel(this.mDeviceModel)).setProperties(propertyPair);
这句代码的意思是:首先new一个SetPropertyTask对象,然后在执行完setTag(tag)将返回值强制转化为SetPropertyTask类型,在接着执行setDeviceModel(this.mDeviceModel),之后再强制转化为SetPropertyTask,再执行setProperties(propertyPair)方法。到影子设备之后涉及将属性保存在TDeviceShadow属性中。
SetPropertyTask类继承于DeviceAsyncTask 又实现了IRequestHandler接口,