【问题标题】:Error in Retrofit GET request in AndroidAndroid 中的 Retrofit GET 请求错误
【发布时间】:2017-11-22 07:17:39
【问题描述】:

我正在开发一个 Android 应用程序。在我的应用程序中,我使用 Retrofit 网络库来连接服务器。这是我第一次使用改造。在我使用 Volley 之前。所以在我在实际项目中使用改造之前,我正在测试它,向服务器发出一个简单的 get 请求。

我在 Gradle 中安装了改造

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

我为改造请求创建了一个接口

public interface RetrofitService {
    @GET("test")
    Call<ChildCategoryItem> repoContributors();

    public static final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(LinkConfig.API_END_POINT)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}

我在这样的活动中提出了请求

 private void makeRetrofitRequest()
    {
        try{
            RetrofitService service = RetrofitService.retrofit.create(RetrofitService.class);
            Call<ChildCategoryItem> call = service.repoContributors();
            String result = call.execute().body().toString();
            Toast.makeText(getBaseContext(),result,Toast.LENGTH_SHORT).show();
        }
        catch (IOException e)
        {
            Toast.makeText(getBaseContext(),"Exception",Toast.LENGTH_SHORT).show();
        }
    }

服务器正在返回这个 json 数据

{"id":1,"name":"name","mm_name":"mm_name"}

这是我的 ChildCategoryItem 类

public class ChildCategoryItem {
    private int Id;
    private String Name;
    private String MmName;
    private int ParentId;

    public void setId(int id)
    {
        this.Id = id;
    }
    public int getId()
    {
        return this.Id;
    }
    public void setName(String name)
    {
        this.Name = name;
    }
    public String getName()
    {
        return this.Name;
    }
    public void setMmName(String mmName)
    {
        this.MmName = mmName;
    }
    public String getMmName()
    {
        return this.MmName;
    }
    public void setParentId(int id)
    {
        this.ParentId = id;
    }
    public int getParentId()
    {
        return this.ParentId;
    }


    public static ChildCategoryItem fromJson(JSONObject json)
    {
        try{
            ChildCategoryItem item = new ChildCategoryItem();
            item.setId(json.getInt("id"));
            item.setName(json.getString("name"));
            item.setMmName(json.getString("mm_name"));
            return item;
        }
        catch (JSONException e)
        {
            return null;
        }
    }
}

当我运行时,它给了我这个错误

08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime: FATAL EXCEPTION: main
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{mmbookhub.com.mmbookhub/mmbookhub.com.mmbookhub.ContributeActivity}: android.os.NetworkOnMainThreadException
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.access$600(ActivityThread.java:141)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:99)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:137)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5103)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:525)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:  Caused by: android.os.NetworkOnMainThreadException
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at libcore.io.IoBridge.connectErrno(IoBridge.java:144)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at libcore.io.IoBridge.connect(IoBridge.java:112)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at java.net.Socket.connect(Socket.java:842)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.AndroidPlatform.connectSocket(AndroidPlatform.java:55)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:185)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:170)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.RealCall.getResponse(RealCall.java:243)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at okhttp3.RealCall.execute(RealCall.java:57)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:89)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at mmbookhub.com.mmbookhub.ContributeActivity.makeRetrofitRequest(ContributeActivity.java:505)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at mmbookhub.com.mmbookhub.ContributeActivity.onCreate(ContributeActivity.java:84)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:5133)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.access$600(ActivityThread.java:141) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:99) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:137) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5103) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:525) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
08-20 05:24:41.195 1341-1341/mmbookhub.com.mmbookhub E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method) 
08-20 05:24:41.231 398-410/system_process W/ActivityManager:   Force finishing activity mmbookhub.com.mmbookhub/.ContributeActivity
08-20 05:24:41.231 398-410/system_process W/ActivityManager:   Force finishing activity mmbookhub.com.mmbookhub/.MainActivity

我的代码有什么问题?这是我提出请求的方式正确吗?

【问题讨论】:

标签: android retrofit retrofit2


【解决方案1】:

你有两个选择:

  1. 将您的 api 调用放在单独的 Thread

    String result = call.execute().body().toString(); //put this inside seperate Thread
    
  2. 使用改造的enqueue()

    call.enqueue(new Callback<ChildCategoryItem>() {
        @Override
        public void onResponse(Call<ChildCategoryItem> call, Response<ChildCategoryItem> response) {
               //Here you will get your response.
        }
    
        @Override
        public void onFailure(Call<ChildCategoryItem> call, Throwable t) {
             t.printStackTrace();
        }
    });
    

您必须检查this 是否有NetworkOnMainThreadException

