Android进阶:4、发送一个get网络请求

安卓也是具有网络编程这一板块的,我们先从线程通讯说起,因为安卓自4.0之后就有一个特性,就是主线程不可以发送网络请求,而子线程不可以更新界面,所以我们想要学会网络编程,必须先掌握线程之间的通讯;

1、handler:

这个是主线程和子线程通讯的媒介,之前我们在制作轮播图的时候用到过这个,可以用它来定时,定时的发送一条信息给主线程,然后主线程根据信息的类型来更新界面:

    /*hanlder= MyHanlder(WeakReference(this))*/
    //1.3 非静态内部类:使用WeakReference防止内存泄漏
    private class MyHanlder(var wk:WeakReference<MainActivity>):Handler(Looper.getMainLooper()){
    
    

        override fun handleMessage(msg: Message) {
    
    
            super.handleMessage(msg)
            var activity = wk.get()
           if(activity!=null){
    
    
                if(msg.what==0){
    
    
                    activity.count++
                    activity.tv_count.setText(activity.count.toString())
                }else if(msg.what==1){
    
    
                    activity.isback=false
                }
            }
        }
    }

在kotlin中,我们可以这样创建一个自己的handler的内部类,因为直接使用handler虽然方便,但是有一个问题就是会导致内存泄漏,handler会默认隐式引用activity,在我们关闭了项目之后并不会被销毁,所以我们就是用了弱引用(WeakReference),只要是通过这个对象引用过得对象,在销毁了引用对象之后,也就是这里的mainactivity,就会被回收,所以不会导致内存泄露;注意这里的写法,我们通过get()可以拿到隐式引用的activity对象,就可以对里面的属性进行更新;但是要判断一下是否为null值

2、线程thread

一般我们创建一个子线程可以这样:

 Thread(){
    
    

            while(flag){
    
    
                Thread.sleep(1000)

                message.what=0
                myHanlder.sendEmptyMessage(0)
            }

        }.start()

当然也可以使用实现Runnable接口的方法;

3、发送get请求

安卓提供了两种发送请求的方式:一个是HttpURLConnection对象,一个是HttpClient(但是这种已经被淘汰了),我们就学习一下HttpURLConnection是如何发送请求的,之前我们说过,我们发送请求只能在子线程,所以我们要创建一个子线程,但是我们需要修改一些配置,因为默认andorid studio 是不允许发送请求的,我们需要在清单文件中添加上这两句:2

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.hanlderpractice">

//允许发送网络请求
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application

        //允许发送纯文本
        android:usesCleartextTraffic="true"
    
    </application>

</manifest>

加上去之后我们再写我们的代码

1、创建URL:

 var httpurl: String = "http://10.0.2.2:5000/api/user/" + parame1
 var url: URL = URL(httpurl)
 var conn: HttpURLConnection = url.openConnection() as HttpURLConnection

我们创建一个字符串,这是我们的网址,然后使用URL封装成一个请求对象,调用他的函数openConnection并且将返回值强转为一个

HttpURLConnection对象,然后我们就可以将请求过来的数据存储下来:

 conn.requestMethod = "GET"
conn.connectTimeout = 5000
conn.readTimeout = 5000
var code: Int = conn.responseCode
if (code == 200) {
    
    
    var inputStream: InputStream = conn.inputStream
    var byteArray: ByteArray = ByteArray(1024)
    var length: Int
    var result: String = ""

    inputStream.use {
    
    
        length = it.read(byteArray)
        result = String(byteArray)
        Log.d(TAG, "$result: ")
    }
    inputStream.close()
}

然后设置一下访问超时时间和阅读超时时间,返回码,我们使用这个返回的请求码判断是否为200,这是请求成功的代码,然后创建一个输入流对象,我们就使用这个输入流将请求下来的数据存储到二进制数组中,然后通过日志打印出来就可以了;最后不要忘了关闭这个流;

2、创建子线程,然后在单击事件里面启动


class HttpPractice : AppCompatActivity() {

    lateinit var thread: Thread
    lateinit var parame1: String

    companion object {
        private const val TAG = "HttpPractice"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_http_practice)
        //1.1 创建子线程用来发送请求
        parame1 = "[email protected]"
        thread = Thread {
            var httpurl: String = "http://10.0.2.2:5000/api/user/" + parame1
            var url: URL = URL(httpurl)
            var conn: HttpURLConnection = url.openConnection() as HttpURLConnection
            conn.requestMethod = "GET"
            conn.connectTimeout = 5000
            conn.readTimeout = 5000
            var code: Int = conn.responseCode
            if (code == 200) {
                var inputStream: InputStream = conn.inputStream
                var byteArray: ByteArray = ByteArray(1024)
                var length: Int
                var result: String = ""

                inputStream.use {
                    length = it.read(byteArray)
                    result = String(byteArray)
                    Log.d(TAG, "$result: ")
                }
                inputStream.close()
            }

        }

    }



    fun sendget(view: View) {
        //2.1 发送请求,启动线程

        thread.start()


    }
}

如果是要带参数的get也很容易,我们这里也是使用了,就是在后面拼接上一个变量,填上我们想要的传递的参数就是了;

对了大家发送请求的时候window是访问本机的127.0.0.1得80端口,但是在安卓中不一样,我们访问的是10.0.2.2的5000端口,而且我们还得在本机启动一个服务器才行,大家如果没有本地服务器的话可以去我的公众号:代码栈回复安卓本地服务器拿取我们这个使用的服务器;

在这里插入图片描述
拿到文件,里面有一个叫做webapi的东西,还有一个PDF的文档,就是这个本地服务器的所有接口以及会返回的数据,我们参考这个文档就可以访问各种接口;
这里直接点击webapi.exe就可以启动了;
在这里插入图片描述

还有就是postman的使用,我们可以使用这个软件测试请求的结果,就是可以看到访问的URL返回的数据:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/aiwanchengxu/article/details/127628056
今日推荐