0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

解读HarmonyOS如何实现一套网络请求框架

电子工程师 来源:HarmonyOS开发者 作者:裴云飞 2021-05-18 11:21 次阅读

本期我们为大家带来的是开发者裴云飞投稿的“HarmonyOS网络请求框架实现”,这个网络请求框架被命名为“蒹葭(JianJia)”。其原理是将Retrofit移植到HarmonyOS上,同时还实现一些Retrofit所不具备的功能。 比如:Retrofit不支持动态替换域名。众所周知,国内的应用一般都是有多个域名的,蒹葭的一大优势就是支持动态替换域名。

如想了解更多内容,可以直接复制链接看源码哦:https://gitee.com/zhongte/JianJia 接下来我们将挑选几个关键点做解释,希望能给你的HarmonyOS开发之旅带来一些启发~ 在敲代码之前,需要大家下载安装“Huawei DevEco Studio”,如有疑问,可参考官网指南。

● Huawei DevEco Studio安装指南: https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415 为了保证顺利使用,我们先来看一下使用前的一些配置,这里我们主要介绍两个方面配置,一个是针对代码混淆的处理,一个是添加依赖。

01

使用前的配置

1.代码混淆处理

如果项目开启了代码混淆,请在proguard-rules.pro添加如下代码:

-renamesourcefileattribute SourceFile-keepattributes SourceFile,LineNumberTable-dontwarn javax.annotation.**-keepattributes Signature, InnerClasses, EnclosingMethod, Exceptions# 蒹葭-dontwarn poetry.jianjia.**-keep class poetry.jianjia.** { *; }-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations-keepclassmembers,allowshrinking,allowobfuscation interface * { @poetry.jianjia.http.* 《methods》;}

# OkHttp3-dontwarn okhttp3.logging.**-keep class okhttp3.internal.**{*;}-dontwarn okio.**

# gson-keep class sun.misc.Unsafe { *; }-keep class com.google.gson.stream.** { *; }-keepattributes *Annotation*-keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve();}# 在示例代码中,com.poetry.jianjia.bean这个包下面的类实现了Serialized接口,# 实现了Serialized接口的类不能被混淆,请把com.poetry.jianjia.bean这个包名替换成你自己的包名-keep class com.poetry.jianjia.bean.**{*;}

2.添加依赖

添加依赖就是引用类库,详情如下:

1) 在项目根目录下的build.gradle文件中添加mavenCentral()仓库

打开项目根目录下的build.gradle文件,在build.gradle文件的repositories闭包下面添加mavenCentral()。

