【问题标题】:Retrofit doesn't call onReponse and onFailure改造不调用 onReponse 和 onFailure
【发布时间】:2018-02-23 06:36:26
【问题描述】:

在我的情况下,我使用改造来联系休息 api。不幸的是,当我启动它时,它也永远不会达到 onResponse 和 onFailure 状态。我一行一行地检查调试,看起来他继续行:call.enqueue(new Callback<Api>() { 然后它回到开始循环,再次继续到同一行并跳过两个语句,最后完成整个方法。当然,问题是为什么?

public void ApiHit(String[] tags) {

    //retrofit
    TagApi tagApi = NetworkService.retrofit.create(TagApi.class);

    //recieve words from searchview, divide and put into string array
    for (int i=0; i < tags.length; i++){

        Call<Api> call = tagApi.getTasks(tags[i]);
        call.enqueue(new Callback<Api>() {

            @Override
            public void onResponse(Call<Api> call, Response<Api> response) {


                //recieve possible tags for one word and put it into list
                for (int i = 0; i < response.body().getResults().size(); i++) {
                    listTags.add(new RowModel(response.body().getResults().get(i).getTag(), response.body().getResults().get(i).getAbsRelevance()));

                }

                //sort whole list
                Collections.sort(listTags);

                //add first tags to list
                for (int y = 0; y < 3; y++) {
                    listTagsFinal.add(new RowModel(listTags.get(y).getName(), listTags.get(y).getPosition()));
                }

                if (!isTagognizerTag) {
                    listTagsFinal.add(new RowModel("tagognizer", 23477853));
                    isTagognizerTag = true;
                }

                //add rest tags to list
                for (int y = 3; y < listTags.size(); y++) {
                    listTagsRest.add(new RowModel(listTags.get(y).getName(), listTags.get(y).getPosition()));
                }

            }

            @Override
            public void onFailure(Call<Api> call, Throwable t) {
            }

        });

    }
    //final sort
    Collections.sort(listTagsFinal);
    Collections.sort(listTagsRest);

    for (int y = 0; listTagsFinal.size() < 30; y++) {
        listTagsFinal.add(new RowModel(listTagsRest.get(y).getName(), listTagsRest.get(y).getPosition()));
    }

} 

我在 onCreate 的同一个类(mainactivity)中调用它——当用户接受输入的文本到 searchView 时:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        ButterKnife.bind(this);
        listTags = new ArrayList<>();
        listTagsFinal = new ArrayList<>();
        listTagsRest = new ArrayList<>();

        //set Proxima Bold font on top textview
        Typeface typeface = Typeface.createFromAsset(getAssets(), "font/proximabold.ttf");
        tvTop.setTypeface(typeface);


        //search text handler
        svSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                result = query.split(",?\\ ");
                for (int x = 0; x < result.length; x++) {
                    //  Log.d("ciacho", result[x] + "\n");

                }
                ApiHit(result);
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                //This is your adapter that will be filtered
                return false;
            }
        });


    }

这就是我的简单模型类:

public class RowModel implements Comparable<RowModel>{

    private String name;
    private float position;

    public float getPosition() {
        return position;
    }

    public void setPosition(float position) {
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public RowModel(String name, float position) {
        this.name = name;
        this.position = position;
    }

    @Override
    public int compareTo(RowModel rowModel) {
        float comparePosition = ((RowModel) rowModel).getPosition();


        return (int) (this.position- comparePosition);
    }

以及与 rest 通信的默认类:

public class Api {

    @SerializedName("geo")
    @Expose
    private List<Float> geo = null;
    @SerializedName("rank")
    @Expose
    private int rank;
    @SerializedName("results")
    @Expose
    private List<Result> results = null;
    @SerializedName("tag")
    @Expose
    private String tag;
    @SerializedName("tagExists")
    @Expose
    private boolean tagExists;

    public List<Float> getGeo() {
        return geo;
    }

    public void setGeo(List<Float> geo) {
        this.geo = geo;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public List<Result> getResults() {
        return results;
    }

    public void setResults(List<Result> results) {
        this.results = results;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public boolean isTagExists() {
        return tagExists;
    }

    public void setTagExists(boolean tagExists) {
        this.tagExists = tagExists;
    }

}

和我的改造类的实现:

public class NetworkService {

    public static final Interceptor loggingInterceptor = new HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY);

    public static final OkHttpClient httpClient = new OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .build();

    public static final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://api.xxx.com")
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient)
            .build();

最后一节课:

public interface TagApi {


    @GET("/tag/{tagId}")
    Call<Api> getTasks(
            @Path("tagId") String tagId);


}

【问题讨论】:

  • 可能是你的回复不成功..
  • 你可以通过以下方式检查它... if (response.isSuccessful) // 做其他事情 { // 做另一部分.. 你的应用程序进入这里
  • 检查你的模型..
  • 但是如果响应不成功,他是否应该直接调用 onFailure ?
  • no..onfailure 在这种情况下不会被调用..它只是抛出不成功......它是一种改造方法..

标签: java android retrofit retrofit2


【解决方案1】:

在 Retrofit 2 中,您应该在 baseUrl 的末尾添加一个/

public static final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://api.xxx.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient)
            .build();

并且您不应该在端点路径前放置/

public interface TagApi {
    @GET("tag/{tagId}")
    Call<Api> getTasks(
            @Path("tagId") String tagId);

}

看看例子here

【讨论】:

  • 很遗憾您的更改并没有解决问题:(
  • 你能检查一下你的logcat看看有没有相关的异常吗?
  • 是的,他向我抛出了这个异常 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 这很明显,因为他跳过了封装在 onResponse 部分中的代码的关键部分
  • 对不起,我的意思是在设置改造时是否有异常
  • 不,不幸的是没有错误,我不知道如何强制它抛出任何异常或日志......
【解决方案2】:

call.enqueue是异步操作,第一个FOR循环会在call.enqueue之后继续运行。如果你想阻塞直到收到响应,你需要使用同步call.execute

如果您在 FOR 循环下方评论并在 onResponse() 中放置断点,我认为您应该会看到断点被命中。

for (int y = 0; listTagsFinal.size() < 30; y++) {
    listTagsFinal.add(new RowModel(listTagsRest.get(y).getName(), listTagsRest.get(y).getPosition()));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2019-09-19
    相关资源
    最近更新 更多