如何在Android中发送POST请求而不使用AsyncTask。

huangapple go评论83阅读模式
英文:

How to send a post request in Android without using AsyncTask

问题

这是我需要异步调用的整个类:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;

public class ServerConnection {
    private String absoluteUrl;
    String parameters;

    public ServerConnection(String postUrl, HashMap<String, String> keyValuePairs)
    {
        absoluteUrl = postUrl;

        StringBuilder sbParams = new StringBuilder();
        int i = 0;
        for (String key : keyValuePairs.keySet()) {
            try {
                if (i != 0){
                    sbParams.append("&");
                }
                sbParams.append(key).append("=")
                        .append(URLEncoder.encode(keyValuePairs.get(key), "UTF-8"));

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            i++;
        }

        parameters = sbParams.toString();
    }

    public boolean Send()
    {
        HttpURLConnection conn = null;

        try {
            URL urlObj = new URL(absoluteUrl);
            conn = (HttpURLConnection) urlObj.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept-Charset", "UTF-8");

            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);

            conn.connect();

            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
            wr.writeBytes(parameters);
            wr.flush();
            wr.close();

            InputStream in = new BufferedInputStream(conn.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder result = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            return result.toString().equals("OK");
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return false;
        } catch (ProtocolException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }

    }

}

此外,这是一个我将在iOS应用程序中调用的库项目,这就是为什么我正在寻找一种标准的Java方式。

谢谢
Jaime

英文:

I am doing a post request to a server using HttpURLConnection but I got an exception that this cannot be made on UI Thread.

I was looking for information but I have only found information using AsyncTask class, but according to Android documentation, this class is deprecated and I should use java.util.concurrent instead.

I have found many information (for example, a complete HttpClient class or to use external libraries) but none of that does a simple thing to send a post request to an URL.

Can you point me to the right direction?

This is my whole class that I need to call asynchronously:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
public class ServerConnection {
private String absoluteUrl;
String parameters;
public ServerConnection(String postUrl, HashMap&lt;String, String&gt; keyValuePairs)
{
absoluteUrl = postUrl;
StringBuilder sbParams = new StringBuilder();
int i = 0;
for (String key : keyValuePairs.keySet()) {
try {
if (i != 0){
sbParams.append(&quot;&amp;&quot;);
}
sbParams.append(key).append(&quot;=&quot;)
.append(URLEncoder.encode(keyValuePairs.get(key), &quot;UTF-8&quot;));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
i++;
}
parameters = sbParams.toString();
}
public boolean Send()
{
HttpURLConnection conn = null;
try {
URL urlObj = new URL(absoluteUrl);
conn = (HttpURLConnection) urlObj.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod(&quot;POST&quot;);
conn.setRequestProperty(&quot;Accept-Charset&quot;, &quot;UTF-8&quot;);
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.connect();
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(parameters);
wr.flush();
wr.close();
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
return result.toString().equals(&quot;OK&quot;);
} catch (MalformedURLException e) {
e.printStackTrace();
return false;
} catch (ProtocolException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
}

Furthermore, this is a lib project I will call for the iOS application as well, that is why I am looking for a standar java way.

Thanks
Jaime

答案1

得分: 0

根据文档,AsyncTask 现在已经被弃用,你需要使用 java.util.concurrent 替代。这里有一个有用的库叫做 ObservableScheduler,它让你可以使用 java.util.concurrent

implementation 'com.jiang.android.observablescheduler:schedule:1.0.1';

示例:

public void send() {
    JObservable.create(new JObservable.OnSubscribe<StringBuilder>() {
        @Override
        public void call(SubscribeManager<StringBuilder> mSubscriber) {
            try {

                HttpURLConnection conn = null;
                URL urlObj = new URL(absoluteUrl);
                conn = (HttpURLConnection) urlObj.openConnection();
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Accept-Charset", "UTF-8");
                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);
                conn.connect();
                DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
                wr.writeBytes(parameters);
                wr.flush();
                wr.close();
                InputStream in = new BufferedInputStream(conn.getInputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                StringBuilder result = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    result.append(line);
                }
                mSubscriber.notifyData(result);
            } catch (Exception e) {
                mSubscriber.error(e);
            }
        }
    }).workedOn(Schedules.background())
            .subscribeOn(Schedules.mainThread())
            .subscribe(new Subscriber<StringBuilder>() {
                @Override
                public void notifyData(StringBuilder result) {
                    // 在这里进行你的操作
                }

                @Override
                public void error(Throwable t) {
                    Toast.makeText(context, "Ops ! " + t.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
}
英文:

As the documentation said AsyncTask is deprecated now, and you need to use java.util.concurrent instead, here's a helpful library called ObservableScheduler let you use java.util.concurrent:

implementation &#39;com.jiang.android.observablescheduler:schedule:1.0.1&#39;

Example :

  public void send() {
JObservable.create(new JObservable.OnSubscribe&lt;StringBuilder&gt;() {
@Override
public void call(SubscribeManager&lt;StringBuilder&gt; mSubscriber) {
try {
HttpURLConnection conn = null;
URL urlObj = new URL(absoluteUrl);
conn = (HttpURLConnection) urlObj.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod(&quot;POST&quot;);
conn.setRequestProperty(&quot;Accept-Charset&quot;, &quot;UTF-8&quot;);
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.connect();
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(parameters);
wr.flush();
wr.close();
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
mSubscriber.notifyData(result);
} catch (Exception e) {
mSubscriber.error(e);
}
}
}).workedOn(Schedules.background())
.subscribeOn(Schedules.mainThread())
.subscribe(new Subscriber&lt;StringBuilder&gt;() {
@Override
public void notifyData(StringBuilder result) {
//DO YOUR STUFF HERE
}
@Override
public void error(Throwable t) {
Toast.makeText(context, &quot;Ops ! &quot; + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}

答案2

得分: 0

我刚刚创建了一个 Thread 对象,并在 run 方法中添加了我的连接代码。

英文:

I have just created a Thread object and I added my connection code inside the run method.

huangapple
  • 本文由 发表于 2020年8月25日 05:35:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63569009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定