I decided to try to pee under Android, respectively, a very large number of questions appeared. Who is not difficult to answer please.
I try to make the application work with a certain API, communicate using json , but I cannot write a class, such as on Sharpe, to which I pass the address, parameters, and execute a POST request, for example, like here https://stackoverflow.com / questions / 4015324 / http-request-with-post .
As far as I understand, an application on Android cannot perform a POST request from the usual method, you need to use AsyncTask<> - here I did not understand anything at all, starting from the syntax itself, namely, doInBackground(String... params) - String... these are enumerations parameters when calling a method of type doInBackground(str1, str2, str3) or what?
In general, I don’t ask you to write ready code for me , I ask you to help understand the principle of how to work with POST requests on Android, at least one specific example: sending POST (json) and getting an answer also in json and a bit of theory, pzhlst)).
4 answers
AsyncTask better to try once, and then forget about them. The same goes for HttpUrlConnection . Currently, Retorofti is considered to be the main library for interacting with the Rest server on Android. There are examples on the official website. Also there are many of them on third-party resources, for example, here . I will give only an example POST request.
To do this, we need a class model that converts the Json received from the server, a class model for the request body, and an interface with a method annotated with a special annotation.
Suppose the server has a method that adds email addresses to the user, and returns some information about the status of the operation. In the request body, the server accepts the usual array of strings, and returns the result as Json.
First, we create a server response model (the fields are declared as public in order to reduce the code; in a real application, it is better to use private + get / set methods):
public class AddEmailResult { @SerializedName("email") public String email; @SerializedName("primary") public Boolean primary; @SerializedName("verified") public Boolean verified; } Now we create an interface through which interaction with the server will take place.
public interface Server { @POST("user/addemail") Call<List<AddEmailResult>> addEmail(@Body List<String> emails) } Annotation over the method means that a POST request will be executed, the @Body annotation indicates that this object should be passed in the request body.
Next you need to create a server. This is done like this:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") // Адрес сервера .addConverterFactory(GsonConverterFactory.create()) // говорим ретрофиту что для сериализации необходимо использовать GSON .build(); Server service = retrofit.create(Server.class); Call<List<AddEmailResult>> call = service.addEmail(/*list of string*/) call.enqueue(new Callback<List<AddEmailResult>>() { @Override public void onResponse(Call<List<AddEmailResult>> call, Response<List<AddEmailResult>> response) { if (response.isSuccessful()) { // запрос выполнился успешно, сервер вернул Status 200 } else { // сервер вернул ошибку } } @Override public void onFailure(Call<List<AddEmailResult>> call, Throwable t) { // ошибка во время выполнения запроса } }); By calling the enqueue() method, you say that the request is executed asynchronously. At the end, the result will come to the transferred callback where it can be processed. That's basically it. This library is not limited to just a POST request, it is able to do everything necessary for developing a client-server application.
To add retrofit to your project, you need to add the following to build.gradle :
compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.google.code.gson:gson:2.6.1' - Thanks a lot, I figured it out a bit, but another question arose, how to get the answer synchronously through
execute? I want the application to start checking the data through theAPIand, depending on the response, perform the action, but I cannot get the data from theAPIsynchronously at startup and the application always performs the action when the response from theAPI==null- tCode - The @tCode method execute works synchronously, but it is worth considering that Android does not allow working with the network in the main thread. In your case, you are most likely trying to work with the response immediately after the enqueue method, but at that moment the request has not finished yet. You need to handle the answer in the callback, which you transfer to the enqueue method - temq
- @termq, thanks, it came out) - tCode
Here is a simple example of sending a request. params is just an unlimited array of strings. HttpPost accepts a string that is the address of the script on the server.
BasicNameValuePair is just a list of the key value of what you are sending. response is what the server script brought us. It is not necessary to do this in AsyncTask. But usually do in it. Since this is not an instant operation and it would be better to process it in a new stream. If you need to specifically explain something, write in the comments. I will answer
String doInBackground(String... params) throws IOException { DefaultHttpClient hc = new DefaultHttpClient(); ResponseHandler<String> res = new BasicResponseHandler(); HttpPost postMethod = new HttpPost(params[0]); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3); //nameValuePairs.add(new BasicNameValuePair("ID_group", PageViewActivity.Get_list_group.get(PageViewActivity.Cur_group_position).get(0))); nameValuePairs.add(new BasicNameValuePair("ID_group", group_id)); nameValuePairs.add(new BasicNameValuePair("Login", Login)); nameValuePairs.add(new BasicNameValuePair("Password", Password)); postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs)); String response = hc.execute(postMethod, res); System.out.println(response); return response; } And now about parsing json. response - string with json
JSONObject jsonResponse = new JSONObject(response); JSONArray movies = jsonResponse.getJSONArray("Resourse"); for (int i = 0; i < movies.length(); i++) { JSONObject actor = null; actor = movies.getJSONObject(i); String Text = null; Text = actor.getString("ID"); News_list.add(text); } An example of the very json that we parsim can be seen here. Purely to understand the format http://contester.ddns.is74.ru:84/Get_all_group_list.ashx
- you pass specific string parameters
ID_group,Login, etc., and how can this be universalized? - tCode - @tCode is just an example. You can any pair of string values. Think of it as mar which we send to the server. Where then the script on the server should get the value from the key. - Aksenov Vladimir
Here is one more example with ready activity, sending simple json to the server. Copied from my answer:
public class MainActivity extends Activity { ProgressDialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new RequestTask().execute("http://www.site.ru/login.php"); // скрипт, на который посылаем запрос } public String getJSON(String login, String pass) // получаем json объект в виде строки { JSONObject bot = new JSONObject(); try { bot.put("Login", login); bot.put("Password", pass); } catch (JSONException e) { e.printStackTrace(); } return bot.toString(); } public class RequestTask extends AsyncTask<String, String, String> { @Override protected String doInBackground(String... params) { try { DefaultHttpClient hc = new DefaultHttpClient(); ResponseHandler<String> res = new BasicResponseHandler(); HttpPost postMethod = new HttpPost(params[0]); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); // ключ - "json", параметр - json в виде строки nameValuePairs.add(new BasicNameValuePair("json", getJSON("userlogin", "userpass"))); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nameValuePairs, "UTF-8"); postMethod.setEntity(entity); return hc.execute(postMethod, res); } catch (Exception e) { System.out.println("Exp=" + e); } return null; } @Override protected void onPostExecute(String res) { dialog.dismiss(); // res - ответ сервера super.onPostExecute(res); } @Override protected void onPreExecute() { dialog = new ProgressDialog(MainActivity.this); dialog.setMessage("Ожидание"); dialog.setIndeterminate(true); dialog.setCancelable(false); dialog.show(); super.onPreExecute(); } } } You can process the request, for example, in PHP:
<?php $json = $_POST['json']; // получаем json объект $array = json_decode($json, true); // преобразуем его в ассоциативный массив // получаем из него данные $login = $array['Login']; $pass = $array['Password']; // дальше уже делаем то, что нужно file_put_contents('login.txt', "$login\n$pass"); ?> - Thank you, in response to the service, you can zamappit on the class? - tCode
AsyncTask is better to try once, and then forget about them. The same goes for HttpUrlConnection. Currently, Retorofti is considered to be the main library for interacting with the Rest server on Android.
IMHO, Retrofit is heavy, while not well documented library, focused on working with web portals with its own API. At least all the examples on the web illustrate how to work with them. If you need to send a 10-character string via http without creating a lot of unnecessary code later, HttpUrlConnection + AsyncTask fits perfectly.
AsyncTask, ConcerningdoInBackground(String... params)whereString... paramsis an array of not a declared value, there how can I be parameters or not, you need to work withparamsas array. There are libraries that have already bothered about a lot of threading and other things for you, for example Retrofit - JVicAsyncTask<Param, Param, Param>as I understood the first is the type of incoming value, the second type of intermediate value (???), the third is the type of return value, right? What is the intermediate value? - tCodeVolley? - Flippy