buildscript { repositories { // 添加maven中央仓库 mavenCentral() maven { url ‘https://mirrors.huaweicloud.com/repository/maven/’ } maven { url ‘https://developer.huawei.com/repo/’ } maven { url ‘http://maven.aliyun.com/nexus/content/repositories/central/’ } jcenter() } dependencies { classpath ‘com.huawei.ohos2.4.2.5’ classpath ‘com.huawei.ohos1.0.0.6’ }}

allprojects { repositories { // 添加maven中央仓库 mavenCentral() maven { url ‘https://mirrors.huaweicloud.com/repository/maven/’ } maven { url ‘https://developer.huawei.com/repo/’ } maven { url ‘http://maven.aliyun.com/nexus/content/repositories/central/’ } jcenter() }}

2)在build.gradle文件的dependencies闭包下添加依赖

打开entry目录下的build.gradle文件,在build.gradle文件中的dependencies闭包下添加下面的依赖。

// 蒹葭的核心代码implementation ‘io.gitee.zhongte1.0.1’// 数据转换器,数据转换器使用gson来帮我们解析json,不需要我们手动解析jsonimplementation ‘io.gitee.zhongte1.0.1’implementation “com.google.code.gson2.8.2”// 日志拦截器,通过日志拦截器可以看到请求头、请求体、响应头、响应体implementation ‘com.squareup.okhttp33.7.0’// 如果服务端返回的json有特殊字符,比如中文的双引号,gson在解析的时候会对特殊字符进行转义// 这时就需要将转义后的字符串进行反转义,commons-lang可以对特殊字符进行转义和反转义implementation ‘commons-lang2.6’

3)在配置文件中添加以下权限

ohos.permission.INTERNET

02

用法

蒹葭与Retrofit用法相同,并且蒹葭提供一系列的注解。“注解”可以看作是对一个类/方法的一个扩展的模版,每个类/方法按照注解类中的规则,来为类/方法注解不同的参数,在用到的地方可以得到不同的类/方法中注解的各种参数与值。在进行网络请求的时候,就需要用到这些注解,下文将介绍蒹葭中常用和需要注意的注解。

1.GET注解

创建接口,在方法里面使用GET注解,GET注解用于标识这是一个GET请求,方法的返回值是Call对象,泛型是ResponseBody,其实泛型也可以是具体的实体对象,我们将在下文“16.添加数据转换器“中详说。

蒹葭如何完成网络请求?使用构造者模式创建jianjia对象,baseUrl就是域名,在创建jianjia对象的时候就必须指定域名。

调用create方法来生成接口的实例,调用wan.getBanner().enqueue来执行网络请求,请求成功就会回调onResponse方法,请求失败就会回调onFailure方法。

public interface Wan { @GET(“banner/json”) Call《ResponseBody》 getBanner();}JianJia jianJia = new JianJia.Builder() .baseUrl(“https://www.wanandroid.com”) .build();Wan wan = jianJia.create(Wan.class);wan.getBanner().enqueue(new Callback《ResponseBody》() { @Override public void onResponse(Call《ResponseBody》 call, Response《ResponseBody》 response) { try { String json = response.body().string(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call《ResponseBody》 call, Throwable t) { LogUtils.info(“yunfei”, t.getMessage()); }});

2. BaseUrl注解

国内的应用一般都是有多个域名的,BaseUrl注解可以对某个接口设置单独的域名。

public interface Wan { @BaseUrl(“https://api.apiopen.top”) @GET(“getJoke”) Call《ResponseBody》 getJoke(@QueryMap Map《String, String》 param);}

3. Path注解

Path注解在路径中替换指定的参数值,定义下面的方法。可以看到我们定义了一个getArticle方法,方法接收一个page参数,并且我们的@GET注解中使用{page}声明了访问路径,这里你可以把{page}当做占位符,而实际运行中会通过@Path(“page”)所标注的参数进行替换。

public interface Wan {

@GET(“article/list/{page}/json”) Call《ResponseBody》 getArticle(@Path(“page”) int page);

}

4.Query注解

Query注解用于给“get请求”添加请求参数,被Query注解修饰的参数类型可以是数组、集合、字符串等。

public interface Wan { @GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@Query(“k”) String k); @GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@Query(“k”) String.。。 k); @GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@Query(“k”) List《String》 k);}

5.QueryMap注解

QueryMap注解以map的形式添加查询参数,被QueryMap注解修饰的参数类型必须是Map对象。

public interface Wan {

@GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@QueryMap Map《String, String》 param);}

6.SkipCallbackExecutor注解

在HarmonyOS中,默认将服务端的响应回调到主线程,如果在方法上使用SkipCallbackExecutor注解,就不会将服务端的结果回调到主线程。

public interface Wan { @SkipCallbackExecutor @GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@QueryMap Map《String, String》 param);}

7.FormUrlEncoded注解和Field注解

“FormUrlEncoded注解”用于发送一个表单请求,使用该注解必须在方法的参数中添加Field注解,被Field注解修饰的参数类型可以是数组、集合、字符串等。

public interface Wan { @POST(“user/login”) @FormUrlEncoded Call《ResponseBody》 login(@Field(“username”) String username, @Field(“password”) String password);}

8.FormUrlEncoded注解和FieldMap注解

