android OkHttpClient 请求错误

Posted

技术标签:

【中文标题】android OkHttpClient 请求错误【英文标题】:android OkHttpClient Requesting Error 【发布时间】:2017-01-19 07:55:18 【问题描述】:

我正在尝试使用我的 android 应用程序将一些数据存储在 mysql 数据库中。我正在使用 okhttp3 发送请求,但在这一行出现错误:

client.newCall(request).execute();

我在本地机器和在线尝试过,但它给了我同样的错误,这里是代码,

public class MainActivity extends AppCompatActivity 

    String token1;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        System.out.println("MainActivity is :" + FirebaseInstanceId.getInstance().getToken());
        FirebaseMessaging.getInstance().subscribeToTopic("test");
        FirebaseInstanceId.getInstance().getToken();
        token1=FirebaseInstanceId.getInstance().getToken();
    

    public void clicking(View view) 

        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                .add("Token",token1)
                .build();

        okhttp3.Request request = new okhttp3.Request.Builder()
                .url("http://saleh923.byethost8.com/hii.html")
                .post(body)
                .build();

        try 
            client.newCall(request).execute();
         catch (IOException e) 

            e.printStackTrace();
        
    

这是日志:

 com.example.user.firebasenot E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.user.firebasenot, PID: 3280
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
        at android.view.View.performClick(View.java:5198)
        at android.view.View$PerformClick.run(View.java:21147)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
        at android.view.View.performClick(View.java:5198) 
        at android.view.View$PerformClick.run(View.java:21147) 
        at android.os.Handler.handleCallback(Handler.java:739) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
     Caused by: android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
        at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
        at java.net.InetAddress.getAllByName(InetAddress.java:215)
        at okhttp3.Dns$1.lookup(Dns.java:39)
        at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:172)
        at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:138)
        at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:80)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:178)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:129)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:98)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:109)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:124)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
        at okhttp3.RealCall.execute(RealCall.java:60)
        at com.example.user.firebasenot.MainActivity.clicking(MainActivity.java:54)
        at java.lang.reflect.Method.invoke(Native Method) 
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
        at android.view.View.performClick(View.java:5198) 
        at android.view.View$PerformClick.run(View.java:21147) 
        at android.os.Handler.handleCallback(Handler.java:739) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

【问题讨论】:

您应该投票并标记您认为正确的答案。这会让更多人在 *** 这样的时候帮助你。 #SOBeginnerTips 【参考方案1】:

以下是调试代码的方法: 你在日志中的第一个提示是,

java.lang.IllegalStateException: 无法执行方法 android:onClick

告诉你 onClick 方法的实现有问题,在这种情况下是clicking(View view)。然后你继续寻找你的下一个提示,这是你在日志中的第二个提示,

原因:android.os.NetworkOnMainThreadException

这肯定发生在您指出的clicking(View view) 方法实现行中。它正在从主线程发出网络请求;哦!,Android系统认为这是一件坏事。

那么出路是什么?您可以使用以下任何一种替代方法:

备选方案 1:View.post(Runnable) 或 View.postDelayed(Runnable, long)

备选方案 2:Activity.runOnUiThread(Runnable)

备选方案 3:处理程序

备选方案 4:异步任务

我已经演示了这些替代方案中的每一个,包括您在我的 Github 项目中展示的错误方式,标题为 DemoThreadsAndProcesses。请随时(分叉和)下载并试用它,看看哪种实现方案适合您的兴趣,然后在您自己的项目中使用它。

为了快速检查,我将着手实现您的clicking(View view),如下所示:

public void clicking(View view) 
   new MakeNetworkRequestAsyncTask().execute();


private void makeNetworkRequest() 
    OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                .add("Token",token1)
                .build();

        okhttp3.Request request = new okhttp3.Request.Builder()
                .url("http://saleh923.byethost8.com/hii.html")
                .post(body)
                .build();

        try 
            client.newCall(request).execute();
         catch (IOException e) 
            e.printStackTrace();
        


private class MakeNetworkRequestAsyncTask extends AsyncTask<Void, Void, Void> 
   // The system calls this to perform work in a worker thread and
   // delivers it the parameters given to AsyncTask.execute()
   protected transient Void doInBackground(Void[] params) 
      makeNetworkRequest();
   

   // The system calls this to perform work in the UI thread and
   // delivers the result from doInBackground() method defined above
   @Override
   protected void onPostExecute(Void result) 

希望有帮助!

【讨论】:

【参考方案2】:

错误信息说明了一切:

原因:android.os.NetworkOnMainThreadException

您不应该在主(又名 UI)线程上发出网络请求。 您可以通过多种方式在不同的线程上发出此请求,这是一种:

final OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
        .add("Token",token1)
        .build();

final okhttp3.Request request = new okhttp3.Request.Builder()
        .url("http://saleh923.byethost8.com/hii.html")
        .post(body)
        .build();

final Thread thread = new Thread(new Runnable() 
    @Override
    public void run() 
        try 
            client.newCall(request).execute();
         catch (IOException e) 
            e.printStackTrace();
        
    
);

但是okhttp 让我们更容易使用enqueue method 发出异步请求:

client.newCall(request).enqueue(new Callback() 
    @Override
    public void onFailure(Call call, IOException e) 
        e.printStackTrace();
    

    @Override
    public void onResponse(Call call, final Response response) throws IOException 
        if (!response.isSuccessful()) 
            throw new IOException("Unexpected code " + response);
        

        // you code to handle response
    
);

【讨论】:

以上是关于android OkHttpClient 请求错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android OKHTTPClient 请求上设置(OAuth 令牌)授权标头

如何在 Android OKHTTPClient 请求上设置(OAuth 令牌)授权标头

Android Studio OkHttpClient使用

OkHttpOkHttp 源码分析 ( OkHttpClient.Builder 构造器源码分析 )

使用 OkHttpClient 时来自 SOCKS 服务器的格式错误的回复

OkHTTPClient