Напишем приложение сложение двух чисел, где сложение двух чисел происходит на стороне сервера.
Эта статья из цикла статей Клиент-серверные приложения.
Статья из цикла «Сложение двух чисел». Для меня минимальное освоение любой системы программирования начинается с возможности создания такой программы. Если можно написать приложение, в которой пользователь может ввести два числа, считать их, провести с ними какие-то действия, а потом вывести результат, то, значит, базовое владение имеется. И много задач именно из области программирования, алгоритмики можно будет решать, зная, как в конкретной системе программирования запрограммировать такую программу.
Внимание! В данной статье используются устаревшие классы по работе с запросами. В статье Сложение двух чисел в Android Studio с использованием HttpURLConnection (клиент-серверное приложение) приведен вариант с использованием классов, пришедших на замену.
В статье показан вариант приложения для отправки GET параметров.
Содержание
- Постановка задачи
- Серверная часть
- Создание Android проекта
- XML разметка
- Добавление в Gradle
- Добавляем разрешения
- Java код
Постановка задачи
В статье показан пример приложения под Android по сложению двух чисел. И там сложение двух чисел происходило в самом приложении, что логично. А в этом приложении мы из полей ввода считаем два числа и отправим их на сервер, который сложит два числа, отправит нам ответ, и мы этот ответ отобразим в текстовом поле.
На сервер поступает HTTP запрос с двумя переменными a и b. Переменные a и b передаются через POST параметры.
Серверная часть
У вас должен быть сервер, доступный из интернета, к которому можно обращаться.
В статье приведен пример серверной части на Java.
В статье приведен пример серверной части на PHP.
В статье буду использовать PHP скрипт, который я расположил по адресу http://demo.harrix.org/demo0012/ (при переходе по ссылке должно выдаваться error — и это правильно).
Создание Android проекта
Надеюсь, что вы сможете сами создать болванку приложения, так что закинул под сплойер.
XML разметка
Пусть разметка файла activity_main.xml будет такой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="16dp" android:paddingRight="16dp" android:orientation="vertical" > <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" /> <EditText android:id="@+id/editText2" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" /> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" /> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> |
Есть два поля ввода чисел, кнопка и поле для вывода суммы чисел. Все элементы имеют свои идентификаторы android:id.
Добавление в Gradle
Для работы с запросами над потребуется дополнительная библиотека, которую мы сейчас подключим в Gradle.
В файле build.gradle (Module.app) в разделе dependencies добавьте следующие строчки.
1 2 3 |
android { useLibrary 'org.apache.http.legacy' } |
После этого нажмите на ссылку Sync now.
И ждем, когда закончится синхронизация.
Добавляем разрешения
Приложение у нас будет обращаться в интернет. Поэтому нужно ей дать на это разрешение в AndroidMainfest.xml.
1 |
<uses-permission android:name="android.permission.INTERNET"/> |
Java код
Был такой код файла MainActivity.java.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.example.clientadding2numbers; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } |
Вначале объявим переменные кнопки, полей ввода и поля для вывода результата и соединим их с элементами из XML файла. Также назначим слушателя для клика кнопки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package com.example.clientadding2numbers; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private TextView textView; private EditText editText; private EditText editText2; private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.textView); editText = (EditText)findViewById(R.id.editText); editText2 = (EditText)findViewById(R.id.editText2); button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); } } |
Запросы к серверу по времени могут быть длительными. Поэтому обязательно делаем их в другом потоке. Для этого внутри класса MainActivity создадим класс-наследник от AsyncTask.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class MyAsyncTask extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { //Тут будет запрос к серверу return null; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); } } |
В классе MyAsyncTask объявим переменные.
1 |
String a, b, answerHTTP; |
А также определим переменную server, которая будет указывать на сервер, к которому мы будем осуществлять запрос. Если вы используйте свой сервер, то поменяйте значение.
1 |
String server = "http://demo.harrix.org/demo0012/"; |
В методе onPreExecute() считаем данные из полей ввода.
1 2 3 4 5 6 |
@Override protected void onPreExecute() { a = editText.getText().toString(); b = editText2.getText().toString(); super.onPreExecute(); } |
В методе onPostExecute() выведем ответ сервера.
1 2 3 4 5 |
@Override protected void onPostExecute(String result) { super.onPostExecute(result); textView.setText(answerHTTP); } |
В методе doInBackground() будем обращаться к серверу.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
@Override protected String doInBackground(String... params) { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(server); try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); nameValuePairs.add(new BasicNameValuePair("a", a)); nameValuePairs.add(new BasicNameValuePair("b", b)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); HttpResponse response = httpclient.execute(httppost); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity entity = response.getEntity(); answerHTTP = EntityUtils.toString(entity); } } catch (ClientProtocolException e) { } catch (IOException e) { } return null; } |
От варианта с GET параметрами программа отличается именно этим методом. Обратите внимание на то, что параметры POST мы передаем через устаревший класс пар значений NameValuePair, в место HttpGet используем HttpPost.
Теперь остается только создать экземпляр данного класса MyAsyncTask в слушателе клика кнопки и запустить его.
1 2 3 4 5 6 |
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new MyAsyncTask().execute(); } }); |
В итоге у меня получился вот такой файл.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
package com.example.clientadding2numbers; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private TextView textView; private EditText editText; private EditText editText2; private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.textView); editText = (EditText)findViewById(R.id.editText); editText2 = (EditText)findViewById(R.id.editText2); button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new MyAsyncTask().execute(); } }); } class MyAsyncTask extends AsyncTask<String, String, String> { String a, b, answerHTTP; String server = "http://demo.harrix.org/demo0012/"; @Override protected void onPreExecute() { a = editText.getText().toString(); b = editText2.getText().toString(); super.onPreExecute(); } @Override protected String doInBackground(String... params) { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(server); try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); nameValuePairs.add(new BasicNameValuePair("a", a)); nameValuePairs.add(new BasicNameValuePair("b", b)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); HttpResponse response = httpclient.execute(httppost); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity entity = response.getEntity(); answerHTTP = EntityUtils.toString(entity); } } catch (ClientProtocolException e) { } catch (IOException e) { } return null; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); textView.setText(answerHTTP); } } } |
Всё. Можете запускать приложение и проверять работу.