# empty_rcp_codelab
**Repository Path**: maosiping/empty_rcp_codelab
## Basic Information
- **Project Name**: empty_rcp_codelab
- **Description**: Rcp demo which need the developers to fill some code.
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2024-06-20
- **Last Updated**: 2024-06-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 高性能网络资源加载
### 介绍
[RemoteCommunicationKit](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/remote-communication-kit-guide-V5)提供设备远距离通信能力,应用可以使用RemoteCommunicationKit实现更丰富、低代码和场景化的网络请求与响应。
您将通过本案例实现一个网络加载图文资源的应用。
在实现例1中,这个应用支持简单的网络资源加载功能,您可以用它实现图片与文字的加载与展示;
在实现例2中,这个应用支持拦截器功能,使用拦截器可以方便的对HTTP的请求与响应进行修改,您可以借助拦截器修改网络请求的URL实现请求更轻量的图片资源;
在实现例3中,这个应用支持跟随图文滑动位置动态加载与取消网络资源的能力,基于此您可以实现图文滑动场景高性能流畅加载的极致体验。
### 效果预览
| 实施例1 - 基本图文加载 | 实施例2 - 拦截器 | 实施例3 - 网络图文滑动访问 |
|--------------------------------------------------------------------------|-------------------------------------------|----------------------------------------------------------|
|  |  |  |
### 使用说明
1. 启动应用,进入“RCP Demo”页签。
2. 点击“GET text”按钮,可以从服务器获取到文字信息“Welcome to HDC 2024!”。
3. 点击“GET image”按钮,可以从服务器获取到高分辨率图片。
4. 打开“Simulate slow network”按钮,之后再点击“Get image”按钮,可以从服务器获取到低分辨率图片。
5. 在顶部切换到“Prefetch Demo”页签,您可以体验流畅的网络图文访问界面。
### 工程目录
```
├──entry/src/main/ets // 代码区
│ ├──ets
│ │ ├──prefetchdemo // 网络图文加载功能
│ │ │ └──DataSourcePrefetchingRCP.ets // 实现例3:基于RemoteCommunicationKit的网络加载实现
| | | └──ListItemComponent.ets // 列表详情组件
| | | └──PageViewModel.ets // 列表信息生成器
| | | └──PrefetchDemoComponent.ets // 网络图文列表组件
| | | └──SongInfoItem.ets // 图文字段变量
| | | └──SongInforProvider.ets // 图文信息声
│ │ └──rcpdemo
│ │ └──Interceptors.ets // 实现例2:拦截器
| | └──NetworkStateSimulator.ets // 模拟网络状态
| | |──RCPDemoComponents.ets // 实现例1:基本文字加载
│ └──EntryAbility.ets
| └──MainPage.ets
│ ├──resources // 资源文件夹
├──lib_prefetch // 图文滑动预加载算法
```
### 相关权限
应用需要访问互联网,需要使用网络权限。
```
ohos.permission.INTERNET
```
### 依赖
该应用依赖连接网络服务器。
为了方便您体验RemoteCommunicationKit,我们为您准备临时网络服务器,在各实施例中,我们直接声明您需要访问的URL,您可以直接访问代码中的地址实现预期效果。
**请注意:** 该应用中的临时网络服务器仅用于在当前codelab中使用和体验RemoteCommunicationKit,计划将在2024年7月择期关闭。
### 约束与限制
1. 本示例仅支持标准系统上运行,支持设备:华为手机。
2. HarmonyOS系统:HarmonyOS NEXT Developer Beta1及以上。
3. DevEco Studio版本:DevEco Studio NEXT Developer Beta1及以上。
4. HarmonyOS SDK版本:HarmonyOS NEXT Developer Beta1 SDK及以上。
### Codelab挑战步骤
### 介绍
[RemoteCommunicationKit](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/remote-communication-kit-guide-V5)是全新的场景化网络协议框架。
| RemoteCommunicationKit架构 |
| :-: |
 |
