📌  相关文章
📜  如何使用 Flask 后端构建一个简单的 Android 应用程序?

📅  最后修改于: 2022-05-13 01:55:19.521000             🧑  作者: Mango

如何使用 Flask 后端构建一个简单的 Android 应用程序?

Flask 是Python的 API,它允许我们构建 Web 应用程序。它是由 Armin Ronacher 开发的。 Flask 的框架比 Django 的框架更明确,也更容易学习,因为它实现一个简单的 web 应用程序的基础代码更少。 Web-Application Framework 或 Web Framework 是模块和库的集合,可帮助开发人员编写应用程序,而无需编写协议、线程管理等低级代码。 Flask 基于 WSGI(Web 服务器网关接口)工具包和 Jinja2 模板引擎。下面的文章将演示如何在开发 Android 应用程序时将 Flask 用于后端。

分步实施

第一步:安装烧瓶

打开终端输入以下命令安装flask

pip install flask

第二步:在build.gradle文件中添加OkHttp依赖

OkHttp 是 Square 开发的用于发送和接收基于 HTTP 的网络请求的库。为了在 Android 应用程序中发出 HTTP 请求,我们使用 OkHttp。该库用于进行同步和异步调用。如果网络调用是同步的,则代码将等待我们从尝试与之通信的服务器获得响应。这可能会导致延迟或性能滞后。如果网络调用是异步的,则执行不会等到服务器响应,应用程序才会运行,如果服务器响应,将执行回调。



安卓依赖

在 Android Studio 的 build.gradle 文件中添加以下依赖

implementation("com.squareup.okhttp3:okhttp:4.9.0")

第 3 步:使用 AndroidManifest.XML 文件

标签上方添加以下行

标签内添加以下行

android:usesCleartextTraffic="true">

第 4 步: Python脚本

  • @app.route(“/”) 与 showHomePage()函数相关联。假设服务器运行在一个 IP 地址为 192.168.0.113,端口号为 5000 的系统上。现在,如果在浏览器中输入 URL“http://192.168.0.113:5000/”,将执行 showHomePage函数,它将返回响应“这是主页”。
  • app.run() 将在本地主机上托管服务器,而 app.run(host=”0.0.0.0″) 将在机器的 IP 地址上托管服务器
  • 默认情况下将使用端口 5000,我们可以使用 app.run() 中的 'port' 参数更改它
Python
from flask import Flask
  
# Flask Constructor
app = Flask(__name__)
  
# decorator to associate 
# a function with the url
@app.route("/")
def showHomePage():
      # response from the server
    return "This is home page"
  
if __name__ == "__main__":
  app.run(host="0.0.0.0")


XML


  
    
      


Java
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
  
import androidx.appcompat.app.AppCompatActivity;
  
import org.jetbrains.annotations.NotNull;
  
import java.io.IOException;
  
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
  
public class MainActivity extends AppCompatActivity {
      
    // declare attribute for textview
    private TextView pagenameTextView;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pagenameTextView = findViewById(R.id.pagename);
  
        // creating a client
        OkHttpClient okHttpClient = new OkHttpClient();
  
        // building a request
        Request request = new Request.Builder().url("http://192.168.0.113:5000/").build();
  
        // making call asynchronously
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            // called if server is unreachable
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "server down", Toast.LENGTH_SHORT).show();
                        pagenameTextView.setText("error connecting to the server");
                    }
                });
            }
  
            @Override
            // called if we get a 
            // response from the server
            public void onResponse(
                    @NotNull Call call,
                    @NotNull Response response)
                    throws IOException {pagenameTextView.setText(response.body().string());
            }
        });
    }
}


Python
from flask import Flask
  
# import request
from flask import request
app = Flask(__name__)
  
@app.route("/")
def showHomePage():
    return "This is home page"
  
@app.route("/debug", methods=["POST"])
def debug():
    text = request.form["sample"]
    print(text)
    return "received"  
    
if __name__ == "__main__":
  app.run(host="0.0.0.0")


XML


  
    
  
    


Java
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
  
import androidx.appcompat.app.AppCompatActivity;
  
import org.jetbrains.annotations.NotNull;
  
import java.io.IOException;
  
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
  
public class DummyActivity extends AppCompatActivity {
  
    private EditText editText;
    private Button button;
    private OkHttpClient okHttpClient;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dummy);
        editText = findViewById(R.id.dummy_text);
        button = findViewById(R.id.dummy_send);
        okHttpClient = new OkHttpClient();
  
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                  
                String dummyText = editText.getText().toString();
  
                // we add the information we want to send in
                // a form. each string we want to send should
                // have a name. in our case we sent the
                // dummyText with a name 'sample'
                RequestBody formbody
                        = new FormBody.Builder()
                        .add("sample", dummyText)
                        .build();
  
                // while building request
                // we give our form
                // as a parameter to post()
                Request request = new Request.Builder().url("http://192.168.0.113:5000/debug")
                        .post(formbody)
                        .build();
                okHttpClient.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(
                            @NotNull Call call,
                            @NotNull IOException e) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getApplicationContext(), "server down", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
  
                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                        if (response.body().string().equals("received")) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(getApplicationContext(), "data recieved", Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    }
                });
            }
        });
    }
}


运行Python脚本



运行Python脚本,服务器将被托管。

步骤 5:使用 activity_main.xml 文件

  • 创建一个约束布局。
  • 将 ID 为“pagename”的 TextView 添加到约束布局以显示来自服务器的响应
  • 因此,将以下代码添加到 android studio 的activity_main.xml文件中。

