HarmonyOS 鸿蒙Next ArKTS中HttpResponse.result类型如何为ArrayBuffer,默认为string
HarmonyOS 鸿蒙Next ArKTS中HttpResponse.result类型如何为ArrayBuffer,默认为string
利用http下载图片并显示,API8
1. httpRequest.request("网址", {
method: http.RequestMethod.GET,
connectTimeout: 60000,
readTimeout: 60000,
header: {
'Content-Type': 'application/octet-stream'
}
}).then((jiguo)=> {
image.createPixelMap(
jiguo.result, //result始终默认为string。无法作为ArrayBuffer
{ editable: true, size: { width: 256, height: 256 }, pixelFormat:3 }
).then ((tu) => { this.tuxiang = tu })
}
网址默认下载的为jpg图片
更多关于HarmonyOS 鸿蒙Next ArKTS中HttpResponse.result类型如何为ArrayBuffer,默认为string的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,图片上传下载可参考以下地址:https://gitee.com/openharmony/app_samples/tree/master/Network/UploadDownload
更多关于HarmonyOS 鸿蒙Next ArKTS中HttpResponse.result类型如何为ArrayBuffer,默认为string的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
为什么不能使用’Content-Type’: ‘application/octet-stream’ 下载为ArrayBuffer直接使用呢,我访问的网站下载的直接是jpg图片。
版主你好,请问ark网络请求回调中无法执行一些系统方法比如setTimeOut,router.push等等,是什么原因?是arkui的bug吗?
我在API9使用了一个叫ImageKnife的三方组件,可以直接下载并缓存网络图片 ,不需要关心ArrayBuffer细节,https://gitee.com/openharmony-tpc/ImageKnife,你也可以试试。另外setTimeout是全局方法,应该没问题,是不是拼错了。但是router.push需要导入import router from '@system.router';
,你可以试试。
我也在研究这个问题,你试试直接用data.result
作为ArrayBuffer
。但根据JS相关的资料,说的是ArrayBuffer
是不能被操作和访问的,比如foreach
遍历的,又要用DataView
封装一遍。但其实我只是想参考官方给的网络图片加载而已。
官方代码如下:
// 先创建一个PixelMap状态变量用于接收网络图片
@State image: PixelMap = undefined
build() {
Column({space: 10}) {
Button("获取网络图片")
.onClick(() => {
this.httpRequest();
})
Image(this.image).height(100).width(100)
}
.width('100%')
.height('100%')
.padding(10)
}
// 网络图片请求方法
private httpRequest() {
let httpRequest = http.createHttp();
httpRequest.request(
"https://www.example.com/xxx.png", // 请填写一个具体的网络图片地址
(error, data) => {
if(error) {
console.log("error code: " + error.code + ", msg: " + error.message)
} else {
let code = data.responseCode
if(ResponseCode.ResponseCode.OK == code) {
let imageSource = image.createImageSource(data.result)
let options = {alphaType: 0,
// 透明度
editable: false,
// 是否可编辑
pixelFormat: 3,
// 像素格式
scaleMode: 1,
// 缩略值
size: {height: 100, width: 100}} // 创建图片大小
imageSource.createPixelMap(options).then((pixelMap) => {
this.image = pixelMap
})
} else {
console.log("response code: " + code);
}
}
}
)
}
但这段代码有个问题就是
let imageSource = image.createImageSource(data.result)
使用API8,这个createImageSource
方法的提示是要传入一个url:string
,但其实http直接访问图片网址,请求到的data.result
是这样的
如果直接在控制台打印data.result
作为字符串,是可以看到和图上TEXT相同的乱码文本的。但这个文本显然是Image
组件无法直接使用的
因此我又查看了giee上官方提供的图片处理相关API
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-image.md#imagecreatepixelmap8
按照我的理解,核心逻辑是要构建一个 pixelMap
,Image
组件直接绑定该 pixelMap
,然后把请求到的图像数据写入 pixelMap
中。
写了一段,还是没跑通,代码如下:
这张网络图片的一些属性如下:
- 图片大小66.5 KB
- 网络请求返回的
Content-Length=68107
- 分辨率 1125x750
struct Index {
// 先创建一个PixelMap状态变量用于接收网络图片
@State imageMy: PixelMap = undefined
build() {
Column({ space: 10 }) {
Button("获取网络图片")
.onClick(() => {
this.httpRequest();
})
Image(this.image)
.height(100)
.width(100)
.alt($r('app.media.ic_launcher'))
.objectFit(ImageFit.Contain)
}
.width('100%')
.height('100%')
.padding(10)
}
// 网络图片请求方法
private httpRequest() {
let httpRequest = http.createHttp();
httpRequest.request(
"https://images.pexels.com/photos/7858743/pexels-photo-7858743.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", // 请填写一个具体的网络图片地址
{
method: http.RequestMethod.GET, // 可选,默认为http.RequestMethod.GET
// 开发者根据自身业务需要添加header字段
header: {},
connectTimeout: 60000, // 可选,默认为60s
readTimeout: 60000, // 可选,默认为60s
},
(error, data) => {
if (error) {
console.log("error code: " + error.code + ", msg: " + error.message)
} else {
// data.header为http响应头,可根据业务需要进行解析
console.info('header:' + JSON.stringify(data.header));
let code = data.responseCode
if (ResponseCode.ResponseCode.OK == code) {
console.info("ResponseCode.ResponseCode.OK=" + ResponseCode.ResponseCode.OK)
console.info("code=" + ResponseCode.ResponseCode.OK)
let resultArrayBuffer = data.result as ArrayBuffer
let resultArrayBufferLength = new ArrayBuffer(3375000)
console.info("resultArrayBuffer=" + resultArrayBuffer.length)
let options = {
alphaType: 0, // 透明度
editable: true, // 是否可编辑
pixelFormat: 2, // 像素格式
scaleMode: 1, // 缩略值
size: { height: 750, width: 1125 }
} // 创建图片大小
image.createPixelMap(resultArrayBufferLength, options).then((pixelMap) => {
pixelMap.writeBufferToPixels(resultArrayBuffer).then(() => {
console.log("Succeeded in writing data from a buffer to a PixelMap.");
this.imageMy=pixelMap//
pixelMap.getImageInfo().then((data) => {//
console.info("data.size.width=" + data.size.width)//
console.info("data.size.height=" + data.size.height)//
data.size.height//
})
}).catch((err) => {
console.error("Failed to write data from a buffer to a PixelMap."+err);
})
})
} else {
console.log("response code: " + code);
}
}
}
)
}
关键点有几个:
createPixelMap
函数第一个参数需要接收一个ArrayBuffer
,最开始我以为这个地方可以直接传入data.result
作为ArrayBuffer
这种形式,发现会提示错误。- 于是手动确定图片大小后,按照上述图片处理API所述,根据图片分辨率1125x720x4创建了
ArrayBuffer
; createPixelMap
第二个参数options
中的size: { height: 750, width: 1125 }
- 使用
writeBufferToPixels
方法将传入的data.result
作为ArrayBuffer
写入pixelMap
中。
一切看起来好像没问题,看日志似乎createPixelMap
也成功了,但一个报错又给我整不会了。
Failed to write data from a buffer to a PixelMap.Error: Failed to napi_get_arraybuffer_info!
import http from '@ohos.net.http';
@Entry
@Preview
@Component
struct Splash {
aboutToAppear() {
let httpRequest = http.createHttp()
let url = 'http://apis.juhe.cn/simpleWeather/query?key=397c9db4cb0621ad0313123dab416668&city=北京'
httpRequest.request(url, (err, data) => {
console.log("请求结果>>" + JSON.stringify(err) + "," + JSON.stringify(data))
setTimeout(() => {
console.log("111")
}, 100)
})
setTimeout(() => {
console.log("222")
}, 200)
}
build() {
Column() {
Text("Hello World").fontSize(30)
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
.backgroundColor("#FFFFFF")
}
}
打印结果:
请求回调里的setTimeOut就不执行…
setTimeout没问题的,我看到222输出了,111 可能部分log日志被过滤了,建议用@State
绑定数据放到UI上Text组件展示,这样能直观看到结果,另外网络请求失败,可以看看是不是网络权限问题,
用State绑定试了,一样没效果,因为请求回调里的setTimeout就没执行,回调外没问题,只要放在回调里就不执行,请求失败那个不是重点,重点在于回调,不知道啥原因0.0,很无语啊…,你试过没?写个最简单的网络请求,然后回调里放个setTimeout试试,我现在不清楚的是arkui本身的问题,还是我自己的环境问题?
试过fetch,以及封装为Promise,都不行,只要写在回调里就不执行,
在HarmonyOS鸿蒙系统的Next ArKTS(Ark TypeScript)环境中,HttpResponse.result
类型默认是 string
。如果你希望将其类型改为 ArrayBuffer
,可以通过处理响应数据来实现,因为原生 HttpResponse
对象并不直接支持将结果解析为 ArrayBuffer
。
你可以通过以下步骤来手动处理响应数据,将其转换为 ArrayBuffer
:
-
获取响应的二进制数据:使用
HttpResponse
对象的arrayBuffer()
方法来获取响应数据的ArrayBuffer
表示。 -
处理
ArrayBuffer
:一旦你有了ArrayBuffer
,你可以使用 TypeScript 中的DataView
或其他相关 API 来进一步处理这些数据。
示例代码(伪代码,具体实现可能需根据实际API调整):
async function fetchData(): Promise<ArrayBuffer> {
const response = await fetch('your-url-here');
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.arrayBuffer();
}
fetchData().then((buffer) => {
// 在这里处理你的 ArrayBuffer
console.log(buffer);
}).catch((error) => {
console.error('Fetch error:', error);
});
注意,上述代码示例使用了 fetch
API,这是基于Web标准的API,在鸿蒙系统中可能有所不同,具体实现需参考鸿蒙系统的文档。
如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html