android网络编程多线程,安卓网络编程实例

在实验的安卓界面完成后,下一步就是对接后台了。在实际的应用中,通常需要从后台接口中获取或修改数据库数据,展示在安卓界面中。为了完成这样的功能,学习了安卓的网络编程实例。

使用网络获取数据

使用网络技术也很简单,无非是发送http请求并解析返回数据,在这里使用了android的网络通信库OkHttp,它能更加简化网络请求的步骤。

首先在app/build.gradle文件中声明OkHttp依赖:

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

在AndroidMainfest.xml中声明网络权限:

创建一个OkHttpClient对象,再创建一个request请求发起一个http请求:

OkHttpClient okHttpClient = new OkHttpClient();

Request request = new Request.Builder().url("http://192.168.2.234:8080/city").build();

Response response = okHttpClient.newCall(request).execute();

其中返回来的json数据,可以从response.string()中获取到返回流的json字符串,再用相应的json解析工具,类似gson解析json就可以获取到我们想要的数据了。

// 使用gson解析json数据

City[] cities = gson.fromJson(response.body().string(), City[].class);

子线程请求数据

当请求服务器获取数据时,考虑到网络原因,服务器往往不能立刻响应我们的网络请求,如果在主线程中使用网络请求,会造成主线程堵塞,给用户带来不好的体验,甚至会因为长时间未响应被关闭。因此,网络请求应该在子线程中进行。

new Thread(new Runnable() {

@Override

public void run() {

// 使用http请求

....

}

}).start();

获取到数据以后,应该把获取到的数据更新到界面上。但是,安卓并不允许在子线程中更新ui,因为多线程更新ui会产生许多的线程同步和线程安全问题。要在子线程中解决ui更新问题,还得使用安卓的异步消息处理机制。

异步消息处理

因为之前一直在写web,说到异步处理就想起了JavaScript。与安卓一样,js也是频繁的修改dom,为此,js设计为单线程的语言。js处理异步的方式就是采用事件循环,当主线程跑完代码后,就会不断循环从消息队列中读取消息执行。安卓的异步消息处理与js的类似,主要由四个部分组成:Message、Handler、MessageQueue、Looper。

Message

Message表示在线程之间传递的消息,它可以携带少量的信息在不同的线程中交换数据。通过Message的what、arg1、arg2、obj字段来携带数据。

Handler

处理者,用于发送和处理消息。通过Handler的sendMessage()方法发送消息,被looper回调后通过handleMessage处理消息。

MessageQueue

消息队列,存放所有通过handler发送的消息。每个线程只有一个消息队列。

Looper

Lopper相当于每个线程中MessageQueue的管家,它会处于无限循环中,每当发现MessageQueue存在一条消息,就会将它取出,并传递到Handler的handlerMessage()方法中,每个线程也只有一个looper。

他们之间的协作关系如下图:

bVbAE8n

使用异步消息发送http请求:

public class MainActivity extends AppCompatActivity {

private Handler handler = new Handler() {

@Override

public void handleMessage(@NonNull Message msg) {

super.handleMessage(msg);

Object message = msg.obj; // 获取携带的数据

// 这里可以更新ui

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

new Thread(new Runnable() {

@Override

public void run() {

// 发送http请求

OkHttpClient okHttpClient = new OkHttpClient();

Request request = new Request.Builder().url("http://192.168.2.234:8080/city").build();

Response response = okHttpClient.newCall(request).execute();

City[] cities = gson.fromJson(response.body().string(), City[].class);

Message message = new Message();

message.obj = cities; // 这里可以携带数据

handler.sendMessage(message);

}

}).start();

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

来梳理以下具体的流程:我们创建了一个Handler对象并覆写了它的handlerMessage方法,然后在子线程中发送http请求,等请求返回数据后,创建一个Message对象,将请求回来的数据放入Message对象的obj字段中,然后通过handler.sendMessage()方法将消息放入消息队列中。因为handler对象是在主线程中创建的,所以消息被放在了主线程的消息队列中。在主线程的looper对象发现消息队列中存在消息时,就会把消息取出,执行Message的Hanler的handlerMessage方法。因为handlerMessage方法是在主线程中运行的,所以可以对ui进行操作。

基于安卓的异步消息的处理机制,我们就可以在子线程发送http请求数据,然后在主线程中更新ui了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值