【讨论】:

  • 谢谢。我可以用这个。但是有问题。当我检索像这样 ChildCategoryItem item = response.body(); 的类别名称时Toast.makeText(getBaseContext(),item.getName(),Toast.LENGTH_SHORT).show(); ,它总是空的。但是服务器返回的正是一个值,请问为什么?我该如何解决?
  • 在解析/使用其数据之前最好检查response.isSuccessful()。如果一切都很完美,请检查您的模型类及其值
  • 在 volley 中,我们必须创建单例类来防止内存不足异常。在改造中,我是否需要像在 volley 中一样创建它?请问我这样做的方式可以防止该错误吗?
  • 我已经检查了成功与否,如你所说。回应是成功。但是值是空的。请问可能的错误是什么?
【解决方案2】:

由于android不支持主线程上的网络而发生错误,您可以通过将网络调用放在新线程中来解决它

或根据您的情况使用以下方法

 call.enqueue(new Callback<ChildCategoryItem>() {
        @Override
        public void onResponse(Call<ChildCategoryItem> call, Response<ChildCategoryItem> response) {

        }

        @Override
        public void onFailure(Call<ChildCategoryItem> call, Throwable t) {
             t.printStackTrace();
        }
    });

【讨论】:

    【解决方案3】:

    使用 call.enqueue() 代替 call.execute() 发出异步请求。 (除了 ui 线程)。 execute() 是在同一线程即 ui 线程上执行的同步调用。

    【讨论】:

      【解决方案4】:

      正如Viktor Yakunin 所指出的,您应该通过以下链接,因为主要问题是使网络调用没有 UI 线程。

      How to fix android.os.NetworkOnMainThreadException?

      根据改造文档

      调用实例可以同步或异步执行。每个实例只能使用一次,但调用 clone() 会创建一个可以使用的新实例。

      在 Android 上,回调将在主线程上执行。在 JVM 上,回调将发生在执行 HTTP 请求的同一线程上。

      对于同步调用,我们使用

      调用.执行

      对于异步调用,我们使用

      call.enqueue

      我没有使用过 volley,但是如果你是从改造开始的,我建议你通过这个:

      Consuming APIs with Retrofit

      对于您的程序,这是最简单的方法:

      ChildCategoryItem.java

      public class ChildCategoryItem
      {
      @SerializedName("id")
      @Expose
      private String id;
      @SerializedName("name")
      @Expose
      private String name;
      @SerializedName("mm_name")
      @Expose
      private String mmName;
      
      /**
       * @return The id
       **/
      public String getId()
      {
          return id;
      }
      
      /**
       * @param id The id
       **/
      public void setId(String id)
      {
          this.id = id;
      }
      
       /**
       * @return The name
       **/
      public String getName()
      {
          return name;
      }
      
      /**
       * @param name The name
       **/
      public void setName(String name)
      {
          this.name = name;
      }
      
      /**
       * @return The mmName
       **/
      public String getMmName()
      {
          return mmName;
      }
      
      /**
       * @param mmName The mm_name
      **/
      public void setMmName(String mmName)
      {
          this.mmName = mmName;
      }
      }
      

      MainActivity.java

      public class MainActivity extends AppCompatActivity
      {
      
          String result;
          doRetrofit DD;
          Call<ChildCategoryItem> call;
          @Override
          protected void onCreate(Bundle savedInstanceState)
          {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              DD= new doRetrofit();
              DD.execute();
          }
      
          public class doRetrofit extends AsyncTask
          {
              @Override
              protected Object doInBackground(Object[] objects)
              {
                  String baseurl="http://192.168.1.12";
                  Retrofit adapter= new Retrofit.Builder().baseUrl(baseurl).addConverterFactory(GsonConverterFactory.create()).build();
                  RetrofitService retrofitService=adapter.create(RetrofitService.class);
                  Call<ChildCategoryItem> call=retrofitService.repoContributors();
                  Response<ChildCategoryItem> c= null;
                  try
                  {
                      c = call.execute();
                  } catch (IOException e)
                  {
                      e.printStackTrace();
                  }
                  Log.d("<<<<<<<<<Response>>>>>>",c.body().toString());
                  ChildCategoryItem child=c.body();
                  Log.d("<<<<<<<<<Response>>>>>>",child.getId());
                  Log.d("<<<<<<<<<Response>>>>>>",child.getName());
                  Log.d("<<<<<<<<<Response>>>>>>",child.getMmName());
      
                  return null;
              }
          }
      }
      

      RetrofitService.java

      public interface RetrofitService
      {
          @GET("/loltry.php")
          Call<ChildCategoryItem> repoContributors();
      }
      

      出于好奇,您在哪里以及如何使用 fromJson 方法?

      希望这会有所帮助:)

      由于缺乏声誉,我无法发表评论,仅供参考:不要在工作线程中使用 toast(即在 Asynctask doInBackground 中)toast 应始终与 UI 线程一起使用。看到这个:

      Can't create handler inside thread that has not called Looper.prepare()

      【讨论】:

        猜你喜欢
        • 2014-03-27
        • 1970-01-01
        • 1970-01-01
        • 2014-12-29
        • 1970-01-01
        • 2016-09-25
        • 1970-01-01
        • 2018-01-28
        • 1970-01-01
        相关资源
        最近更新 更多