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

版权声明:版权归“行知致简”所有,转载请保留 https://blog.csdn.net/paladinzh/article/details/87256931

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;
}

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

 

 

展开阅读全文

没有更多推荐了,返回首页