有时候表单的参数会比较多,如果使用Field注解,方法的参数就会比较多,此时就可以使用FieldMap注解,FieldMap注解以map的形式发送一个表单请求。如果被FieldMap注解修饰的参数不是Map类型,就会报异常。如果Map的键值对为空,也会报异常。

public interface Wan { @POST(“user/login”) @FormUrlEncoded Call《ResponseBody》 login(@FieldMap Map《String, String》 map);}

9. Body注解

服务端会要求客户端把json字符串作为请求体发给服务端。此时就可以使用Body注解定义的参数直接传入一个实体类,内部会把该实体序列化并将序列化后的结果直接作为请求体发送出去。 如果被Body注解修饰的参数的类型是RequestBody对象,那调用者可以不用添加数据转换器,内部会使用默认的数据转换器。

如果被Body注解修饰的参数的类型不是RequestBody对象,是一个具体的实体类,那调用者需要自定义一个类,并且继承Converter.Factory。

public interface Wan { /** * 被Body注解修饰的参数的类型是RequestBody对象,那调用者可以不添加数据转换器,内部会使用默认的数据转换器 * * @param body * @return */ @POST(“user/register”) Call《ResponseBody》 register(@Body RequestBody body);

/** * 被Body注解修饰的参数的类型不是RequestBody对象,是一个具体的实体类,那调用者需要自定义一个类,并且继承Converter.Factory * * @param user * @return */ @POST(“user/register”) Call《ResponseBody》 register(@Body User user);}

10.Url注解

Url注解用于添加接口的完整地址。在Retrofit里面,如果接口的域名与创建retrofit对象指定的域名不相同,就会使用Url注解来解决问题。在蒹葭里面不但可以使用Url注解来解决问题,还提供了BaseUrl来解决该问题。

public interface Wan {

@GET() Call《ResponseBody》 getArticle(@Url String url);

}

11.Header注解

Header注解是作用于参数上的注解,用于添加请求头。

public interface Wan {

@GET() Call《ResponseBody》 foo(@Header(“Accept-Language”) String lang);

}

12.Headers注解

Headers注解是作用于方法上的注解,用于添加一个或多个请求头。

public interface Wan { @Headers(“Cache-Control: max-age=640000”) @GET(“/”) Call《ResponseBody》 getArticle(@Url String url); @Headers({ “X-Foo: Bar”, “X-Ping: Pong” }) @GET(“/”) Call《ResponseBody》 getArticle(@Url String url);}

13.HeaderMap注解

HeaderMap注解是作用于参数上的注解,以Map的形式添加请求头,Map中每一项的键和值都不能为空,否则会报异常。

public interface Wan {

@GET(“/search”) Call《ResponseBody》 list(@HeaderMap Map《String, String》 headers);

}

14. Multipart注解和Part注解

Multipart注解和Part注解用于上传单个文件。 在配置文件添加下面两个权限,这两个权限需要动态申请。

ohos.permission.READ_MEDIAohos.permission.WRITE_MEDIA

定义一个upload方法,方法参数使用Part注解修饰,参数类型必须是MultipartBody.Part。

public interface Wan {

/** * 上传文件,需要使用Multipart注解和Part注解 * * @param photo 本地文件的路径 * @return */ @Multipart @POST() Call《ResponseBody》 upload(@Part MultipartBody.Part photo);}// 文件路径File file = new File(getExternalCacheDir(), “icon.png”);// 创建请求体对象RequestBody photoBody = RequestBody.create(MediaType.parse(“image/png”), file);// MultipartBody.Part photo = MultipartBody.Part.createFormData(“photos”, “icon.png”, photoBody);

JianJia jianJia = new JianJia.Builder() .baseUrl(“https://www.wanandroid.com”) .build();

Wan wan = jianJia.create(Wan.class);// 上传文件wan.upload(photo).enqueue(new Callback《ResponseBody》() { @Override public void onResponse(Call《ResponseBody》 call, Response《ResponseBody》 response) { // 上传成功 }

@Override public void onFailure(Call《ResponseBody》 call, Throwable t) { LogUtils.info(“yunfei”, t.getMessage()); }});

