Android多线程同步转异步方法总结

//实现网络传输,要求:【线程同步转异步】在子线程完成数据上报,当前调用线程必须等待"子线程"返回的结果后,才继续向下执行,返回 response byte数组。
一、归纳总结

1. Thread\Handler + Callback

2. Thread\LooperHandler + FutureTask

3. AsyncTask

 

二、引子

Android之NetworkOnMainThreadException异常

看名字就应该知道,是网络请求在MainThread中产生的异常

 

、详细介绍及示例

1. Thread\Handler + Callback (无阻塞结果返回)

说明:通过Callback回调结果,只切换线程了;未进行线程同步转异步后的结果阻塞返回。

private final static Handler mLooperHandler;static {    HandlerThread handlerThread = new HandlerThread("BackgroundHandler");    handlerThread.start();    mLooperHandler = new Handler(handlerThread.getLooper());}public static void login(final String code, final LoginCallback<UserInfo> cb) {    mLooperHandler.post(new Runnable() {        @Override        public void run() {            final UserInfo userInfo = loginAsync(code);            Handler mainHandler = new Handler(Looper.getMainLooper());            mainHandler.post(new Runnable() {                @Override                public void run() {                    //已在主线程中,可以更新UI                    cb.onResult(userInfo);                }            });        }    });}

 

2. Thread\LooperHandler + FutureTask

public static byte[] networkTransport(byte datas[]) {    final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式    String date = df.format(new Date());// new Date()为获取当前系统时间,也可使用当前时间戳    System.out.println("networkTransport thread=" + Thread.currentThread().getName()            + " task datas=" + datas + " entry date=" + df.format(new Date()));    final byte[] arrByte = datas;    FutureTask<byte[]> task = new FutureTask<byte[]>((Callable<byte[]>) () -> {        System.out.println("networkTransport thread=" + Thread.currentThread().getName()                + " task datas=" + arrByte + " inThreadTask date=" + df.format(new Date()));        Thread.sleep(2 * 1000);        return arrByte;    });    new Thread(task, "do").start();    byte[] outArrByte = new byte[0];    try {        outArrByte = task.get();    } catch (InterruptedException | ExecutionException e) {        e.printStackTrace();    }    System.out.println("networkTransport thread=" + Thread.currentThread().getName()            + " task datas=" + datas + " postThreadTaskGet date=" + df.format(new Date()));    return outArrByte;}

说明:new Thread(task, "do").start();换成mLooperHandler.post(new Runnable() {…});亦可。

 

3. AsyncTask

说明:即可通过Callback回调结果,也可线程同步转异步后的结果阻塞返回。

public static byte[] httpGet(final String url) {   Log.i(TAG, "httpGet foreground thread=" + Thread.currentThread().getName() + " url=" + url);   AsyncTask<String, Void, byte[]> asyncTask = new AsyncTask<String, Void, byte[]>() {      @Override      protected byte[] doInBackground(String... strings) {         Log.i(TAG, "httpGet background thread=" + Thread.currentThread().getName() + " url=" + strings[0]);         byte[] arrByte = httpGetAsync(strings[0]);         return arrByte;      }      @Override      protected void onPostExecute(byte[] result) {         Log.i(TAG, "httpGet foreground thread=" + Thread.currentThread().getName() + " result=" + result);      }   };   asyncTask.execute(url);   //asyncTask.executeOnExecutor(url);   try {      byte[] arrByte = (byte[]) asyncTask.get();      Log.i(TAG, "httpGet foreground thread=" + Thread.currentThread().getName() + " arrByte=" + arrByte);      return arrByte;   } catch (ExecutionException | InterruptedException e) {      e.printStackTrace();   }   return null;}

欢迎大家讨论,提供新思路新解决方案。

 

 

更多相关文章

  1. Android中修改系统时间的几种方式
  2. android9.0 系统默认时间修改
  3. 线程安全
  4. android 日期时间选择器
  5. Android学习札记29:对线程更新UI界面的一些理解(2)
  6. Android的线程和线程池--《Android开发艺术探索》阅读笔记——第
  7. 【Android】Java四种线程池的使用

随机推荐

  1. android强大的SpannableStringBuilder
  2. Android解析XML(PULL)展示到ListView
  3. android与C++的选择
  4. 安装Android的SDK--中文教程(完整版,包括Ec
  5. Android指纹解锁调用
  6. android 中Message、Handler、Message Qu
  7. Android用户版本分布更新 2.1版领先
  8. Android热补丁动态修复技术(完结篇):自动
  9. 使用TensorFlow在Android上进行物体检测
  10. 飞凌ok6410开发板 android 有线配置