Android network programming

Keywords: Java Android

Chapter 9 network programming

Android system provides the following ways to realize network communication: Socket communication, HTTP communication, URL communication and WebView.

One of the most commonly used is HTTP communication. This chapter describes how to use HTTP protocol to communicate with the server on the mobile phone.

9.1 introduction to HTTP protocol

HTTP is the hypertext transfer protocol, which stipulates the communication rules between browser and server.

HTTP is a request / response protocol. After the client establishes a connection with the server segment, the request sent to the server is called HTTP request. After receiving the request, the server will respond, which is called HTTP response.

9.2 accessing the network

Android provides good support for HTTP communication. The URL based request and response functions can be realized through the standard java class HttpURLConnection. HttpURLConnection inherits from URLConnection. It can send and receive data of any type and length, and set the request mode. You can also set the request mode and timeout.

9.2.1 HttpURLConnection

URL url = new URL("http://itcast.cn "); / / get the url object to access the resource
HttpURLConnection conn = (HttpURLConnection) url.openConnection();//Get connection
conn.setRequestMethod("GET");//Set request mode
conn.setConnectTimeout(5000);//Set timeout
InputStream is = conn.getInputStream();//Gets the input stream returned by the server
conn.disconnect();//Close connection

The above demonstrates the process of establishing a connection with the server and obtaining the data returned by the server. It should be noted that when using the HttpURLConnection object to access the network, you need to set the timeout time to prevent no response when the connection is blocked and affect the user experience.

9.2.2 GET and POST request methods

Request method refers to different ways of requesting specified resources.

  1. Submit data in GET mode

    GET method is to obtain the resource information pointed to by the request URL in the form of entity, and the parameters submitted to the server follow the request URL. The length of accessing the network URL using GET method is generally less than 1KB.

  2. When sending a request through POST, you need to attach an entity after the request. The parameters it submits to the server are in the entity after the request. POST has no limit on the length of the URL. When using POST, the request parameters follow the request entity. Users cannot see the request parameters submitted to the server in the browser, so POST is safer than GET.

    String path = "http://192.168.1.100:8080/web/LoginServlet";
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setRequestMethod("POST");
            //Prepare data and code parameters
            String data = "username = "+ URLEncoder.encode("zhangsan")+"&password="+URLEncoder.encode("123");
            //Set the submission method of request header data. Here, it is submitted in form form
            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            //Set the length of the submitted data
            conn.setRequestProperty("Content-Length",data.length()+"");
            //In the post mode, the browser actually writes the data to the server
            conn.setDoOutput(true); //Setting allows data to be written out
            OutputStream os = conn.getOutputStream();
            os.write(data.getBytes()); //Write parameters to the server
            int code = conn.getResponseCode();
            if(code == 200) {
                InputStream is = conn.getInputStream();
            }
    

    Note: submitting Chinese is prone to garbled code. Be sure to pay attention to the matching of encoding method and decoding method

9.2.3 handler message mechanism

When the program starts, Android will first start a UI thread (main thread) , the UI thread is responsible for managing the controls of the UI interface and distributing events. For example, when you click the Button of the UI interface, Android will distribute events to the Button to respond to the operations to be performed. If you perform time-consuming operations, such as accessing the network, reading data, and returning the obtained results to the UI interface, a false death will occur. If 5s has not been completed, it will be received At this time, beginners will think of putting those operations into the sub thread to complete, but in Android, updating the UI interface can only be completed in the main thread, and other threads cannot operate directly on the main thread.

In order to solve the above problems, Android provides an asynchronous callback mechanism Handler, which is responsible for communicating with the main thread. Generally, the Handler object is bound in the main thread, and a sub thread is created above the event trigger to complete some time-consuming operations. When the work in the sub thread is completed, a completed signal will be sent to the Handler (Message object). When the Handler receives the signal, it will update the mainline UI.

The Handler mechanism mainly includes four key objects: Message, Handler, MessageQueue and Looper. These four key objects are briefly introduced below.

  1. Message

    Message is a message passed between threads. It can carry a small amount of information internally to exchange information between different threads. The what field of Meessage can be used to carry some integer data, and the obj field can be used to carry an Object object.

  2. Handler

    Handler means handler. It is mainly used to send and process messages. Generally, the sendMessage method of handler object is used to send messages. After a series of processing, the sent messages will eventually be delivered to the handlerMessage method of handler object.

  3. MessageQueue

    MessageQueue means message queue. It is mainly used to store messages sent through Handler. Messages sent through Handler will be stored in MessageQueue for processing, and each thread has only one MessageQueue object.

  4. Looper

    Looper is the steward of MessageQueue in each thread. After calling Looper's loop method, it will enter an infinite loop. Whenever a message is found in MessageQueue, it will be taken out and passed to the Handler's handlerMessage method. In addition, each thread will only have one looper object. When the Handler object is created in the mainline, the system already exists by default The Handler object in the child thread needs to call the loop.loop method to start the message loop.