15.PartMap注解和Multipart注解

PartMap注解和Multipart注解用于上传多个文件在配置文件添加下面两个权限,这两个权限需要动态申请:

ohos.permission.READ_MEDIAohos.permission.WRITE_MEDIA

被PartMap注解修饰的Map,Map的第一个泛型必须是String:

public interface Wan {

/** * 使用PartMap注解上传多个文件 * * @param params 第一个泛型必须是String * @return */ @Multipart @POST() Call《ResponseBody》 upload(@PartMap Map《String, RequestBody》 params);}File photoFile = new File(getExternalCacheDir(), “photo.png”);RequestBody photoBody = RequestBody.create(MediaType.parse(“image/png”), photoFile);

File avatarFile = new File(getExternalCacheDir(), “avatar.png”);RequestBody avatarBody = RequestBody.create(MediaType.parse(“image/png”), avatarFile);Map《String, RequestBody》 photos = new HashMap《》();photos.put(“photo”, photoBody);photos.put(“avatar”, avatarBody);

JianJia jianJia = new JianJia.Builder() .baseUrl(“https://www.wanandroid.com”) .build();

Wan wan = jianJia.create(Wan.class);// 上传文件wan.upload(photos).enqueue(new Callback《ResponseBody》() { @Override public void onResponse(Call《ResponseBody》 call, Response《ResponseBody》 response) { // 上传成功 }

@Override public void onFailure(Call《ResponseBody》 call, Throwable t) { LogUtils.info(“yunfei”, t.getMessage()); }});

16.添加数据转换器

之前我们在接口里面定义方法(GET注解中)的时候,方法的返回值Call对象,泛型是ResponseBody。在这种情况下,服务端返回给客户端的数据就会在ResponseBody里面,客户端需要手动解析json,将json解析成一个实体类。 其实,我们没必要手动解析json,可以让gson帮我们解析json。蒹葭支持添加数据转换器,在创建对象的时候添加数据转换器,也就是把gson添加进来。在onResponse方法里面就可以直接得到实体类对象了,gson帮我们把json解析成了一个实体类。

public interface Wan { @GET(“banner/json”) Call《Banner》 getBanner();}JianJia jianJia = new JianJia.Builder() .baseUrl(“https://www.wanandroid.com”) .addConverterFactory(GsonConverterFactory.create()) .build();Wan wan = jianJia.create(Wan.class);wan.getBanner().enqueue(new Callback《Banner》() { @Override public void onResponse(Call《Banner》 call, Response《Banner》 response) { try { if (response.isSuccessful()) { Banner banner = response.body(); } } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call《Banner》 call, Throwable t) { LogUtils.info(“yunfei”, t.getMessage()); }});

03

Demo演示

● 示例中的网页地址:

https://www.wanandroid.com/blog/show/2 视频内显示的是一个网页上的文章列表。客户端通过使用蒹葭网络库访问该网站提供的接口,以此来获取网页的文章列表,当请求成功后,文章列表将显示在模拟器页面上。

以下为Demo代码关键步骤的详解:

1.在com.poetry.jianjia.net包下面创建了如下的接口,把所有的请求放在一个接口里面即可, 无需创建多个接口类。

/** * @author 裴云飞 * @date 2021/1/23 */public interface Wan {

@GET(“article/list/{page}/json”) Call《ResponseBody》 getArticle(@Path(“page”) int page);

@GET(“article/list/{page}/json”) Call《Article》 getHomeArticle(@Path(“page”) int page);

@GET() Call《ResponseBody》 getArticle(@Url String url);

@GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@Query(“k”) String k);

@GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@Query(“k”) String.。。 k);

@GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@Query(“k”) List《String》 k);

@GET(“wxarticle/list/405/1/json”) Call《ResponseBody》 search(@QueryMap Map《String, String》 param);

@GET(“article/list/0/json”) Call《ResponseBody》 getArticle(@QueryMap Map《String, String》 param);

