【问题标题】:How to do API call with Request body(application/json) and Request headers?如何使用请求正文(应用程序/json)和请求标头进行 API 调用?
【发布时间】:2016-04-20 19:01:14
【问题描述】:

我是安卓初学者。尝试使用请求正文(应用程序/json)和请求标头调用 API。这是我尝试过的

private String doEmotionAPICall(String imgURL){

        //creating map object to creat Json object from it
        try {
            HttpClient client = new DefaultHttpClient();
            HttpPost post = new HttpPost("https://api.projectoxford.ai/emotion/v1.0/recognize");
            JSONObject data = new JSONObject();
            try {
                data.put("url", imgURL);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            StringEntity se = new StringEntity(data.toString());

            se.setContentEncoding("UTF-8");
            se.setContentType("application/json");

            post.setEntity(se);
            post.setHeader("Ocp-Apim-Subscription-Key", "my key");
            HttpResponse response = client.execute(post);
            String result = EntityUtils.toString(response.getEntity());

            Toast.makeText(getApplicationContext(),result,Toast.LENGTH_LONG).show();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "result if success";
    }
}

它给出了类似的错误

01-15 13:13:36.188    3849-3849/net.simplifiedcoding.imageuploadsample E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: net.simplifiedcoding.imageuploadsample, PID: 3849
    android.os.NetworkOnMainThreadException
            at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
            at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
            at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
            at java.net.InetAddress.getAllByName(InetAddress.java:214)
            at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
            at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
            at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
            at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:374)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:575)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:498)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:476)
            at net.simplifiedcoding.imageuploadsample.MainActivity.doEmotionAPICall(MainActivity.java:184)
            at net.simplifiedcoding.imageuploadsample.MainActivity.onClick(MainActivity.java:149)
            at android.view.View.performClick(View.java:4456)
            at android.view.View$PerformClick.run(View.java:18465)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

https://dev.projectoxford.ai/docs/services/5639d931ca73072154c1ce89/operations/563b31ea778daf121cc3a5fa

更新

尝试使用AsyncTask toast 消息消息不只显示on pre toast 消息显示其他没有也没有错误。有没有其他方法可以调试它或我做错了?

这里是代码

 private  void doEmotionAPICall() {

        class CallAPI extends AsyncTask<String, Integer, String> {
            protected void onPreExecute() {
                Toast.makeText(getApplicationContext(), "on pre", Toast.LENGTH_LONG).show();
            }
            protected void onPostExecute() {
                Toast.makeText(getApplicationContext(), "on post", Toast.LENGTH_LONG).show();
            }

            @Override
            protected String doInBackground(String... params) {
                try {
                    HttpClient client = new DefaultHttpClient();
                    HttpPost post = new HttpPost("https://api.projectoxford.ai/emotion/v1.0/recognize");
                    JSONObject data = new JSONObject();
                    String imgURL = "http://amysdayspa.com/wp-content/uploads/2015/02/smile.jpg";
                    try {
                        data.put("url", imgURL);
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    Toast.makeText(getApplicationContext(), "json" + data, Toast.LENGTH_LONG).show();

                    StringEntity se = new StringEntity(data.toString());

                    se.setContentEncoding("UTF-8");
                    se.setContentType("application/json");
                    post.setEntity(se);
                    post.setHeader("Ocp-Apim-Subscription-Key", "my key");
                    HttpResponse response = client.execute(post);
                    Toast.makeText(getApplicationContext(), "response", Toast.LENGTH_LONG).show();

                    String result = EntityUtils.toString(response.getEntity());

                    Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();

                } catch (Exception e) {
                    e.printStackTrace();
                }

                return "selva";
            }
        }
        String imgURL = "http://amysdayspa.com/wp-content/uploads/2015/02/smile.jpg";
        new CallAPI().execute(imgURL);

        //creating map object to creat Json object from it

    }

【问题讨论】:

  • 把api调用代码放到Async类的doInBackground()方法中。在谷歌上搜索异步类,你会看到很多例子。或者使用任何第三方库进行 API 调用,例如 VolleyRetrofit
  • 哦,谢谢,上面的代码是否正确?

标签: android json api androidhttpclient


【解决方案1】:

Android 上的网络调用禁止在主线程上运行。

要解决这个问题,只需在 AsyncTask 的 doInBackground 方法中运行您的代码。

这将确保您的代码可以在另一个线程上正常运行。 AsyncTask 为您提供了很大的灵活性,可以在 (onPreExecution) 之前、在 (onProgressUpdate) 期间、在 (onPostExecute) 之后以及在操作取消的情况下 (onCancelled) 处理应用程序的状态。

请注意,只有 doInBackground 会在另一个线程上运行。

【讨论】:

  • 谢谢,除此之外我的代码是否正确?
  • 检查您的更新代码。将所有与 UI 相关的代码移至“onPostExecute”方法。 onPostExecute 在 doInBackground 之后运行并在主线程上运行,您可以在其中与 UI 进行交互。 doInBackground 中不会发生更改
【解决方案2】:

你在主线程上做,当有人试图在主线程上做长时间工作时发生这个异常,尝试使用Async task

【讨论】:

    【解决方案3】:

    您正在主线程上执行一些长时间运行的操作。 请使用AsyncTaskHere 是一个很好的教程。

    【讨论】:

    • 谢谢,除此之外我的代码是否正确?
    • 除非你尝试我不能说,因为我还没有编译:D 要么
    • 更改了我的代码,伙计。我现在什么也得不到。只有 pre exe 工作 @sector11
    • 你应该等到 ondoinbackground 完成
    【解决方案4】:

    这个异常

    android.os.NetworkOnMainThreadException
    

    当应用程序尝试在主线程上执行网络操作时发生。使用 AsyncTask 从中恢复。

    更多信息请通过link

    希望对你有帮助

    【讨论】:

    • 谢谢,除此之外我的代码是否正确?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多