网络请求框架 Retrofit 2 使用入门

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本文讲的是网络请求框架 Retrofit 2 使用入门,Retrofit 是一个用于 Android 和 Java 平台的类型安全的网络请求框架。Retrofit 通过将 API 抽象成 Java 接口而让我们连接到 REST web 服务变得很轻松。
本文讲的是网络请求框架 Retrofit 2 使用入门,

Final product image

你将要创造什么

Retrofit 是什么?

Retrofit 是一个用于 Android 和 Java 平台的类型安全的网络请求框架。Retrofit 通过将 API 抽象成 Java 接口而让我们连接到 REST web 服务变得很轻松。在这个教程里,我会向你介绍如何使用这个 Android 上最受欢迎和经常推荐的网络请求库之一。

这个强大的库可以很简单的把返回的 JSON 或者 XML 数据解析成简单 Java 对象(POJO)。GETPOSTPUTPATCH, 和DELETE 这些请求都可以执行。

和大多数开源软件一样,Retrofit 也是建立在一些强大的库和工具基础上的。Retrofit 背后用了同一个开发团队的 OkHttp 来处理网络请求。而且 Retrofit 不再内置 JSON 转换器来将 JSON 装换为 Java 对象。取而代之的是提供以下 JSON 转换器来处理:

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi

对于 Protocol Buffers, Retrofit 提供了:

  • Protobuf: com.squareup.retrofit2:converter-protobuf

  • Wire: com.squareup.retrofit2:converter-wire

对于 XML 解析, Retrofit 提供了:

  • Simple Framework: com.squareup.retrofit2:converter-simpleframework

那么我们为什么要用 Retrofit 呢?

开发一个自己的用于请求 REST API 的类型安全的网络请求库是一件很痛苦的事情:你需要处理很多功能,比如建立连接,处理缓存,重连接失败请求,线程,响应数据的解析,错误处理等等。从另一方面来说,Retrofit 是一个有优秀的计划,文档和测试并且经过考验的库,它会帮你节省你的宝贵时间以及不让你那么头痛。

在这个教程里,我会构建一个简单的应用,根据 Stack Exchange API 查询上面最近的回答,从而来教你如何使用 Retrofit 2 来处理网络请求。我们会指明 /answers 这样一个路径,然后拼接到 base URL https://api.stackexchange.com/2.2/ 上执行一个 GET请求——然后我们会得到响应结果并且显示到 RecyclerView 上。我还会向你展示如何利用 RxJava 来轻松地管理状态和数据流。

1.创建一个 Android Studio 工程

打开 Android Studio,创建一个新工程,然后创建一个命名为 MainActivity 的空白 Activity。 Create a new empty activity

2. 添加依赖

创建一个新的工程后,在你的 build.gradle 文件里面添加以下依赖。这些依赖包括 RecyclerView,Retrofit 库,还有 Google 出品的将 JSON 装换为 POJO(简单 Java 对象)的 Gson 库,以及 Retrofit 的 Gson。

// Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'

// JSON Parsing
compile 'com.google.code.gson:gson:2.6.1'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

// recyclerview
compile 'com.android.support:recyclerview-v7:25.0.1'

不要忘记同步(sync)工程来下载这些库。

3. 添加网络权限

要执行网络操作,我们需要在应用的清单文件 AndroidManifest.xml 里面声明网络权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.chikeandroid.retrofittutorial">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

4.自动生成 Java 对象

我们利用一个非常有用的工具来帮我们将返回的 JSON 数据自动生成 Java 对象:jsonschema2pojo

取得示例的 JSON 数据

复制粘贴 https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow 到你的浏览器地址栏,或者如果你熟悉的话,你可以使用 Postman 这个工具。然后点击 Enter —— 它将会根据那个地址执行一个 GET 请求,你会看到返回的是一个 JSON 对象数组,下面的截图是使用了 Postman 的 JSON 响应结果。