@BaseUrl(“https://api.apiopen.top”) @GET(“getJoke”) Call《ResponseBody》 getJoke(@QueryMap Map《String, String》 param);

@POST(“user/login”) @FormUrlEncoded Call《ResponseBody》 login(@Field(“username”) String username, @Field(“password”) String password);

@POST(“user/login”) @FormUrlEncoded Call《ResponseBody》 login(@FieldMap Map《String, String》 map);

@GET(“banner/json”) Call《Banner》 getBanner();}

(左右滑动查看更多)

2.创建“jianjia”对象,整个项目只需一个jianjia对象即可。 如何确保只有一个 jianjia对象?当代码运行起来后,首先会创建AbilityPackage对象,调用AbilityPackage的onInitialize方法,AbilityPackage执行完成后才会启动Ability。AbilityPackage就是一个全局的单例,所以在 AbilityPackage里面创建的对象就是一个单例对象。只需在AbilityPackage 里面创建jianjia对象,就能确保整个项目只有一个jianjia对象。AbilityPackage这个类不需要手动创建,在创建的项目的时候, 编译器会自动创建一个继承于AbilityPackage的类。

public class BaseApplication extends AbilityPackage {

private static BaseApplication instance;

private JianJia mJianJia; private Wan mWan;

public static BaseApplication getInstance() { return instance; }

/** * 获取全局的蒹葭对象 * * @return 全局的蒹葭对象 */ public JianJia getJianJia() { return mJianJia; }

/** * 获取全局的接口实例对象 * * @return 全局的接口实例对象 */ public Wan getWan() { return mWan; }

@Override public void onInitialize() { super.onInitialize(); instance = this; // 创建全局的蒹葭对象 mJianJia = new JianJia.Builder() .baseUrl(“https://www.wanandroid.com”) .addConverterFactory(GsonConverterFactory.create()) .build(); mWan = mJianJia.create(Wan.class); }}

如上面的代码,BaseApplication继承AbilityPackage,在onInitialize 方法创建全局的蒹葭对象。同时,整个项目只创建了一个接口类,所以可以在创建完蒹葭对象后直接调用蒹葭的create方法来创建接口的实例对象。其它地方只需要通过下面的方式即可获取蒹葭对象和接口实例对象。

// 获取全局的蒹葭对象BaseApplication.getInstance().getJianJia();// 获取全局的接口实例对象BaseApplication.getInstance().getWan();

3.在MainAbilitySlice里面添加ListContainer,关于ListContainer的用法,请查看 官方文档 ,此处不再赘述。

● 官方文档

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-listcontainer-0000001060007847

接着调用“getHomeArticle方法”请求服务器,“getHomeArticle方法”会获取在AbilityPackage里面创建好的对象,然后执行网络请求,请求成功后调用“setHomeArticle方法”来刷新页面。

public class MainAbilitySlice extends AbilitySlice {

private ListContainer mListContainer; private HomeArticleProvider mHomeArticleProvider; List《Article.Data.Datas》 mDatas;

@Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); mListContainer = (ListContainer) findComponentById(ResourceTable.Id_list); mDatas = new ArrayList《》(); mHomeArticleProvider = new HomeArticleProvider(this, mDatas); mListContainer.setItemProvider(mHomeArticleProvider); // 从服务端获取数据 getHomeArticle(); }

/** * 从服务端获取数据 */ public void getHomeArticle() { BaseApplication.getInstance().getWan().getHomeArticle(0).enqueue(new Callback《Article》() { @Override public void onResponse(Call《Article》 call, Response《Article》 response) { if (response.isSuccessful()) { // 请求成功 setHomeArticle(response.body()); } }

@Override public void onFailure(Call《Article》 call, Throwable t) { // 请求失败 LogUtils.info(“yunfei”, t.getMessage()); } }); }

@Override public void onActive() { super.onActive(); }

@Override public void onForeground(Intent intent) { super.onForeground(intent); }

public void setHomeArticle(Article article) { if (article == null || article.data == null || article.data.datas == null) { return; } mDatas.addAll(article.data.datas); // 刷新列表 mHomeArticleProvider.notifyDataChanged(); }

}

(左右滑动查看更多)

04

关于转义字符问题的解决

如果服务端返回的json有特殊字符,比如中文的双引号。gson在解析的时候会对特殊字符进行转义,这时就需要将转义后的字符串进行反转义。如下图所示:

如何将转义后的字符串进行反转义?commons-lang这个库可以将转义后的字符串进行反转义,在build.gradle文件添加下的依赖。

// commons-lang可以对特殊字符进行转义和反转义implementation ‘commons-lang2.6’

调用StringEscapeUtils的unescapeHtml方法,如果字符串中没有转义字符,unescapeHtml方法会直接返回原字符串,否则会对字符串进行反转义。具体的代码可查看示例代码中的HomeArticleProvider类。

// json里面有一些特殊符号,特殊符号会被gson转义,// StringEscapeUtils可以对转义的字符串进行反转义String title = StringEscapeUtils.unescapeHtml(data.title);componentHolder.title.setText(title);

反转义之后,特殊字符即可正常显示:

温馨提示:如果开发者具备以下知识的基础,看源码的时会更加轻松哦。

熟悉okhttp的常见用法

熟悉面向接口编程、反射、泛型、注解

熟悉构造者模式、适配器模式、工厂模式、策略模式、静态代理、动态代理、责任链模式等设计模式

Demo刚运行的时候页面可能会出现白屏的情况,是因为此时正在请求网络。可以增加一个进度条来提升用户体验,大家可以自行添加~

目前只获取了第一页的文章列表,有兴趣的开发者可以自行实现分页加载,让内容更加丰富,由于篇幅有限,此处只展示简单的示例。

本文作者:裴云飞,爱奇艺应用开发工程师

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 转换器
    +关注

    关注

    27

    文章

    8732

    浏览量

    147473
  • 服务器
    +关注

    关注

    12

    文章

    9239

    浏览量

    85682
  • 代码
    +关注

    关注

    30

    文章

    4803

    浏览量

    68762
  • 接口编程
    +关注

    关注

    0

    文章

    9

    浏览量

    8748
  • OpenHarmony
    +关注

    关注

    25

    文章

    3729

    浏览量

    16409

原文标题:【开发者说】HarmonyOS如何实现一套网络请求框架

文章出处:【微信号:HarmonyOS_Dev,微信公众号:HarmonyOS开发者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    HarmonyOS NEXT应用元服务开发Intents Kit(意图框架服务)综述

    、综述 Intents Kit(意图框架服务)是HarmonyOS级的意图标准体系 ,意图连接了应用/元服务内的业务功能。 意图框架能帮开发者将应用/元服务内的业务功能,智能分发到各
    发表于 11-28 10:43

    Vector推出一套基于Visual Studio Code的免费插件

    编写工具(如Vector的CAPL Browser)虽然功能强大,但是结合Visual Studio Code更能够满足多语言编程和集成现代开发工具的需求。 因此,Vector推出一套基于Visual
    的头像 发表于 11-24 14:15 468次阅读
    Vector推出<b class='flag-5'>一套</b>基于Visual Studio Code的免费插件

    卷积神经网络实现工具与框架

    卷积神经网络因其在图像和视频处理任务中的卓越性能而广受欢迎。随着深度学习技术的快速发展,多种实现工具和框架应运而生,为研究人员和开发者提供了强大的支持。 TensorFlow 概述
    的头像 发表于 11-15 15:20 290次阅读

    Python编程:处理网络请求的代理技术

    网络编程中,代理技术扮演着至关重要的角色,尤其在处理网络请求时。通过代理服务器,我们可以实现请求的转发、缓存、负载均衡以及安全控制等功能。
    的头像 发表于 11-12 07:23 205次阅读

    HarmonyOS NEXT应用元服务开发Intents Kit(意图框架服务)本地搜索方案概述

    、概述 本地搜索是在HarmonyOS化搜索特性,开发者将应用/元服务内的功能和内容通过意图框架共享到HarmonyOS,即可
    发表于 11-06 10:59

    AWTK 最新动态:支持鸿蒙系统(HarmonyOS Next)

    为ToolkitAnyWhere,是ZLG倾心打造的一套基于C语言开发的GUI框架。旨在为用户提供个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的GUI引擎,支
    的头像 发表于 11-06 08:03 277次阅读
    AWTK 最新动态:支持鸿蒙系统(<b class='flag-5'>HarmonyOS</b> Next)

    如何设计出一套用于移动式综合监测站管理的软件系统

    如何设计出一套用于移动式综合监测站管理的软件系统 要设计并实现一套系统,用于管理移动式综合监测站,并具备绘制其动态位置变化图和部署时间分布图的功能,我们需要从系统的整体架构设计、功能模块划分
    的头像 发表于 09-10 18:15 221次阅读

    bootstrap框架和vue框架的区别

    响应式移动优先的网页。Bootstrap的核心设计理念是“移动优先”,即优先考虑移动设备的显示效果,然后通过媒体查询等技术实现对不同设备的适配。Bootstrap提供了一套丰富的CSS和JavaScript组件,可以快速实现各种
    的头像 发表于 07-11 09:55 914次阅读

    HarmonyOS NEXT Developer Beta1最新术语表

    Foundation,硬件驱动框架,用于提供统外设访问能力和驱动开发、管理框架。 HML HarmonyOS Markup Language,是
    发表于 06-27 16:16

    在不同的电脑上启动同一套代码时,出现编译路径错误的提示怎么解决?

    不同的电脑上安装esp-idf的路径不同时,启动同一套代码时会出现: 无法找到“D:\\Espressif\\tools\\xtensa-esp32-elf\\esp-2022r1-11.2.0
    发表于 06-11 06:54

    专家解读 | NIST网络安全框架(1):框架概览

    本文主要探讨NIST CSF框架的起源目标、内容组成,及其在网络安全风险管理中的关键作用,通过采用该框架,组织能够更有效地实施风险识别、安全保护、威胁检测和事件响应,从而构建更加坚固和弹性的
    的头像 发表于 05-06 10:30 1387次阅读
    专家<b class='flag-5'>解读</b> | NIST<b class='flag-5'>网络</b>安全<b class='flag-5'>框架</b>(1):<b class='flag-5'>框架</b>概览

    鸿蒙OS开发实例:【HarmonyHttpClient】网络框架

    鸿蒙上使用的Http网络框架,里面包含纯Java实现的HttpNet,类似okhttp使用,支持同步和异步两种请求方式;还有鸿蒙版retrofit,和Android版Retrofit相
    的头像 发表于 04-12 16:58 860次阅读
    鸿蒙OS开发实例:【HarmonyHttpClient】<b class='flag-5'>网络</b><b class='flag-5'>框架</b>

    ICON发布一套新型建筑3D打印硬件、软件和材料

    2024年3月,先进建筑公司ICON 发布了一套实现建筑自动化的新产品和技术,包括能够实现多层建筑的全新机器人打印机、新型低碳建筑材料、包含 60 多种现成住宅设计的住宅建筑数字目录,以及用于住宅设计和施工的 AI 建筑师。
    的头像 发表于 04-07 18:27 1175次阅读

    鸿蒙OS开发实例:【窥探网络请求

    HarmonyOS 平台中使用网络请求,需要引入 "@ohos.net.http", 并且需要在 module.json5 文件中申请网络权限, 即 “ohos.permission.
    的头像 发表于 04-01 16:11 810次阅读
    鸿蒙OS开发实例:【窥探<b class='flag-5'>网络</b><b class='flag-5'>请求</b>】

    鸿蒙OS封装【axios 网络请求】(类似Android的Okhttp3)

    HarmonyOS 封装 axios 网络请求 包含 token 类似Android Okhttp3
    的头像 发表于 03-26 21:14 2770次阅读