Bonjour, fin d'école cette semaine complète, passer les vacances d'été sans contenu de la semaine prochaine c'est mon. Cette fois, j'aimerais utiliser l'application Android pour la communication HTTP avec l'API Django créée dans Article précédent.
Au fait, la qualité n'est pas si élevée car elle a été mise en œuvre en un jour même si elle a été couverte. (Bien que cela prenne environ 16 heures)
C'est là que j'ai eu le plus de problèmes. Je n'ai pas du tout compris la configuration d'exécution, je ne pouvais pas du tout voir l'image dans son ensemble, comment implémenter le front-end? etc. Tout d'abord, si vous ne pouvez pas saisir le tableau d'ensemble, vous ne savez pas par quoi commencer. Par conséquent, tout d'abord, il est nécessaire de comprendre de quel type de structure il est constitué et ce qu'il peut faire.
De plus, récemment, il y a Kotlin et React Native lors du développement d'applications Android, mais cette fois, nous utiliserons Java qui est Owacon Legacy Language.
Voici quelques actions importantes à effectuer lors de la création d'une application Android. À tout le moins, je veux que vous compreniez cette configuration, alors pardonnez-moi.
--Activité
Si un amoureux du Web le compare à MVC, cette fois, le modèle est sur le serveur Django, et le code java qui compose Android est le contrôleur, et la partie écrite en XML est la vue.
Cette fois, la partie que je ne comprenais pas le plus sur la communication HTTP est ici. Quelle classe est exécutée dans Android en premier lieu? J'avais des ennuis parce que c'était comme ça. En tant que prémisse majeure ** Lorsque vous exécutez Android, la classe spécifiée dans le manifeste sera exécutée. ** ** En d'autres termes, même si vous définissez d'autres classes, vous devrez éventuellement les agréger ici. (Je n'ai pas compris ça)
L'image ressemblera à la figure ci-dessous.
C'est un chiffre sale, mais comme la seule classe qui est finalement exécutée est la classe principale, même s'il y a beaucoup d'autres classes, le traitement que vous voulez faire est exécuté uniquement dans la classe principale. Vous pouvez faire un détour, alors passons à la principale! !! !!
Écrivons en fait le code.
Les classes utilisées cette fois sont les suivantes.
classe | Utilisation |
---|---|
ExSample.java | Classe d'exécution principale |
AsyncHttpRequestGet.java | Obtenez toutes les données |
AsyncHttpRequestPost.java | Envoyer une notification de fin de livraison |
ListAndView.java | Classe pour définir la vue de liste dans une disposition linéaire |
Cette fois, je vais créer une application Android en utilisant ces quatre.
Écrivons.
--Construisez un programme en héritant de la classe AppCompatActivity. --Exécutez avec la méthode onCreate.
ExSample.java
package es.exsample;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
public class ExSample extends AppCompatActivity {
//Afficher la classe
private static final String TAG = "ExSample";
//Variables pour référencer le contexte dans différentes classes
private static ExSample context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_item);
context = this;
//Courir
AsyncHttpRequestGet task = new AsyncHttpRequestGet(context);
task.execute("http://localhost:8000/get_shop");
Log.d(TAG, "created");
}
//Fonctions d'utilisation du contexte dans d'autres classes
public static ExSample getInstance(){
return context;
}
}
--ExSample n'exécute que ceci, donc le montant dans cette classe est plutôt grand.
AsyncHttpRequestGet.java
package es.exsample;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
public class AsyncHttpRequestGet extends AsyncTask<String, Void, String> {
//Balise enregistreur
private static final String TAG = "AsyncHttpRequestGet";
//Vue exploitée depuis le fil de l'interface utilisateur
private TextView titleView;
private TextView beforUserContent;
private TextView doneUserContent;
private ListView beforUser;
private ListView doneUser;
public static Map<String, String> data;
public static List<Map<String, String>> dataList;
public static ListView listView;
public static ListAndView adapter;
//Constructeur d'ensemble, vue
public AsyncHttpRequestGet(Context context) {
super();
ExSample sample = (ExSample) context;
titleView = (TextView)sample.findViewById(R.id.title);
beforUserContent = (TextView)sample.findViewById(R.id.befor);
doneUserContent = (TextView)sample.findViewById(R.id.done);
beforUser = (ListView)sample.findViewById(R.id.beforUser);
doneUser = (ListView)sample.findViewById(R.id.doneUser);
listView = (ListView)sample.findViewById(R.id.beforUser);
}
//Traitez les demandes et les réponses ici
@Override
protected String doInBackground(String... params) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
HttpsURLConnection connection = null;
try {
//L'URL est définie, la valeur d'en-tête est gérée ici et le jeton peut être obtenu lors de la connexion.
URL url = new URL(params[0]);
connection = (HttpsURLConnection)url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Spécifiez la clé obtenue par JWT Django");
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
// GET
connection.setRequestMethod("GET");
connection.connect();
//Vérifiez le code de réponse
int responseCode = connection.getResponseCode();
if(responseCode != HttpsURLConnection.HTTP_OK) {
throw new IOException("HTTP responseCode: " + responseCode);
}
//Stringification
inputStream = connection.getInputStream();
if(inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(connection != null) {
connection.disconnect();
}
}
return sb.toString();
}
//Créez une vue ici
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onPostExecute(String result) {
List<String> userListOrderDone = new ArrayList<String>();
List<String> userListBeforOrder = new ArrayList<String>();
List<String> idList = new ArrayList<String>();
//Une fonction qui renvoie simplement ceci dans ExSample (je ne sais pas si cela a du sens)
Context context = ExSample.getInstance().getApplicationContext();
ArrayAdapter<String> beforUserList = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, userListBeforOrder);
ArrayAdapter<String> doneUserList = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, userListOrderDone);
Log.d(TAG, result);
titleView.setText("Motodeli");
beforUserContent.setText("Avant la livraison");
doneUserContent.setText("Livraison terminée");
beforUser.setAdapter(beforUserList);
doneUser.setAdapter(doneUserList);
try{
//Obtenez toutes les réponses avec JSONArray
JSONArray all = new JSONArray(result);
dataList = new ArrayList<Map<String, String>>();
for(int i = 0; i < all.length(); i++){
data = new HashMap<String, String>();
//Vous pouvez obtenir chaque valeur souhaitée
JSONObject json = all.getJSONObject(i);
String email = json.getString("user");
String total = json.getString("total");
String status = json.getString("status");
String id = json.getString("id");
//Juger s'il a été livré ou livré en fonction de la condition de l'utilisateur (une image que de nombreux débutants sont accros à la comparaison de chaînes de caractères Java)
if(status.equals("true")){
data.put("text1", email);
data.put("text2", id);
dataList.add(data);
}
else{
userListOrderDone.add(String.format("%s: %s yen", email, total));
}
}
}
catch (JSONException e){
System.out.println(e);
}
//Entrez la valeur basée sur les données extraites précédemment
adapter = new ListAndView(
context,
dataList,
R.layout.row,
new String[] {
"text1",
"text2",
},
new int[] {
android.R.id.text1,
android.R.id.text2,
});
//Reflété dans la vue de liste
listView.setAdapter(adapter);
listView.setTextFilterEnabled(false);
}
}
AsyncHttpRequestPost.java
package es.exsample;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class AsyncHttpRequestPost extends AsyncTask<String, Void, String> {
private static final String TAG = "AsyncHttpRequestPost";
private TextView textView;
public AsyncHttpRequestPost(Context context) {
super();
}
@Override
protected String doInBackground(String... params) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
HttpsURLConnection connection = null;
try {
//Définissez la chaîne URL.
URL url = new URL(params[0]);
connection = (HttpsURLConnection)url.openConnection();
connection.setConnectTimeout(3000); //Timeout 3 secondes
connection.setReadTimeout(3000);
// POST
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo2LCJ1c2VybmFtZSI6ImIxODA2NDI5QHBsYW5ldC5rYW5hemF3YS1pdC5hYy5qcCIsImV4cCI6MTU5NTIzMTIzNiwiZW1haWwiOiJiMTgwNjQyOUBwbGFuZXQua2FuYXphd2EtaXQuYWMuanAifQ.18LotiLgemUmSXTqmdcjjD3eKLSL1B13N87msbQswoE");
OutputStream outputStream = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
writer.write(params[1]);
writer.close();
connection.connect();
//Code de réponse.
int responseCode = connection.getResponseCode();
if(responseCode != HttpsURLConnection.HTTP_OK) {
throw new IOException("HTTP responseCode: " + responseCode);
}
//Stringification
inputStream = connection.getInputStream();
if(inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(connection != null) {
connection.disconnect();
}
}
return sb.toString();
}
}
ListAndView.java
package es.exsample;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.content.ContentValues.TAG;
public class ListAndView extends SimpleAdapter {
private LayoutInflater inflater;
private List<? extends Map<String, ?>> listData;
//Classe de conservation des données détenue par chaque ligne
public class ViewHolder {
TextView text1;
TextView text2;
}
public ListAndView(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.listData = data;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
//Recevoir une vue
View view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.row, parent, false);
holder = new ViewHolder();
holder.text1 = (TextView) view.findViewById(android.R.id.text1);
holder.text2 = (TextView) view.findViewById(android.R.id.text2);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
//Définir les données dans le support
String text1 = ((HashMap<?, ?>) listData.get(position)).get("text1").toString();
String text2 = ((HashMap<?, ?>) listData.get(position)).get("text2").toString();
holder.text1.setText(text1);
holder.text2.setText(text2);
//Exécuter lorsque vous appuyez sur le bouton
Button btn = (Button) view.findViewById(R.id.rowbutton);
btn.setTag(position);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
String id = holder.text2.getText().toString();
Context context = ExSample.getInstance().getApplicationContext();
AsyncHttpRequestPost task = new AsyncHttpRequestPost(context);
String url = "http://localhost:8000/post_shop/" + id;
task.execute(url, "hi");
Log.d(TAG, "created");
}
});
return view;
}
}
XML
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
card_view:cardBackgroundColor="#ffffff"
card_view:cardCornerRadius="7dp"
card_view:cardElevation="5dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="1542dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="24sp"
card_view:layout_constraintBottom_toBottomOf="parent"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintHorizontal_bias="0.498"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toTopOf="parent"
card_view:layout_constraintVertical_bias="0.01"
/>
<TextView
android:id="@+id/befor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="TextView"
card_view:layout_constraintTop_toBottomOf="@+id/title"
tools:layout_editor_absoluteX="189dp"
/>
<ListView
android:id="@+id/beforUser"
android:layout_width="402dp"
android:layout_height="130dp"
android:background="#7A7A7A"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toBottomOf="@+id/befor" />
<TextView
android:id="@+id/done"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView"
card_view:layout_constraintTop_toBottomOf="@+id/beforUser"
tools:layout_editor_absoluteX="189dp" />
<ListView
android:id="@+id/doneUser"
android:layout_width="402dp"
android:layout_height="364dp"
android:layout_marginTop="12dp"
android:background="#777777"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toBottomOf="@+id/done" />
<TextView
android:id="@+id/tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:text="TextView"
card_view:layout_constraintTop_toBottomOf="@+id/doneUser"
tools:layout_editor_absoluteX="98dp" />
<TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="60dp"
android:text="TextView"
card_view:layout_constraintStart_toEndOf="@+id/tag"
card_view:layout_constraintTop_toBottomOf="@+id/doneUser" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
row.xml --Faire le contenu de chaque liste
row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
tools:ignore="MissingConstraints">
<TextView
android:id="@android:id/text1"
android:layout_width="278dp"
android:layout_height="80dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="Text1"
android:textSize="18dp" />
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical|right"
android:text="Text2"
android:textSize="18dp" />
<Button
android:id="@+id/rowbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Livré!" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
C'est un peu compliqué, mais j'espère que vous pourrez réellement le copier et l'utiliser!
--Création d'une fonction pour informer l'administrateur lorsque la livraison est terminée. --Lorsque vous appuyez sur le bouton AsyncHttpRequestPost, le processus passe à ce point de terminaison, vidant le panier de l'utilisateur propriétaire du panier sélectionné et sautant le courrier. (La partie courrier est omise)
shop/views.py
######
###réduction###
#Ajoutez ce qui suit
from rest_framework.decorators import api_view
@api_view(['POST'])
def order_done_post_request(request, pk):
user_info = UserInfomation.objects.get(id=pk)
user = User.objects.get(email=user_info)
if request.method == 'POST':
cart = Cart.objects.get(cart_id=user_info.cart.cart_id)
order_done(request, str(cart))
user = user_info
#La gestion du panier est implémentée en entrant une valeur négative au lieu d'une suppression logique (mystère)
cart.cart_id = -cart.cart_id
user.status = None
cart.save()
user.save()
return Response(None) #Vous n'avez rien à retourner
###réduction###
Spécifiez l'ID du panier en spécifiant le type int pk
shop/urls.py
urlpatterns = [
###réduction###
path('post_shop/<int:pk>', views.order_done_post_request,), #ajouter à
]
Ce qui précède est le contenu que j'ai travaillé dur pour mettre en œuvre un jour après la relance d'Android Studio. Lorsque j'ai essayé d'écrire un article de cette manière, le nombre de phrases est devenu très important, même si de nombreuses parties ont été omises.
Il faut une journée pour créer une application aussi simple et la construction de l'environnement est délicate, les ingénieurs sont donc impressionnés à chaque fois. Cette fois, c'était Android, mais j'aimerais bientôt commencer à travailler sur iOS. C'est impossible à moins d'acheter un nouvel ordinateur. C'est un article assez compliqué, donc si vous avez des questions, envoyez-les dans les commentaires ou dans le DM sur Twitter et nous vous répondrons! Après cela, veuillez commenter s'il y a des erreurs ou des omissions!
Bonnes vacances d'été pour tous les étudiants! !! !!
Recommended Posts