Getting started with Android (15) | Network


WebView

WebView can display some web pages in the application (instead of the browser).

layout file web_layout.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

Activity file:

public class WebActivity extends AppCompatActivity {
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web_layout);

        WebView webView = findViewById(R.id.web_view);
        // 使WebView支持JavaScript脚本
        webView.getSettings().setJavaScriptEnabled(true);
        // 用当前WebView显示网页而不是浏览器
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl("https://www.bilibili.com/");
    }
}

To use network technology in Android, you need to declare permissions AndroidManifest.xmlin :

<uses-permission android:name="android.permission.INTERNET" />

operation result:
insert image description here


HTTP

Use HttpURLConnection

layout file http_layout.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button_sendRequest"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送请求"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/response_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </ScrollView>

</LinearLayout>
  • ScrollView Control: View off-screen content in a scrolling manner.
  • TextView control: used to display the data returned by the server.

Activity file:

public class HTTPActivity extends AppCompatActivity {
    
    
    private static final String TAG = "HTTPActivity";
    TextView responseText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.http_layout);

        Button button_sendRequest = findViewById(R.id.button_sendRequest);
        responseText = findViewById(R.id.response_text);
        button_sendRequest.setOnClickListener(v->{
    
    
            sendRequestWithHttpURLConnection();
            Log.e(TAG, "click over");
        });
    }

    private void sendRequestWithHttpURLConnection() {
    
    
        // 开启子线程来发起网络请求
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
    
    
                    URL url = new URL("https://www.csdn.net/");

                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);

                    InputStream in = connection.getInputStream();
                    Log.e(TAG, "get in");
                    // 下面对获取到的输入流进行读取
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while((line = reader.readLine()) != null){
    
    
                        response.append(line);
                    }
                    Log.e(TAG, "run: "+response.toString());

                    // 安卓不允许在子线程中进行UI操作
                    // 通过runOnUiThread切换为主线程,然后将结果显示到界面中
                    runOnUiThread(new Runnable() {
    
    
                        @Override
                        public void run() {
    
    
                            responseText.setText(response.toString());
                        }
                    });
                } catch (Exception e) {
    
    
                    e.printStackTrace();
                } finally {
    
    
                    if(reader != null){
    
    
                        try {
    
    
                            reader.close();
                        } catch (IOException e){
    
    
                            e.printStackTrace();
                        }
                    }
                    if(connection != null){
    
    
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
}

operation result:
insert image description here


Use OkHttp

The home page address of the OkHttp project on github

Add dependencies in build.gradle (:app)the file :dependencies

	// define a BOM and its version
    implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3"))
    // define any required OkHttp artifacts without version
    implementation("com.squareup.okhttp3:okhttp")

Activity file:

public class HTTPActivity extends AppCompatActivity {
    
    
    private static final String TAG = "HTTPActivity";
    TextView responseText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.http_layout);

        Button button_sendRequest = findViewById(R.id.button_sendRequest);
        responseText = findViewById(R.id.response_text);
        button_sendRequest.setOnClickListener(v->{
    
    
            sendRequestWithOkHttp();
            Log.e(TAG, "click over");
        });
    }

    private void sendRequestWithOkHttp() {
    
    
        // 开启子线程来发起网络请求
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url("https://www.bilibili.com")
                            .build();
                    Log.e(TAG, "request: "+request);
                    Response response = client.newCall(request).execute();
                    Log.e(TAG, "response: "+response);
                    String responseData = response.body().string();
                    Log.e(TAG, "responseData: "+responseData);
                    runOnUiThread(new Runnable() {
    
    
                        @Override
                        public void run() {
    
    
                            responseText.setText(responseData);
                        }
                    });
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

operation result:
insert image description here


Encapsulate network operations

Encapsulate HttpURLConnection

It is undoubtedly cumbersome to implement the code for sending HTTP requests in every place where network functions are used. Therefore, it is advisable to write commonly used network operations as static methods and store them in a class, such as:

public class HttpUtil {
    
    
    private static final String TAG = "HttpUtil";

    public static String sendHttpRequest(String address){
    
    
        HttpURLConnection connection = null;
        try {
    
    
        	URL url =new URL(address);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(8000);
            connection.setReadTimeout(8000);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            InputStream in = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder response = new StringBuilder();
            String line;
            while((line = reader.readLine()) != null){
    
    
            	response.append(line);
            }
            return response.toString();
        } catch (Exception e) {
    
    
        	e.printStackTrace();
        	return e.getMessage();
        } finally {
    
    
            if(connection != null){
    
    
            	connection.disconnect();
            }
        }
    }
}

In this way, it can be implemented when an HTTP request needs to be sent:

String url = "https://www.bilibili.com";
String response = HttpUtil.sendHttpRequest(url);

But this still has flaws. The method does not use sub-threadssendHttpRequest() inside , which means that the main thread may be blocked when calling this method , and network requests are time-consuming operations, which is undoubtedly a disaster for operating efficiency.

And if you simply open a thread in sendHttpRequest()the method to initiate an HTTP request, then all the time-consuming logic is performed in the sub-thread, and the method will be executed before the serversendHttpRequest() has time to respond (in the sub-thread The logic has not been executed yet, and the call to the method has ended in the main thread ).sendHttpRequest()

Therefore, it should be equipped with a callback mechanism to accept feedback data and define an interface:

public interface HttpCallbackListener {
    
    
    // 成功响应时回调,参数为服务器返回的数据
    void onFinish(String response);
    // 操作错误时回调
    void onError(Exception e);
}

Then modify HttpUtil.java:

public class HttpUtil {
    
    
    private static final String TAG = "HttpUtil";

    public static void sendHttpRequest(final String address, HttpCallbackListener listener){
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                HttpURLConnection connection = null;
                try {
    
    
                    URL url =new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.setDoInput(true);
                    connection.setDoOutput(true);

                    InputStream in = connection.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while((line = reader.readLine()) != null){
    
    
                        response.append(line);
                    }
                    
                    // 子线程中无法通过 return 返回数据,应通过 onFinish 方法回调
                    if(listener != null){
    
    
                        listener.onFinish(response.toString());
                        Log.e(TAG, "run: "+response.toString());
                    }
                } catch (Exception e) {
    
    
                    if(listener != null){
    
    
                        listener.onError(e);
                        Log.e(TAG, "run: Exception");
                    }
                } finally {
    
    
                    if(connection != null){
    
    
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
}

At this point, when we call sendHttpRequest()the method we need to pass in the instance of HttpCallbackListener :

    private void sendRequestWithOkHttp() {
    
    
        // 开启子线程来发起网络请求
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                String url = "https://www.baidu.com";
                HttpUtil.sendHttpRequest(url, new HttpCallbackListener() {
    
    
                    @Override
                    public void onFinish(String response) {
    
    
                        runOnUiThread(new Runnable() {
    
    
                            @Override
                            public void run() {
    
    
                                responseText.setText(response);
                            }
                        });

                    }

                    @Override
                    public void onError(Exception e) {
    
    
                        Log.e(TAG, "onError: "+e);
                    }
                });
            }
        }).start();
    }

operation result:
insert image description here


Package OkHttp

Encapsulate operations on HTTP:

public class HttpUtil {
    
    
    private static final String TAG = "HttpUtil";

    public static void sendHttpRequest(final String address, okhttp3.Callback callback){
    
    
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        Log.e(TAG, "request: "+request);
        client.newCall(request).enqueue(callback);
    }
}

Call the method that HttpUtil.sendHttpRequest()sends the request:

    // 开启子线程来发起网络请求,OkHttp
    private void sendRequestWithOkHttp(){
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                HttpUtil.sendHttpRequest("https://www.bilibili.com", new okhttp3.Callback(){
    
    

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
    
    
                        String responseData = response.body().string();
                        runOnUiThread(new Runnable() {
    
    
                            @Override
                            public void run() {
    
    
                                responseText.setText(responseData);
                            }
                        });
                    }

                    @Override
                    public void onFailure(Call call, IOException e) {
    
    
                        Log.e(TAG, "onError: "+e);
                    }
                });
            }
        }).start();
    }

PS: Whether using HttpURLConnection or OkHttp , the final callback interface is still in the child thread, so if you want to perform UI operations, you must use runOnUiThread()the method to perform thread conversion.

operation result:
insert image description here

Guess you like

Origin blog.csdn.net/Jormungand_V/article/details/123319755