1 关键字

直播;列表重复

2 问题描述

现象:频道列表上存在重复的频道,日志查看频道url:

Common:{getLocation:167} DTV getLocation getLocation url isdvb://23f.b.44e
Common:{getLocation:170} DTV getLocation getLocation end
...
Common:{getLocation:167} DTV getLocation getLocation url isdvb://23f.b.44e
Common:{getLocation:170} DTV getLocation getLocation end

3 问题原因

3.1 正常机制

频道列表上每个频道都是唯一的

3.2 异常机制

应用在调用channelManage.filter后刷选出频道,存在重复的频道。

4 解决方案

获取频道时置空 m_list 和 m_channelInfo:

NGBChannel::m_channelInfo.clear();
NGBChannelList::m_list.clear();

5 定位过程

channelManage.filter 功能关键源码如下

// platform\tvos-o\ohos\foundation\multimedia\dtv\frameworks\js\src\ChannelManager.cpp
JS_CHANNEL_PRIVATE* listChannels = NULL;    
NGBChannelList* listPtr = NGBChannelList::create();
int ret = DTVAL_ChannelManager_filterChannels(m_tunerId,filterTypeArr, filterValueArr, arrtypeLen, (JS_CHANNEL_PRIVATE**)&listChannels, &channelNums);
if (channelNums && listChannels) {
      for (int i = 0; i < channelNums; i++) {
          //生成频道对象 NGBChannel
          NGBChannel* host = NGBChannel::create(listChannels[i],m_tunerId);
          if (host) {
              //存进listPtr
              listPtr->append(host);
          }
      }
}
...
napi_value outputArr;
int arrLen = listPtr->length();
//构造返回给应用的数组,长度为istPtr的长度
napi_create_array_with_length(env, arrLen, &outputArr);
...
​

filter调用底层组件DTVAL_ChannelManager_filterChannels接口,根据过滤参数得到频道列表数据(JS_CHANNEL_PRIVATE类型)listChannels,生成NGBChannel后存进 vector NGBChannelList中。最后遍历此vector通过Napi暴露给应用一个数组Array。

NGBChannel(单条频道信息)生成逻辑如下:

// platform\tvos-o\ohos\foundation\multimedia\dtv\frameworks\js\src\NGBChannel.cpp
static NGBChannel* create(JS_CHANNEL_PRIVATE& obj, int tunerId)
{
    return new NGBChannel(obj, tunerId);
}
​
NGBChannel::NGBChannel(const JS_CHANNEL_PRIVATE& obj, int tunerId)
{
    ...
    m_channelInfo.push_back(obj);
    ...   
}

即所有单条频道信息会存进m_channelInfo,m_channelInfo定义如下:

static vector<JS_CHANNEL_PRIVATE> m_channelInfo;

listPtr(频道信息列表)生成逻辑如下:

static NGBChannelList* create()
{
    return new NGBChannelList();
}

通过append添加频道逻辑如下:

void NGBChannelList::append(NGBChannel* channel)
{
    m_list.push_back(channel);
}

即频道信息存进了m_list中,m_list定义:

static vector<NGBChannel*> m_list;

即m_list和m_channelInfo都为对应类内静态变量,它始终驻留在全局数据区,直到程序运行结束。但是存在一种场景:例如更换码流后应用不退出再次搜索频道的情形,此时再一次程序运行周期内,执行了多次filter。这时m_list会保留有以前存在的频道数据,继续追加新的频道数据,造成数据重复现象。

6 知识分享

C++程序在执行的时候,全局区用来存放全局变量和静态变量以及常量,程序结束销毁。

 

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