接上篇继续,说到通过已知的属性id取到对应的位置,却没有解决根据当前阅读页的段落位置或者笔记位置取到其属性id.这样就会造成一个问题,我只能用其他端的id来跳转到指定的位置阅读,自己却没有属性id来表示同步位置.
后来又无脑的翻找已一下,在JavaNativeFormatPlugin.cpp中找到相关的代码,initInternalHyperlinks()
方法中的model.internalHyperlinks()
就是存储了属性id与段落位置,在上篇中取到的id实际上也是这里持久化的产物.那么我只需将此处的id与位置关系回传给java层并保存下来就差不多了.至于是选择缓存到本地还是内存,还是根据实际情况来判断吧,我这就简单放在内存中.
相关回传的代码(不会c++,low代码别见笑)
static bool initInternalHyperlinks(JNIEnv *env, jobject javaModel, BookModel &model, const std::string &cacheDir) {
ZLCachedMemoryAllocator allocator(131072, cacheDir, "nlinks");
ZLUnicodeUtil::Ucs2String ucs2id;
ZLUnicodeUtil::Ucs2String ucs2modelId;
const std::map<std::string,BookModel::Label> &links = model.internalHyperlinks();
std::map<std::string,BookModel::Label>::const_iterator it = links.begin();
for (; it != links.end(); ++it) {
const std::string &id = it->first;
const BookModel::Label &label = it->second;
//将解析的属性回传给java层的BookModel=====start
JString idj(env, id.substr());
AndroidUtil::Method_BookModel_AttrIds->call(javaModel, idj.j(), label.ParagraphNumber);
//将解析的属性回传给java层的BookModel=====end
if (label.Model.isNull()) {
continue;
}
ZLUnicodeUtil::utf8ToUcs2(ucs2id, id);
ZLUnicodeUtil::utf8ToUcs2(ucs2modelId, label.Model->id());
const std::size_t idLen = ucs2id.size() * 2;
const std::size_t modelIdLen = ucs2modelId.size() * 2;
char *ptr = allocator.allocate(idLen + modelIdLen + 8);
ZLCachedMemoryAllocator::writeUInt16(ptr, ucs2id.size());
ptr += 2;
std::memcpy(ptr, &ucs2id.front(), idLen);
ptr += idLen;
ZLCachedMemoryAllocator::writeUInt16(ptr, ucs2modelId.size());
ptr += 2;
std::memcpy(ptr, &ucs2modelId.front(), modelIdLen);
ptr += modelIdLen;
ZLCachedMemoryAllocator::writeUInt32(ptr, label.ParagraphNumber);
}
allocator.flush();
JString linksDirectoryName(env, allocator.directoryName(), false);
JString linksFileExtension(env, allocator.fileExtension(), false);
jint linksBlocksNumber = allocator.blocksNumber();
AndroidUtil::Method_BookModel_initInternalHyperlinks->call(javaModel, linksDirectoryName.j(), linksFileExtension.j(), linksBlocksNumber);
return !env->ExceptionCheck();
}
其中AndroidUtil::Method_BookModel_AttrIds->call()
方法请依葫芦画瓢!!!
然后在BookModel.java中定义方法接收
protected SparseArray<String> links = new SparseArray<>();
public void attrIds(String attrId, int paragraphIndex){
if (attrId.contains("#")){
//之所以这里有#号,可以看上篇的attrId组成
links.put(paragraphIndex, attrId.split("#")[1]);
}
}
紧接着在需要的地方调用,即做到了通过id取位置,也可以做到通过位置取id
public int getParagraphIndexByAttrId(String attrId){
if (links != null){
int index = links.indexOfValue(attrId);
return links.keyAt(index);
}
return -1;
}
public String getAttrIdByParagraphIndex(int paragraphIndex){
if (links != null){
return links.get(paragraphIndex);
}
return "";
}