A3 网络通信

1.线程

1.1阐述

  • 故名思意,线程就是用来执行一直耗时操作的代码段
  • 在android中,与用户交互的线程不能执行耗时操作,否则显示会出现卡顿,不利于人机交互体验

1.2线程创建方法

  • 需求:在主界面中有一个按钮,当按钮按下后,会在后台每隔1s打印一条信息.而与用户交互的线程不受影响
  • 首先设计主界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Button"
        tools:layout_editor_absoluteX="202dp"
        tools:layout_editor_absoluteY="124dp" />

</LinearLayout>
  • 主代码
package com.example.testthread;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //创建一个匿名线程类
                new Thread(){
                    @Override
                    //线程执行方法
                    public void run() {
                        //异常捕获
                        try {
                            //后台一直打印信息
                            while (true){
                                Thread.sleep(1000);
                                System.out.println("------Tick------");
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        super.run();
                    }
                }.start();
            }
        });
    }
}

2.AsyncTask用法

2.1概念

  • AsyncTask是android提供的一个轻量级的异步操作类,可在类中实现异步操作并与UI进程通信

2.2AsyncTask使用方法

  • 需求:在主界面创建一个按钮,当点击按钮的时候会在下方显示网页内容
  • 主界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Button"
        tools:layout_editor_absoluteX="202dp"
        tools:layout_editor_absoluteY="124dp" />

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



</LinearLayout>
  • 代码
package com.example.testthread;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MainActivity extends AppCompatActivity {
    TextView text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = findViewById(R.id.textView);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //调用自定义函数获取网页数据
                ReadURL("http://www.baidu.com");
            }
        });
    }
    @SuppressLint("StaticFieldLeak")
    public void ReadURL(String URL){
        //使用AsyncTask获取网络数据
        new AsyncTask<String, Float, String>(){
            @Override
            //后台执行的部分(耗时操作)
            protected String doInBackground(String... strings) {
                try {
                    //获取URL参数
                    URL url = new URL(strings[0]);
                    try {
                        URLConnection connection = url.openConnection();
                        long total = connection.getContentLength();         //获取总长度
                        InputStream inputStream = connection.getInputStream();
                        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                        String line;
                        StringBuilder builder = new StringBuilder();
                        while ((line = bufferedReader.readLine()) != null){
                            builder.append(line);
                            publishProgress((float)builder.toString().length()/total);  //发布进度
                        }
                        bufferedReader.close();
                        inputStream.close();
                        return builder.toString();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onProgressUpdate(Float... values) {
                System.out.println(values[0]);      //向外发布任务进度
                super.onProgressUpdate(values);
            }

            @Override
            //任务执行入口
            protected void onPreExecute() {
                Toast.makeText(MainActivity.this, "开始读取", Toast.LENGTH_SHORT).show();
                super.onPreExecute();
            }
            @Override
            //任务执行结果
            protected void onPostExecute(String s) {
                text.setText(s);
                super.onPostExecute(s);
            }
        }.execute(URL);
    }
}
  • 注意要在AndroidManifest添加网络权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testthread">

    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.TestThread">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

3.Http

3.1GET获取网络数据

  • 此处我们向有道发送一个get请求
  • 主界面设计如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="读取数据"
        tools:layout_editor_absoluteX="137dp"
        tools:layout_editor_absoluteY="144dp" />

</LinearLayout>
  • 程序
package com.example.httpget;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @SuppressLint("StaticFieldLeak")
            @Override
            public void onClick(View view) {
                new AsyncTask<String, Void, Void>(){
                    @Override
                    protected Void doInBackground(String... strings) {
                        try {
                            //创建URL对象
                            URL url = new URL(strings[0]);
                            //获取互联网连接
                            try {
                                URLConnection connection = url.openConnection();
                                InputStream inputStream = connection.getInputStream();
                                InputStreamReader isr = new InputStreamReader(inputStream, "utf-8");
                                BufferedReader br = new BufferedReader(isr);
                                String line;
                                while ((line = br.readLine()) != null){
                                    System.out.println(line);
                                }
                                br.close();
                                isr.close();
                                inputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                }.execute("http://fanyi.youdao.com/openapi.do?keyfrom=<keyfrom>&key=<key>&type=data&doctype=json&version=1.1&q=good");
            }
        });
    }
}
  • 权限申请
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.httpget">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.HttpGET">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
  • 执行结果,后台打印了json数据
11-08 11:29:47.142 1875-1895/com.example.httpget I/System.out: {"query":"good","errorCode":50}
...
11-08 11:29:49.012 1875-1896/com.example.httpget I/System.out: {"query":"good","errorCode":50}

3.2POST方式

  • 大体框架跟上面的一样,只是主代码发送了改变
package com.example.httpget;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @SuppressLint("StaticFieldLeak")
            @Override
            public void onClick(View view) {
                new AsyncTask<String, Void, Void>(){
                    @Override
                    protected Void doInBackground(String... strings) {
                        try {
                            //创建URL对象
                            URL url = new URL(strings[0]);
                            //获取互联网连接
                            try {
                                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//                                URLConnection connection = url.openConnection();

                                connection.setDoInput(true);
                                connection.setDoOutput(true);
                                connection.setRequestMethod("POST");

                                OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream(), "utf-8");
                                BufferedWriter bw = new BufferedWriter(osw);
                                bw.write("keyfrom=<keyfrom>&key=<key>&type=data&doctype=json&version=1.1&q=good");
                                bw.flush();

                                InputStream inputStream = connection.getInputStream();
                                InputStreamReader isr = new InputStreamReader(inputStream, "utf-8");
                                BufferedReader br = new BufferedReader(isr);
                                String line;
                                while ((line = br.readLine()) != null){
                                    System.out.println(line);
                                }
                                br.close();
                                isr.close();
                                inputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                }.execute("http://fanyi.youdao.com/openapi.do");
            }
        });
    }
}

4.Socket通信

4.1

posted @ 2021-08-03 00:12  MHDSG  阅读(69)  评论(0)    收藏  举报