API response to GET request

   {
      "items": [
        {
          "owner": {
            "reputation": 1,
            "user_id": 6540831,
            "user_type": "registered",
            "profile_image": "https://www.gravatar.com/avatar/6a468ce8a8ff42c17923a6009ab77723?s=128&d=identicon&r=PG&f=1",
            "display_name": "bobolafrite",
            "link": "http://stackoverflow.com/users/6540831/bobolafrite"
          },
          "is_accepted": false,
          "score": 0,
          "last_activity_date": 1480862271,
          "creation_date": 1480862271,
          "answer_id": 40959732,
          "question_id": 35931342
        },
        {
          "owner": {
            "reputation": 629,
            "user_id": 3054722,
            "user_type": "registered",
            "profile_image": "https://www.gravatar.com/avatar/0cf65651ae9a3ba2858ef0d0a7dbf900?s=128&d=identicon&r=PG&f=1",
            "display_name": "jeremy-denis",
            "link": "http://stackoverflow.com/users/3054722/jeremy-denis"
          },
          "is_accepted": false,
          "score": 0,
          "last_activity_date": 1480862260,
          "creation_date": 1480862260,
          "answer_id": 40959731,
          "question_id": 40959661
        },
        ...
      ],
      "has_more": true,
      "backoff": 10,
      "quota_max": 300,
      "quota_remaining": 241
    }

从你的浏览器或者 Postman 复制 JSON 响应结果。

将 JSON 数据映射到 Java 对象

现在访问 jsonschema2pojo,然后粘贴 JSON 响应结果到输入框。

选择 Source Type 为 JSON,Annotation Style 为 Gson,然后取消勾选 Allow additional properties

然后点击 Preview 按钮来生成 Java 对象。

你可能想知道在生成的代码里面, @SerializedName 和 @Expose 是干什么的。别着急,我会一一解释的。

Gson 使用 @SerializedName 注解来将 JSON 的 key 映射到我们类的变量。为了与 Java 对类成员属性的驼峰命名方法保持一致,不建议在变量中使用下划线将单词分开。@SerializeName 就是两者的翻译官。

@SerializedName("quota_remaining")
@Expose
private Integer quotaRemaining;

在上面的示例中,我们告诉 Gson 我们的 JSON 的 key quota_remaining 应该被映射到 Java 变量 quotaRemaining上。如果两个值是一样的,即如果我们的 JSON 的 key 和 Java 变量一样是 quotaRemaining,那么就没有必要为变量设置@SerializedName 注解,Gson 会自己搞定。

@Expose 注解表明在 JSON 序列化或反序列化的时候,该成员应该暴露给 Gson。

将数据模型导入 Android Studio

