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. Android(安卓)UI线程和非UI线程
  3. 使用navigator.userAgent.toLowerCase()判断移动端类型
  4. Android精华汇总
  5. Android(安卓)系统中WatchDog 日志分析
  6. Android事件处理分析+Android事件处理 +Android输入事件流程
  7. Android(安卓)UI Operation in Thread
  8. android消息机制之二--Handler
  9. Android之Handler用法总结

随机推荐

  1. Android中的Binder概述
  2. android面试(2)----组件
  3. android 笔记——listView应用
  4. Android(安卓)AM命令
  5. Android(安卓)事件触发机制的深入学习
  6. Android中shape的使用
  7. Android绘图之Paint的使用方法详解
  8. EditText 各部分颜色设置小结
  9. android视频播放-饺子播放器
  10. android菜单的使用