阅读 69

Android 异步方法以同步方式进行

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Android 异步方法以同步方式进行

我们一般在主线程创建子线程的时候,子线程启动之后,主线程会接着往下执行,当子线程执行完毕之后就会有接口回调,回调到主线程,主线程再去处理结果。该篇文章讲解如何使用阻塞方法,直接就可以得到返回值。

一、线程返回值的两种不同思想

为了更直观的表达,参考流程图,正常的接口回调是这样的。

接口回调伪代码:


new Thread(new TestTask(new TestTask.Callback() {

@Override

public void onDown() {

// todo 处理完毕

}

})).start();

复制代码

阻塞方法伪代码:


private String getData(){

return blockThread();

}

复制代码

那么这两种方法有什么不同呢?

第一种接口回调的方法不会影响主线程,但需要接口回调,在接口回到中切换到主线程进行更新;

第二种阻塞的方法会影响主线程,所以需要再开一个子线程中进行操作,由于直接就可以拿到返回值,所以代码的逻辑可读性会大大的增强。

查看一些第三方框架的源码,在mina通讯的框架中的连接方法则是使用的阻塞方法。


ConnectFuture future = connector.connect(new InetSocketAddress(host, port));

future.awaitUninterruptibly();

复制代码

二、怎么实现阻塞方法

1. FutureTask作用

FutureTask 来自java。

一种可取消的异步计算。此类提供了Future的基本实现,其中包含启动和取消计算、查询以查看计算是否完成以及检索计算结果的方法。只有在计算完成后才能检索结果;如果计算尚未完成,get方法将阻塞。

2. 实现方式一

直接使用

为了不阻塞主线程,我们在线程中另开线程,对android来说,是允许这样操作的,因为阻塞方法阻塞的时长不一定。


import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import java.util.concurrent.Callable;

import java.util.concurrent.FutureTask;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 100; i++) {

String data = getData(i);

Log.e("===", "isMainThread:" + HandlerUtils.isMainThread() + " data:" + data);

}

}

}).start();

}

private String getData(int i) {

try {

FutureTask<String> task = new FutureTask<String>(new Callable<String>() {

@Override

public String call() throws Exception {

Thread.sleep(2000);

Log.e("===", "isMainThread:" + HandlerUtils.isMainThread());

return "iii:" + i;

}

});

new Thread(task).start();

return task.get();

} catch (Exception e) {

e.printStackTrace();

throw new RuntimeException("Exception");

}

}

}

复制代码

2. 实现方式二

自定义类实现Callable接口

CallableThread 类


import android.util.Log;

import java.util.concurrent.Callable;

class CallableThread implements Callable<String> {

int mIndex;

public CallableThread(int i) {

this.mIndex = i;

}

@Override

public String call() throws Exception {

Thread.sleep(2000);

Log.e("===", "isMainThread:" + HandlerUtils.isMainThread());

return "iii" + mIndex;

}

}

复制代码

MainActivity 类


import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import java.util.concurrent.FutureTask;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 100; i++) {

String data = getData(i);

Log.e("===", "isMainThread:" + HandlerUtils.isMainThread() + " data:" + data);

}

}

}).start();

}

private String getData(int i) {

try {

CallableThread callableThread = new CallableThread(i);

FutureTask<String> task1 = new FutureTask<String>(callableThread);

new Thread(task1).start();

return task1.get();

} catch (Exception e) {

e.printStackTrace();

throw new RuntimeException("Exception");

}

}

}

复制代码
文章分类
Android
文章标签