XML



  
    
      

第 6 步:使用MainActivity。 Java文件

转到主活动。 Java文件,参考如下代码。首先,我们需要一个 OkHttp Client 来发起请求

OkHttpClient okhttpclient = new OkHttpClient();

接下来,使用服务器的 URL 创建一个请求。在我们的例子中,它是“http://192.168.0.113:5000/”。注意 URL 末尾的“/”,我们正在发送对主页的请求。

Request request = new Request.Builder().url("http://192.168.0.113:5000/").build();

现在,使用上述请求进行调用。完整代码如下。如果服务器关闭或无法访问,将调用 onFailure(),因此我们在 TextView 中显示一个文本,说“服务器关闭”。如果请求成功,将调用 onResponse()。我们可以使用我们在 onResponse() 中收到的 Response 参数访问响应

// to access the response we get from the server
response.body().string; 

下面是MainActivity的代码。 Java文件。代码中添加了注释以更详细地理解代码。

Java



import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
  
import androidx.appcompat.app.AppCompatActivity;
  
import org.jetbrains.annotations.NotNull;
  
import java.io.IOException;
  
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
  
public class MainActivity extends AppCompatActivity {
      
    // declare attribute for textview
    private TextView pagenameTextView;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pagenameTextView = findViewById(R.id.pagename);
  
        // creating a client
        OkHttpClient okHttpClient = new OkHttpClient();
  
        // building a request
        Request request = new Request.Builder().url("http://192.168.0.113:5000/").build();
  
        // making call asynchronously
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            // called if server is unreachable
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "server down", Toast.LENGTH_SHORT).show();
                        pagenameTextView.setText("error connecting to the server");
                    }
                });
            }
  
            @Override
            // called if we get a 
            // response from the server
            public void onResponse(
                    @NotNull Call call,
                    @NotNull Response response)
                    throws IOException {pagenameTextView.setText(response.body().string());
            }
        });
    }
}

输出:

正在运行的安卓应用

第 7 步:检查在Python编辑器中发出的请求

如果发出请求,我们可以看到发出请求的设备的 IP 地址、发出请求的时间和请求类型(在我们的例子中请求类型是 GET)。

POST 请求

我们可以使用 okhttp 客户端通过服务器发送数据。将以下行添加到导入语句

from flask import request

我们需要将路由的方法设置为 POST。让我们添加一个方法并将路由关联到它。该方法将我们在android应用程序中输入的文本打印到pycharm中的控制台。在showHomePage()方法之后添加以下几行。

@app.route("/debug", methods=["POST"])
def debug():
    text = request.form["sample"]
    print(text)
    return "received"

完整的脚本如下

Python

from flask import Flask
  
# import request
from flask import request
app = Flask(__name__)
  
@app.route("/")
def showHomePage():
    return "This is home page"
  
@app.route("/debug", methods=["POST"])
def debug():
    text = request.form["sample"]
    print(text)
    return "received"  
    
if __name__ == "__main__":
  app.run(host="0.0.0.0")

创建一个虚拟活动。 Android Studio 中的Java 。一旦我们从服务器的showHomePage()方法得到响应,这个活动就会开始。在MainActivity 的onResponse() 回调中添加以下行。Java



Intent intent = new Intent(MainActivity.this, DummyActivity.class);
startActivity(intent);
finish();

步骤 1:使用 activity_dummy.xml 文件

  • 添加一个 ID 为 dummy_text 的 EditText。
  • 添加一个带有 id dummy_send 和文本“send”的按钮。

XML



  
    
  
    

第 2 步:使用 DummyActivity。 Java文件

  • 我们使用表单通过 OkHTTP 客户端发送数据。
  • 在构建我们的请求时,我们将此表单作为参数传递给 post()。
  • 添加一个 onClickListener() 以发出 POST 请求。
  • 如果数据被发送,并且我们得到了响应,我们会显示一个 toast 确认数据已被接收。

下面是DummyActivity的代码。 Java文件。代码中添加了注释以更详细地理解代码。

Java

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
  
import androidx.appcompat.app.AppCompatActivity;
  
import org.jetbrains.annotations.NotNull;
  
import java.io.IOException;
  
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
  
public class DummyActivity extends AppCompatActivity {
  
    private EditText editText;
    private Button button;
    private OkHttpClient okHttpClient;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dummy);
        editText = findViewById(R.id.dummy_text);
        button = findViewById(R.id.dummy_send);
        okHttpClient = new OkHttpClient();
  
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                  
                String dummyText = editText.getText().toString();
  
                // we add the information we want to send in
                // a form. each string we want to send should
                // have a name. in our case we sent the
                // dummyText with a name 'sample'
                RequestBody formbody
                        = new FormBody.Builder()
                        .add("sample", dummyText)
                        .build();
  
                // while building request
                // we give our form
                // as a parameter to post()
                Request request = new Request.Builder().url("http://192.168.0.113:5000/debug")
                        .post(formbody)
                        .build();
                okHttpClient.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(
                            @NotNull Call call,
                            @NotNull IOException e) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getApplicationContext(), "server down", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
  
                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                        if (response.body().string().equals("received")) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(getApplicationContext(), "data recieved", Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    }
                });
            }
        });
    }
}

输出:

检查 Flask 控制台

在这里我们可以看到 android 应用程序发出了一个 POST 请求。我们甚至可以看到我们通过服务器发送的数据