
鸿蒙5手机-平板协同阅读器开发实战:基于分布式数据同步的阅读进度共享 原创
鸿蒙5手机-平板协同阅读器开发实战:基于分布式数据同步的阅读进度共享
一、项目概述与架构设计
本方案实现一个支持手机和平板间实时同步阅读进度的电子阅读器,核心技术包括:
分布式数据管理:跨设备阅读状态同步
ArkUI声明式开发:阅读器UI构建
分布式文件共享:书籍内容快速传输
多设备协同:自动识别附近设备并建立连接
技术架构图
┌─────────────┐ ┌─────────────┐
手机设备 │ │ 平板设备 │
┌────────┐ │ │ ┌────────┐ │
│ 阅读器 │ │ │ │ 阅读器 │ │
│ UI组件 ├─┼──────┤ │ UI组件 │ │
└───┬────┘ │ │ └───┬────┘ │
│ │ │ │ │
└──────┼──────┘ └──────┼──────┘
分布式数据服务 │
└─────────┬──────────┘
┌──────▼──────┐
鸿蒙分布式 │
软总线 │
└─────────────┘
二、核心代码实现
分布式数据同步服务
// DistributedDataManager.ets
import distributedData from ‘@ohos.data.distributedData’;
const STORE_ID = ‘reader_sync_store’;
const KEY_READING_PROGRESS = ‘reading_progress’;
export class DistributedDataManager {
private kvManager: distributedData.KVManager;
private kvStore: distributedData.KVStore;
async initKVStore(context: Context) {
try {
const config = {
context: context,
bundleName: ‘com.example.reader’
};
this.kvManager = await distributedData.createKVManager(config);
const options = {
createIfMissing: true,
encrypt: true,
backup: false,
autoSync: true,
kvStoreType: distributedData.KVStoreType.SINGLE_VERSION
};
this.kvStore = await this.kvManager.getKVStore(STORE_ID, options);
await this.kvStore.enableSync({enable: true});
catch (err) {
console.error('Init KVStore failed:', err);
}
// 同步阅读进度
async syncReadingProgress(bookId: string, progress: ReadingProgress) {
try {
const data = {
bookId,
progress,
timestamp: new Date().getTime(),
deviceId: deviceInfo.deviceId
};
await this.kvStore.put({KEY_READING_PROGRESS}_{bookId}, JSON.stringify(data));
catch (err) {
console.error('Sync progress failed:', err);
}
// 监听进度变化
subscribeProgressChanges(callback: (bookId: string, progress: ReadingProgress) => void) {
this.kvStore.on(‘dataChange’, distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, (changes) => {
changes.forEach(change => {
if (change.key.startsWith(KEY_READING_PROGRESS)) {
const data = JSON.parse(change.value);
if (data.deviceId !== deviceInfo.deviceId) { // 排除本设备触发
const bookId = change.key.replace(${KEY_READING_PROGRESS}_, ‘’);
callback(bookId, data.progress);
}
});
});
}
interface ReadingProgress {
chapter: number;
page: number;
position: number; // 0-100 百分比
阅读器主界面实现
// ReaderPage.ets
@Entry
@Component
struct ReaderPage {
@State currentBook: BookInfo;
@State readingProgress: ReadingProgress = { chapter: 0, page: 0, position: 0 };
@State connectedDevices: Array<DeviceInfo> = [];
private dataManager: DistributedDataManager = new DistributedDataManager();
private bookManager: BookManager = new BookManager();
aboutToAppear() {
// 初始化数据同步
this.dataManager.initKVStore(getContext(this));
this.dataManager.subscribeProgressChanges(this.handleProgressChange.bind(this));
// 加载书籍
this.currentBook = this.bookManager.getCurrentBook();
this.loadProgress();
build() {
Column() {
// 顶部状态栏
ReaderHeader({
book: this.currentBook,
progress: this.readingProgress,
devices: this.connectedDevices
})
// 阅读内容区域
Scroll(this.readingProgress.position) {
BookContent({
content: this.bookManager.getBookContent(
this.currentBook.id,
this.readingProgress.chapter
)
})
.onScrollEnd((offset: number) => {
this.updateProgress(offset);
})
// 底部控制栏
ReaderFooter({
onPrev: this.prevChapter.bind(this),
onNext: this.nextChapter.bind(this)
})
}
private updateProgress(offset: number) {
const newProgress = this.calculateProgress(offset);
this.readingProgress = newProgress;
this.dataManager.syncReadingProgress(this.currentBook.id, newProgress);
private handleProgressChange(bookId: string, progress: ReadingProgress) {
if (bookId === this.currentBook.id) {
this.readingProgress = progress;
// 滚动到同步的位置
scrollTo(progress.position);
}
// 其他方法…
设备发现与连接管理
// DeviceManager.ets
import deviceManager from ‘@ohos.distributedHardware.deviceManager’;
export class DeviceManager {
private deviceList: Array<DeviceInfo> = [];
private discoverManager;
async startDiscovery() {
try {
this.discoverManager = await deviceManager.createDeviceManager(‘com.example.reader’);
this.discoverManager.on('deviceStateChange', (data) => {
this.handleDeviceChange(data);
});
this.discoverManager.startDeviceDiscovery(['reader_sync']);
catch (err) {
console.error('Device discovery failed:', err);
}
private handleDeviceChange(data: deviceManager.DeviceStateChangeData) {
if (data.action === 0) { // 设备上线
if (!this.deviceList.some(d => d.deviceId === data.device.deviceId)) {
this.deviceList.push(data.device);
} else if (data.action === 1) { // 设备下线
this.deviceList = this.deviceList.filter(d => d.deviceId !== data.device.deviceId);
// 更新UI
AppStorage.setOrCreate('connectedDevices', this.deviceList);
async connectDevice(deviceId: string) {
try {
const device = this.deviceList.find(d => d.deviceId === deviceId);
if (device) {
await this.discoverManager.authenticateDevice(deviceId, {
authType: 1, // PIN码认证
extraInfo: {}
});
} catch (err) {
console.error('Connect device failed:', err);
}
书籍内容分布式共享
// BookManager.ets
import fileIO from ‘@ohos.fileio’;
import distributedFile from ‘@ohos.file.distributed’;
export class BookManager {
private currentBookId: string = ‘’;
async shareBookToDevice(bookId: string, deviceId: string) {
try {
const bookPath = this.getBookPath(bookId);
const fileUri = await distributedFile.getDistributedFile(bookPath);
await distributedFile.send(deviceId, [fileUri], (progress) => {
console.log(传输进度: ${progress});
});
catch (err) {
console.error('Share book failed:', err);
}
async receiveBookFromDevice(deviceId: string) {
return new Promise((resolve, reject) => {
distributedFile.receive(deviceId, (files) => {
if (files.length > 0) {
const bookFile = files[0];
this.saveBook(bookFile).then(resolve).catch(reject);
else {
reject(new Error('No book received'));
});
});
// 其他书籍管理方法…
三、关键功能实现细节
阅读进度同步算法
// 计算阅读进度
private calculateProgress(offset: number): ReadingProgress {
const totalHeight = this.getContentHeight();
const visibleHeight = this.getVisibleHeight();
const currentPos = offset / (totalHeight - visibleHeight) * 100;
// 计算当前章节和页数
const chapterCount = this.currentBook.chapters.length;
const currentChapter = Math.min(
Math.floor(currentPos / 100 * chapterCount),
chapterCount - 1
);
const pagesInChapter = this.getPagesInChapter(currentChapter);
const currentPage = Math.min(
Math.floor((currentPos % (100 / chapterCount)) / (100 / chapterCount) * pagesInChapter),
pagesInChapter - 1
);
return {
chapter: currentChapter,
page: currentPage,
position: currentPos
};
多设备冲突解决策略
// 处理多设备同时修改的冲突
private resolveProgressConflict(local: ReadingProgress, remote: ReadingProgress): ReadingProgress {
// 策略1: 选择时间戳最新的
if (remote.timestamp > local.timestamp) {
return remote;
// 策略2: 如果时间相近,选择阅读更远的进度
const timeDiff = Math.abs(remote.timestamp - local.timestamp);
if (timeDiff < 5000) { // 5秒内
const localPos = local.chapter * 100 + local.position;
const remotePos = remote.chapter * 100 + remote.position;
return remotePos > localPos ? remote : local;
return local;
UI自适应布局
// 自适应文本样式
@Extend(Text) function responsiveText(sizeTable: Record<string, number>) {
.fontSize(sizeTable[deviceInfo.deviceType] || sizeTable.default)
// 使用示例
Text(this.currentBook.title)
.responsiveText({
phone: 18,
tablet: 24,
default: 16
})
四、项目部署与测试
配置权限
在module.json5中添加必要权限:
“requestPermissions”: [
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”
},
“name”: “ohos.permission.READ_USER_STORAGE”
},
“name”: “ohos.permission.DISTRIBUTED_SOFTBUS”
]
测试方案
// 模拟多设备测试
describe(‘ReadingProgressSync’, () => {
it(‘should sync progress between devices’, async () => {
const device1 = new MockDevice(‘device1’);
const device2 = new MockDevice(‘device2’);
await device1.setProgress({chapter: 1, page: 10, position: 25});
await device2.waitForSync();
expect(device2.getProgress()).toEqual({
chapter: 1,
page: 10,
position: 25
});
});
});
五、性能优化建议
数据同步频率控制:
private lastSyncTime: number = 0;
private throttleSync(progress: ReadingProgress) {
const now = Date.now();
if (now - this.lastSyncTime > 1000) { // 1秒限流
this.dataManager.syncReadingProgress(this.currentBook.id, progress);
this.lastSyncTime = now;
}
缓存策略:
@StorageProp('lastReadingState')
lastReadingState: Record<string, ReadingProgress> = {};
网络状态检测:
import network from '@ohos.net.connection';
network.getDefaultNet().on(‘netAvailable’, (data) => {
if (data.netInfo.type === network.NetBearType.BEARER_WIFI) {
this.resumeSync();
});
六、总结与扩展
本方案实现了:
基于分布式数据管理的阅读进度实时同步
手机与平板间的无缝阅读体验切换
自适应不同设备的UI布局
完善的冲突解决和异常处理机制
扩展方向:
添加多人批注共享功能
实现语音朗读进度同步
集成云端书库备份
开发阅读数据统计面板
鸿蒙的分布式能力为多设备协同提供了强大支持,开发者可以基于此模式轻松实现各种跨设备场景的应用创新。