RemoteCommunicationKit主要特性如下:
- 基于Session来处理多个具有共享配置的请求。
- 高度可定制的API:可链接的拦截器,验证器等。使用拦截器实现与业务逻辑分离的辅助操作(基于过滤器的日志记录,身份验证,缓存,cookie处理等)。
- 支持请求/响应数据的扩展格式:字符串,对象,二进制,文件,流,回调,multipart表单。
- 支持自定义证书验证和代理证书(以及SSL pinning)。
- 高级性能调度:取消请求,限制同时连接数,自动选择HTTP版本,为高工作负载启用多线程。
### 您将学到
1. 使用声明式编程风格发送HTTP请求,接收HTTP响应。
2. 创建典型的HTTP会话配置:超时设置、证书验证等。
3. 取消传输层HTTP资源加载。
4. 使用拦截器对HTTP请求进行后处理,并对HTTP响应进行预处理,从而方便、透明地实现业务逻辑。
### 开发准备
1. 准备DevEco Studio。
2. 打开项目。
3. 等待项目同步结束。
4. 为应用签名。
5. 编译和运行应用,点击`Run` > `Run ‘entry’`。
6. 在“RCP Demo”标签中,点击“GET text”按钮、“GET image”按钮。
7. 在“Prefetch Demo”标签中,尝试滑动屏幕。
| Step 2 | Step 4 | Step 6 | Step 7 |
| :-: | :-: | :-: | :-: |
|  |  |  |  |
### 开发过程
#### 任务1 基本图文加载
1. 打开文件 `RCPDemoComponent.ets`,找到`getText`方法
2. 实现`getText`方法的空白部分,以便它可以从`https://1.95.54.71/welcome` URL获取数据,并将结果保存在`responseText`中。您可以使用以下文档作为参考[远程通信工具包/基本功能](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/remote-communication-basic-ability-V5)
3. 编译运行应用,点击“GET text”按钮,您将看到文本区域显示文字。
| 任务1截图 |
| :-: |
|
|
#### 任务2 实现图片下载
1. 打开文件`RCPDemoComponent.ets`文件,找到`getImage`方法
2. 实现`getImage`方法中空白的部分,使它能够访问指定的URL,获取结果显示在`pathToImage`中。
3. 编译运行应用,点击`GET image`按钮,您将看到图片区域显示图片。
参考代码如下:
```typescript
private async getImage() {
this.isImageDownloaded = false;
const networkStateSimulator = new NetworkStateSimulator();
const session = rcp.createSession({
requestConfiguration: {
transfer: {
timeout: {
connectMs: 5 * 1000,
},
},
},
interceptors: [ ],
});
try {
if (this.simulateSlowNetwork) {
networkStateSimulator.simulateSlowNetwork();
} else {
networkStateSimulator.simulateFastNetwork();
}
const request = new rcp.Request('https://1.95.54.71/Panda.jpg', 'GET');
request.destination = {
kind: 'file', file: this.pathToImage
};
request.configuration = {
security: {
remoteValidation: 'skip',
},
tracing: {
collectTimeInfo: true,
},
};
const response = await session.fetch(request);
this.logResponse(response);
const isFileCreated = await fileIo.access(this.pathToImage);
if (response.statusCode === 200 && isFileCreated) {
this.isImageDownloaded = true;
}
} catch (e) {
this.logError(e)
} finally {
session.close();
}
}
```
#### 任务3 实现拦截器
拦截器应用提供了便利的修改请求、响应的方式,在RemoteCommunicationKit中,您可以创建拦截器链,按需定制一组拦截器堆您的网络请求/响应进行修改。
| RemoteCommunicationKit中拦截器工作机制 |
|:-----------------------------------------------:|
|  |
该任务中,您将通过以下步骤实现拦截器。
1. 打开`Interceptors.ets`文件, 找到`RequestUrlChangeInterceptor`和`ResponseHeaderRemoveInterceptor`实现, 您需要实现请求拦截器`RequestUrlChangeInterceptor`:
- `RequestUrlChangeInterceptor`实现请求拦截,例如当网络质量变化时,调整请求资源的大小。
- `ResponseHeaderRemoveInterceptor` 实现响应拦截,它可以在响应返回给应用前检查和修改服务器的请求头。
2. 在`RCPDemoComponent.ets`中,您可以看到`getImage`方法中的session使能了步骤1中的拦截器。
| 拦截器使能的办法 |
|:----------------------------------------------------------------------------:|
|  |
3. 实现拦截器
任务3答案
```typescript
if (context.request.method === 'GET' && !this.networkQualityProvider.isNetworkFast()) {
this.logger.log('[RequestUrlChangeInterceptor]: Slow network is detected');
const parts = context.request.url.pathname.split('.');
if (parts.length === 2) {
const changed = url.URL.parseURL(context.request.url.href);
changed.pathname = parts[0] + '_small.' + parts[1];
this.logger.log(`[RequestUrlChangeInterceptor]: Replace URL from "${context.request.url.href}" to "${changed}"`);
context.request.url = changed;
}
} else {
this.logger.log('[RequestUrlChangeInterceptor]: Network is fast');
}
```
4. 编译运行应用,在点击`Simulate slow network`开关打开后点击`Get Image`,如果您的拦截器实现正确,图片资源将替换为低分辨率图片。
| 实现效果示意 |
|:------------------------------------------------------------------------------:|
|
|
#### 任务4 实现图文请求预加载和取消
1. 打开`DataSourcePrefetchingRCP.ets`文件,实现`prefetch`方法,该方法将页面的albumUrl资源提前下载并缓存到本地文件,使跟随页面滑动时网络图片提前加载。
参考代码如下:
```typescript
async prefetch(index: number): Promise {
PREFETCH_ENABLED = true;
if (this.requestsInFlight.hasKey(index)) {
throw new Error('Already being prefetched');
}
const item = this.data[index];
if (item.cachedImage) {
return;
}
const request = new rcp.Request(item.albumUrl, 'GET');
this.requestsInFlight.set(index, request);
try {
const response = await this.session.fetch(request);
if (response.statusCode !== 200 || !response.body) {
throw new Error('Bad response');
}
item.cachedImage = await this.cache(item.songId, response.body);
this.requestsInFlight.remove(index);
} catch (e) {
if (e.code !== CANCEL_CODE) {
item.cachedImage = IMAGE_UNAVAILABLE;
this.requestsInFlight.remove(index);
}
throw e as Error;
}
```
2. 打开`DataSourcePrefetchingRCP.ets`文件,实现`cancel`方法,该方法可以取消正在下载的网络资源,使不必要的场景下取消网络请求。
参考代码如下:
```typescript
cancel(index: number) {
if (this.requestsInFlight.hasKey(index)) {
const request = this.requestsInFlight.get(index);
this.session.cancel(request);
this.requestsInFlight.remove(index);
}
}
```
3. 编译运行应用,查看效果:图片加载更为流畅丝滑。
| Screenshot of app for steps 3 |
| :-: |
|
|
### 附件
任务1答案
```typescript
private async getText() {
this.responseText = '';
const session = rcp.createSession({
requestConfiguration: {
transfer: {
timeout: {
connectMs: 5 * 1000
},
},
security: {
remoteValidation: 'skip'
},
},
});
try {
const response = await session.get('https://1.95.54.71/welcome');
this.logResponse(response);
const body = response.toString();
if (response.statusCode === 200 && body !== null && body.length > 0) {
this.responseText = body;
}
} catch (e) {
this.logError(e);
} finally {
session.close();
}
}
```