现在让我们回到 Android Studio。新建一个 data 的子包,在 data 里面再新建一个 model 的包。在 model 包里面,新建一个 Owner 的 Java 类。 然后将 jsonschema2pojo 生成的 Owner 类复制粘贴到刚才新建的 Owner 类文件里面。

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Owner {

    @SerializedName("reputation")
    @Expose
    private Integer reputation;
    @SerializedName("user_id")
    @Expose
    private Integer userId;
    @SerializedName("user_type")
    @Expose
    private String userType;
    @SerializedName("profile_image")
    @Expose
    private String profileImage;
    @SerializedName("display_name")
    @Expose
    private String displayName;
    @SerializedName("link")
    @Expose
    private String link;
    @SerializedName("accept_rate")
    @Expose
    private Integer acceptRate;


    public Integer getReputation() {
        return reputation;
    }

    public void setReputation(Integer reputation) {
        this.reputation = reputation;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUserType() {
        return userType;
    }

    public void setUserType(String userType) {
        this.userType = userType;
    }

    public String getProfileImage() {
        return profileImage;
    }

    public void setProfileImage(String profileImage) {
        this.profileImage = profileImage;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public String getLink() {
        return link;
    }

    public void setLink(String link) {
        this.link = link;
    }

    public Integer getAcceptRate() {
        return acceptRate;
    }

    public void setAcceptRate(Integer acceptRate) {
        this.acceptRate = acceptRate;
    }
}

利用同样的方法从 jsonschema2pojo 复制过来,新建一个 Item 类。

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Item {

    @SerializedName("owner")
    @Expose
    private Owner owner;
    @SerializedName("is_accepted")
    @Expose
    private Boolean isAccepted;
    @SerializedName("score")
    @Expose
    private Integer score;
    @SerializedName("last_activity_date")
    @Expose
    private Integer lastActivityDate;
    @SerializedName("creation_date")
    @Expose
    private Integer creationDate;
    @SerializedName("answer_id")
    @Expose
    private Integer answerId;
    @SerializedName("question_id")
    @Expose
    private Integer questionId;
    @SerializedName("last_edit_date")
    @Expose
    private Integer lastEditDate;

    public Owner getOwner() {
        return owner;
    }

    public void setOwner(Owner owner) {
        this.owner = owner;
    }

    public Boolean getIsAccepted() {
        return isAccepted;
    }

    public void setIsAccepted(Boolean isAccepted) {
        this.isAccepted = isAccepted;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    public Integer getLastActivityDate() {
        return lastActivityDate;
    }

    public void setLastActivityDate(Integer lastActivityDate) {
        this.lastActivityDate = lastActivityDate;
    }

    public Integer getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Integer creationDate) {
        this.creationDate = creationDate;
    }

    public Integer getAnswerId() {
        return answerId;
    }

    public void setAnswerId(Integer answerId) {
        this.answerId = answerId;
    }

    public Integer getQuestionId() {
        return questionId;
    }

    public void setQuestionId(Integer questionId) {
        this.questionId = questionId;
    }

    public Integer getLastEditDate() {
        return lastEditDate;
    }

    public void setLastEditDate(Integer lastEditDate) {
        this.lastEditDate = lastEditDate;
    }
}

最后,为返回的 StackOverflow 回答新建一个 SOAnswersResponse 类。注意在 jsonschema2pojo 里面类名是 Example,别忘记把类名改成 SOAnswersResponse

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.util.List;

public class SOAnswersResponse {

    @SerializedName("items")
    @Expose
    private List<Item> items = null;
    @SerializedName("has_more")
    @Expose
    private Boolean hasMore;
    @SerializedName("backoff")
    @Expose
    private Integer backoff;
    @SerializedName("quota_max")
    @Expose
    private Integer quotaMax;
    @SerializedName("quota_remaining")
    @Expose
    private Integer quotaRemaining;

    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

    public Boolean getHasMore() {
        return hasMore;
    }

    public void setHasMore(Boolean hasMore) {
        this.hasMore = hasMore;
    }

    public Integer getBackoff() {
        return backoff;
    }

    public void setBackoff(Integer backoff) {
        this.backoff = backoff;
    }

    public Integer getQuotaMax() {
        return quotaMax;
    }

    public void setQuotaMax(Integer quotaMax) {
        this.quotaMax = quotaMax;
    }

    public Integer getQuotaRemaining() {
        return quotaRemaining;
    }

    public void setQuotaRemaining(Integer quotaRemaining) {
        this.quotaRemaining = quotaRemaining;
    }
}

5. 创建 Retrofit 实例

为了使用 Retrofit 向 REST API 发送一个网络请求,我们需要用 Retrofit.Builder 类来创建一个实例,并且配置一个 base URL。

在 data 包里面新建一个 remote 的包,然后在 remote 包里面新建一个 RetrofitClient 类。这个类会创建一个 Retrofit 的单例。Retrofit 需要一个 base URL 来创建实例。所以我们在调用 RetrofitClient.getClient(String baseUrl) 时会传入一个 URL 参数。参见 13 行,这个 URL 用于构建 Retrofit 的实例。参见 14 行,我们也需要指明一个我们需要的 JSON converter(Gson)。

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {

    private static Retrofit retrofit = null;

    public static Retrofit getClient(String baseUrl) {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

6.创建 API 接口

在 remote 包里面,创建一个 SOService 接口,这个接口包含了我们将会用到用于执行网络请求的方法,比如 GETPOST,PUTPATCH, 以及 DELETE。在该教程里面,我们将执行一个 GET 请求。

import com.chikeandroid.retrofittutorial.data.model.SOAnswersResponse;

import java.util.List;

import retrofit2.Call;
import retrofit2.http.GET;

public interface SOService {

   @GET("/answers?order=desc&sort=activity&site=stackoverflow")
   Call<List<SOAnswersResponse>> getAnswers();

   @GET("/answers?order=desc&sort=activity&site=stackoverflow")
   Call<List<SOAnswersResponse>> getAnswers(@Query("tagged") String tags);
}

GET 注解明确的定义了当该方法调用的时候会执行一个 GET 请求。接口里每一个方法都必须有一个 HTTP 注解,用于提供请求方法和相对的 URL。Retrofit 内置了 5 种注解:@GET@POST@PUT@DELETE, 和 @HEAD

在第二个方法定义中,我们添加一个 query 参数用于从服务端过滤数据。Retrofit 提供了 @Query("key") 注解,这样就不用在地址里面直接写了。key 的值代表了 URL 里参数的名字。Retrofit 会把他们添加到 URL 里面。比如说,如果我们把 android作为参数传递给 getAnswers(String tags) 方法,完整的 URL 将会是:

https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow&tagged=android

接口方法的参数有以下注解:

@Path 替换 API 地址中的变量
@Query 通过注解的名字指明 query 参数的名字
@Body POST 请求的请求体
@Header 通过注解的参数值指明 header

7.创建 API 工具类

现在我们要新建一个工具类。我们命名为 ApiUtils。该类设置了一个 base URL 常量,并且通过静态方法 getSOService()为应用提供 SOService 接口。

public class ApiUtils {

    public static final String BASE_URL = "https://api.stackexchange.com/2.2/";

    public static SOService getSOService() {
        return RetrofitClient.getClient(BASE_URL).create(SOService.class);
    }
}

8.显示到 RecyclerView

既然结果要显示到 RecyclerView 上面,我们需要一个 adpter。以下是 AnswersAdapter 类的代码片段。

public class AnswersAdapter extends RecyclerView.Adapter<AnswersAdapter.ViewHolder> {

    private List<Item> mItems;
    private Context mContext;
    private PostItemListener mItemListener;

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        public TextView titleTv;
        PostItemListener mItemListener;

        public ViewHolder(View itemView, PostItemListener postItemListener) {
            super(itemView);
            titleTv = (TextView) itemView.findViewById(android.R.id.text1);

            this.mItemListener = postItemListener;
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            Item item = getItem(getAdapterPosition());
            this.mItemListener.onPostClick(item.getAnswerId());

            notifyDataSetChanged();
        }
    }

    public AnswersAdapter(Context context, List<Item> posts, PostItemListener itemListener) {
        mItems = posts;
        mContext = context;
        mItemListener = itemListener;
    }

    @Override
    public AnswersAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        View postView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);

        ViewHolder viewHolder = new ViewHolder(postView, this.mItemListener);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(AnswersAdapter.ViewHolder holder, int position) {

        Item item = mItems.get(position);
        TextView textView = holder.titleTv;
        textView.setText(item.getOwner().getDisplayName());
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    public void updateAnswers(List<Item> items) {
        mItems = items;
        notifyDataSetChanged();
    }

    private Item getItem(int adapterPosition) {
        return mItems.get(adapterPosition);
    }

    public interface PostItemListener {
        void onPostClick(long id);
    }
}

9.执行请求

在 MainActivity 的 onCreate() 方法内部,我们初始化 SOService 的实例(参见第 9 行),RecyclerView 以及 adapter。最后我们调用 loadAnswers() 方法。

 private AnswersAdapter mAdapter;
    private RecyclerView mRecyclerView;
    private SOService mService;

    @Override
    protected void onCreate (Bundle savedInstanceState)  {
        super.onCreate( savedInstanceState );
        setContentView(R.layout.activity_main );
        mService = ApiUtils.getSOService();
        mRecyclerView = (RecyclerView) findViewById(R.id.rv_answers);
        mAdapter = new AnswersAdapter(this, new ArrayList<Item>(0), new AnswersAdapter.PostItemListener() {

            @Override
            public void onPostClick(long id) {
                Toast.makeText(MainActivity.this, "Post id is" + id, Toast.LENGTH_SHORT).show();
            }
        });

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setHasFixedSize(true);
        RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
        mRecyclerView.addItemDecoration(itemDecoration);

        loadAnswers();
    }

loadAnswers() 方法通过调用 enqueue() 方法来进行网络请求。当响应结果返回的时候,Retrofit 会帮我们把 JSON 数据解析成一个包含 Java 对象的 list(这是通过 GsonConverter 实现的)。

public void loadAnswers() {
    mService.getAnswers().enqueue(new Callback<SOAnswersResponse>() {
    @Override
    public void onResponse(Call<SOAnswersResponse> call, Response<SOAnswersResponse> response) {

        if(response.isSuccessful()) {
            mAdapter.updateAnswers(response.body().getItems());
            Log.d("MainActivity", "posts loaded from API");
        }else {
            int statusCode  = response.code();
            // handle request errors depending on status code
        }
    }

    @Override
    public void onFailure(Call<SOAnswersResponse> call, Throwable t) {
       showErrorMessage();
        Log.d("MainActivity", "error loading from API");

    }
});
}

10. 理解 enqueue()

enqueue() 会发送一个异步请求,当响应结果返回的时候通过回调通知应用。因为是异步请求,所以 Retrofit 将在后台线程处理,这样就不会让 UI 主线程堵塞或者受到影响。

要使用 enqueue(),你必须实现这两个回调方法:

  • onResponse()
  • onFailure()

只有在请求有响应结果的时候才会调用其中一个方法。

  • onResponse():接收到 HTTP 响应时调用。该方法会在响应结果能够被正确地处理的时候调用,即使服务器返回了一个错误信息。所以如果你收到了一个 404 或者 500 的状态码,这个方法还是会调用。为了拿到状态码以便后续的处理,你可以使用 response.code() 方法。你也可以使用 isSuccessful() 来确定返回的状态码是否在 200-300 范围内,该范围的状态码也表示响应成功。
  • onFailure():在与服务器通信的时候发生网络异常或者在处理请求或响应的时候发生异常的时候调用。

要执行同步请求,你可以使用 execute() 方法。要注意同步请求在主线程会阻塞用户的任何操作。所以不要在主线程执行同步请求,要在后台线程执行。

11.测试应用

现在你可以运行应用了。

Sample results from StackOverflow

12. 结合 RxJava

如果你是 RxJava 的粉丝,你可以通过 RxJava 很简单的实现 Retrofit。RxJava 在 Retrofit 1 中是默认整合的,但是在 Retrofit 2 中需要额外添加依赖。Retrofit 附带了一个默认的 adapter 用于执行 Call 实例,所以你可以通过 RxJava 的 CallAdapter 来改变 Retrofit 的执行流程。

第一步

添加依赖。

compile 'io.reactivex:rxjava:1.1.6'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

第二步

在创建新的 Retrofit 实例的时候添加一个新的 CallAdapter RxJavaCallAdapterFactory.create()

public static Retrofit getClient(String baseUrl) {
    if (retrofit==null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

第三步

当我们执行请求时,我们的匿名 subscriber 会响应 observable 发射的事件流,在本例中,就是 SOAnswersResponse。当 subscriber 收到任何发射事件的时候,就会调用 onNext() 方法,然后传递到我们的 adapter。

@Override
public void loadAnswers() {
    mService.getAnswers().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<SOAnswersResponse>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(SOAnswersResponse soAnswersResponse) {
                    mAdapter.updateAnswers(soAnswersResponse.getItems());
                }
            });
}

查看 Ashraff Hathibelagal 的 Getting Started With ReactiveX on Android 以了解更多关于 RxJava 和 RxAndroid 的内容。

总结

在该教程里,你已经了解了使用 Retrofit 的理由以及方法。我也解释了如何将 RxJava 结合 Retrofit 使用。在我的下一篇文章中,我将为你展示如何执行 POSTPUT, 和 DELETE 请求,如何发送 Form-Urlencoded 数据,以及如何取消请求。

要了解更多关于 Retrofit 的内容,请参考 官方文档。同时,请查看我们其他一些关于 Android 应用开发的课程和教程。






原文发布时间为:2016年12月26日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。
目录
相关文章
|
24天前
|
人工智能 运维 API
云栖大会 | Terraform从入门到实践:快速构建你的第一张业务网络
云栖大会 | Terraform从入门到实践:快速构建你的第一张业务网络
|
21天前
|
监控 安全 Cloud Native
企业网络架构安全持续增强框架
企业网络架构安全评估与防护体系构建需采用分层防御、动态适应、主动治理的方法。通过系统化的实施框架,涵盖分层安全架构(核心、基础、边界、终端、治理层)和动态安全能力集成(持续监控、自动化响应、自适应防护)。关键步骤包括系统性风险评估、零信任网络重构、纵深防御技术选型及云原生安全集成。最终形成韧性安全架构,实现从被动防御到主动免疫的转变,确保安全投入与业务创新的平衡。
|
3月前
|
机器学习/深度学习 算法 PyTorch
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
本文探讨了图神经网络(GNN)与大型语言模型(LLM)结合在知识图谱问答中的应用。研究首先基于G-Retriever构建了探索性模型,然后深入分析了GNN-RAG架构,通过敏感性研究和架构改进,显著提升了模型的推理能力和答案质量。实验结果表明,改进后的模型在多个评估指标上取得了显著提升,特别是在精确率和召回率方面。最后,文章提出了反思机制和教师网络的概念,进一步增强了模型的推理能力。
143 4
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
|
3月前
|
JSON Dart 前端开发
鸿蒙应用开发从入门到入行 - 篇7:http网络请求
在本篇文章里,您将掌握鸿蒙开发工具DevEco的基本使用、ArkUI里的基础组件,并通过制作一个简单界面掌握使用
117 8
|
3月前
|
机器学习/深度学习 资源调度 算法
图卷积网络入门:数学基础与架构设计
本文系统地阐述了图卷积网络的架构原理。通过简化数学表述并聚焦于矩阵运算的核心概念,详细解析了GCN的工作机制。
237 3
图卷积网络入门:数学基础与架构设计
|
4月前
|
人工智能 自然语言处理
WebDreamer:基于大语言模型模拟网页交互增强网络规划能力的框架
WebDreamer是一个基于大型语言模型(LLMs)的网络智能体框架,通过模拟网页交互来增强网络规划能力。它利用GPT-4o作为世界模型,预测用户行为及其结果,优化决策过程,提高性能和安全性。WebDreamer的核心在于“做梦”概念,即在实际采取行动前,用LLM预测每个可能步骤的结果,并选择最有可能实现目标的行动。
118 1
WebDreamer:基于大语言模型模拟网页交互增强网络规划能力的框架
|
3月前
|
Web App开发 网络协议 安全
网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark
Wireshark是一款开源和跨平台的抓包工具。它通过调用操作系统底层的API,直接捕获网卡上的数据包,因此捕获的数据包详细、功能强大。但Wireshark本身稍显复杂,本文将以用抓包实例,手把手带你一步步用好Wireshark,并真正理解抓到的数据包的各项含义。
171 2
|
3月前
|
机器学习/深度学习 人工智能 算法
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
138 3
|
4月前
|
数据采集 XML 存储
构建高效的Python网络爬虫:从入门到实践
本文旨在通过深入浅出的方式,引导读者从零开始构建一个高效的Python网络爬虫。我们将探索爬虫的基本原理、核心组件以及如何利用Python的强大库进行数据抓取和处理。文章不仅提供理论指导,还结合实战案例,让读者能够快速掌握爬虫技术,并应用于实际项目中。无论你是编程新手还是有一定基础的开发者,都能在这篇文章中找到有价值的内容。
|
4月前
|
JSON 数据处理 Swift
Swift 中的网络编程,主要介绍了 URLSession 和 Alamofire 两大框架的特点、用法及实际应用
本文深入探讨了 Swift 中的网络编程,主要介绍了 URLSession 和 Alamofire 两大框架的特点、用法及实际应用。URLSession 由苹果提供,支持底层网络控制;Alamofire 则是在 URLSession 基础上增加了更简洁的接口和功能扩展。文章通过具体案例对比了两者的使用方法,帮助开发者根据需求选择合适的网络编程工具。
82 3

热门文章

最新文章