【问题标题】:Why can't I send JSON from Android with this code?为什么我不能使用此代码从 Android 发送 JSON?
【发布时间】:2019-10-28 04:34:45
【问题描述】:

我想使用 HTTP (POST) 从 Android 向服务器发送 JSON。

但停在下面一行:

OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());

我为 HTTP 使用了一个线程,并添加了以下清单:

<uses-permission android:name="android.permission.INTERNET" />

但结果并没有改变。

public class MainActivity extends AppCompatActivity {

    private Handler handler = new Handler();
    private String PostUrl = "http://localhost:3000";
    private String JSON = "{\"test\":\"100\"}";

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

    public void callPost()  {

        handler.post(new Runnable() {
            @Override
            public void run() {

                HttpURLConnection con = null;

                try{
                    URL url = new URL(PostUrl);
                    con = (HttpURLConnection) url.openConnection();
                    con.setRequestMethod("POST");
                    con.setDoOutput(true);
                    con.setRequestProperty("Content-Type","application/JSON; charset=utf-8");

                    Log.d("debug", "----- All right here -----");
                    OutputStreamWriter out = new 
OutputStreamWriter(con.getOutputStream());
                    Log.d("debug", "----- This message is not displayed -----");
                    out.write(JSON);
                    out.flush();
                    con.connect();

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

没有错误,只显示“----- All right here -----”。

【问题讨论】:

  • localhost:3000 指向当前设备,除非明确更改为指向远程主机。并查看堆栈跟踪使用e.printStackTrace();
  • 感谢您的快速回复。我将“localhost:3000”更改为服务器的IP地址,但这种情况并没有改变。当我尝试 e.printStackTrace(); , 显示“android.os.NetworkOnMainThreadException”。
  • This 可以帮你解决

标签: java android


【解决方案1】:

更新答案 验证您是否已实现以下几点,然后在最后使用适合您的代码。

1.使用 IP 地址:

您不能在模拟器中使用 localhost,因为模拟器将本地主机引用到自身而不是您的笔记本电脑。而是使用笔记本电脑的 IP 地址,即http://100.100.10.1:3000。 阅读更多here

2。明文问题:

您需要在明文网络配置中添加您的服务器 URL(在您的情况下为 IP 地址)。 为此创建文件 res/xml/network_security_config.xml 并添加您的 IP 地址而不是 Ip.Adress.here。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Ip.Adress.here</domain>
    </domain-config>
</network-security-config>

然后通过android:networkSecurityConfig="@xml/network_security_config"将此文件添加到应用程序标签清单中

清单中的应用程序标记将如下所示

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:networkSecurityConfig="@xml/network_security_config"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

阅读更多here

3.主线程中的网络

您将在主线程问题中获得网络。由于网络调用应该在后台使用异步任务。下面的代码对我来说工作正常,只需将 your.ip.address.here 替换为您的 IP 地址。

public class MainActivity extends AppCompatActivity {

private String PostUrl = "http://your.ip.address.here:3000";
private String JSON = "{\"test\":\"100\"}";

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

class PostTask extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... voids) {
        HttpURLConnection con = null;

        try {
            URL url = new URL(PostUrl);
            con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8");

            Log.d("debug", "----- All right here -----");
            OutputStream os = con.getOutputStream();
            Log.d("debug", "----- This message is not displayed -----");
            os.write(JSON.getBytes("UTF-8"));
            os.close();

            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
            StringBuilder response = new StringBuilder();
            String responseLine = null;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            return response.toString();

        } catch (Exception e) {
            return e.getMessage();
        }
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (s!=null) {
            System.out.println(s);
        } else {
            System.out.println("Result not found");
        }
    }
}

}

祝你好运。 如果仍然存在问题,请尝试从 logcat 发布 System.out 的结果。

【讨论】:

  • 非常感谢您的回答。但结果并没有改变。
  • 抱歉迟到了,这段代码可以从 Android 发送 JSON!非常感谢。
【解决方案2】:

将 con.connect() 行移到 con.setRequestProperty 行之后,并在调用 flush 方法后关闭 OutputStreamWriter。

如果你得到一个 NetworkOnMainThreadException,那是因为你不能在主线程中进行网络调用,所以你需要使用 AsyncTask。

【讨论】:

  • 我通过几个建议解决了这个问题。谢谢。
猜你喜欢
  • 2022-10-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
  • 2023-01-09
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多