热门搜索 :
考研考公
您的当前位置:首页正文

在一个方法内实现异步获取数据同步返回

来源:东饰资讯网

背景

今天一个开发群里的小伙伴遇到一个需求大致意思是实现这样一个方法

public List<Apn>   getApnList(){//在主线成调用这个方法
//从网络获取数据
//同步返回
return list;
}

讨论

群里的小伙伴们一看,噶哈呢这是,在主线程进行网络操作啊,不直接宕机了吗
于是一顿讨论后纷纷给出别的替代解决办法

Rxjava,Handler Thread,观察者模式接口,广播

这个小伙看了解决办法说:"要是能这样实现也不会来问了,这个是上层定义好的接口,不能改,而且是在主线成调用,我是要在这个里面实现掉接口获取,并将结果返回.我也很无奈"

思考

我一想,以前我也遇到过这种问题,在一个方法里异步获取数据,同步返回.但是后来都放弃了,换了上层接口,毕竟直接阻塞主线程一点都不够优雅

但是为了体现我Android大佬的身份

灵机一动,忽然想起了FutureTask这个类,Android只禁止了主线程做网络耗时操作,别的都是出个ANR啊,这个是不是也是呢,于是,就产生了下面的代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int i = -1;
        i = getAPN();
        System.out.println("do====result:"+i);
    }
    private Integer getAPN(){
        //定义耗时Task,5秒之后返回1
        FutureTask<Integer> futureTask = new FutureTask<Integer>(
                new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                //获取apn
                Thread.sleep(60000);
                return 1;
            }
        });
        //开始耗时操作
        System.out.println("do==== Start Start Start:");
        new Thread(futureTask).start();
        try {
            Integer i = -1;
            //futureTask.get()这个方法阻塞主线程
            System.out.println("do==== OK OK OK:"
                    +(i =futureTask.get()));
            //阻塞结束后返回
            return i;
        } catch (InterruptedException e) {
            System.out.println("do==== ex ex ex:");
            e.printStackTrace();
        } catch (ExecutionException e) {
            System.out.println("do==== ex ex ex:");
            e.printStackTrace();
        }
        return -1;
    }
}

果然,实现了异步耗时,同步返回,并且避免了主线程进行网络操作
但是这样写一定是不优雅的,,,也就是,没啥用,就当是学习一下FutureTask

还有一个问题就是,我用模拟器运行的,为什么没有出现ANR异常呢,非常疑惑,而且在OnClick里面Thread.sleep(30000)也不会ANR异常,求解!

Top