9.2.4 actual combat drill -- Web Image Browser

  1. Create program

    Create an ImageView program, and the layout code is as follows:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/line1"
                android:orientation="horizontal"
                android:layout_marginTop="5dp">
                <EditText
                    android:layout_width="0dp"
                    android:layout_weight="5"
                    android:layout_height="wrap_content"
                    android:id="@+id/et1"
                    android:hint="Please enter a path"></EditText>
                <Button
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="wrap_content"
                    android:text="browse"
                    android:textSize="19sp"
                    android:id="@+id/bt1"
                    android:onClick="click"></Button>
            </LinearLayout>
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@+id/line1">
                
            </ImageView>
        </RelativeLayout>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
  2. Write interface interaction code

    Use HttpURLConnection to obtain the network picture of the specified address and display the picture returned by the server on the interface. The code is as follows:

    package cn.luoxin88.imageview;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    public class MainActivity extends AppCompatActivity {
    
        protected static final int CHANGE_UI = 1;
        protected static final int ERROR = 2;
        private static final int REQUEST_CODE_ASK_PERMISSIONS = 123;
        private static EditText et;
        private static ImageView iv;
        //The main thread creates a message handler
        private static Handler handler = new Handler() {
            public void handlerMessage(android.os.Message msg) {
                if(msg.what == CHANGE_UI){
                    Bitmap bitmap = (Bitmap)msg.obj;
                    iv.setImageBitmap(bitmap);
                }
                else if(msg.what == ERROR) {
                    // Toast.makeText(MainActivity.this, "error displaying picture", Toast.LENGTH_SHORT).show();
                }
            }
        };
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            et = (EditText)findViewById(R.id.et1);
            iv = (ImageView) findViewById(R.id.iv1);
        }
        public void click(View view) {
            final String path = et.getText().toString().trim();
            if(TextUtils.isEmpty(path)) {
                Toast.makeText(this,"Picture path cannot be empty",Toast.LENGTH_SHORT).show();
            }
            else {
                System.out.println(path);
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                    int hasReadSmsPermission = checkSelfPermission(Manifest.permission.INTERNET);
                    if (hasReadSmsPermission != PackageManager.PERMISSION_GRANTED) {
                        requestPermissions(new String[]{Manifest.permission.READ_SMS}, REQUEST_CODE_ASK_PERMISSIONS);
                        return;
                    }
                }
                System.out.println(1);
                //The sub thread accesses the network. The network access after Android 4.0 cannot be placed on the main thread
                new Thread() {
                    private HttpURLConnection conn;
                    private Bitmap bitmap;
                    public void run() {
                        //Connect to the server GET request to GET pictures
                        try {
                            URL url = new URL(path);
                            conn = (HttpURLConnection) url.openConnection();
                            conn.setRequestMethod("GET");
                            conn.setConnectTimeout(5000);
                            int code = conn.getResponseCode();
                            System.out.println(code);
                            if(code == 200) {
                                InputStream is = conn.getInputStream();
                                //Convert stream to Bitmap object
                                bitmap = BitmapFactory.decodeStream(is);
                                //Send the message of changing the main interface to the main thread
                                Message message = new Message();
                                message.what = CHANGE_UI;
                                message.obj = bitmap;
                                handler.sendMessage(message);
                            }
                            else {
                                //Request server failed
                                Message msg = new Message();
                                msg.what = ERROR;
                                handler.sendMessage(msg);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            Message msg = new Message();
                            msg.what = ERROR;
                            handler.sendMessage(msg);
    
                        }
                        conn.disconnect();
                    }
                }.start();
            }
        }
    }
    
    
  3. add permission

    Because the network picture needs to access the network, you need to configure the Internet permission in the Manifest file

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

    input https://www.photophoto.cn/m6/018/030/0180300388

Posted by n00854180t on Fri, 26 Nov 2021 09:12:19 -0800