在Android中改进GET请求时出错

时间:2016-08-20 09:34:44

标签: android retrofit retrofit2

我正在开发一款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

我的代码出了什么问题?这是我提出要求的方式吗?

4 个答案:

答案 0 :(得分:1)

发生错误是因为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();
        }
    });

答案 1 :(得分:1)

您有两个选择:

  1. 将您的api通话置于单独的Thread

    String result = call.execute().body().toString(); //put this inside seperate Thread
    
  2. 使用Retrofit的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();
        }
    });
    
  3. 您必须检查this NetworkOnMainThreadException

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

How to fix android.os.NetworkOnMainThreadException?

根据Retrofit文档

  

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

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

对于同步通话,我们使用

  

call.execute

对于异步调用,我们使用

  

call.enqueue

我没有使用过排球,但如果你从改造开始,我建议你仔细阅读:

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方法?

希望这会有所帮助:)

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

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