日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 从零开始打造异步处理框架

發布時間:2024/9/30 Android 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 从零开始打造异步处理框架 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/52847872
本文出自【趙彥軍的博客】

    • 概述
    • 封裝嘗試
    • Handler優化
    • 線程優化
    • 框架使用
    • 參考資料

概述

在Android中會使用異步任務來處理耗時操作,避免出現界面卡頓的問題,當然到目前為止可以使用的異步任務框架有很多,比如:

  • 直接 new Thread()
  • 用Android自帶的AsyncTask
  • 用RxJava
  • 等等

    今天我們就來自己嘗試寫一個異步任務處理框架,代碼的設計思路參考AsyncTask

封裝嘗試

既然是異步的框架,那么肯定是在子線程中,所以第一步我們用自定義的ThreadTask繼承Thread. 并且重寫里面的run方法。

package com.zyj.app;/*** Created by ${zyj} on 2016/10/17.*/public class ThreadTask extends Thread {@Overridepublic void run() {super.run();} }

然后子線程需要把處理結果回調給主線程,我們需要定義3個方法:

  • onStart 任務開始之前調用,運行在主線程。可以做顯示進度條或者加載動畫。
  • onDoInBackground 異步任務執行,運行在子線程。可以做耗時操作。
  • onResult 異步任務處理的結果,運行在主線程。

    onDoInBackground這個方法是要在子類中實現的,所以要寫成抽象的方法,那么ThreadTask類自然也要寫成抽象類。同時這個方法會返回異步處理結果,這個結果的類型需要寫成泛型,以便在子類中靈活運用。

package com.zyj.app;import android.support.annotation.MainThread; import android.support.annotation.WorkerThread;/*** Created by ${zyj} on 2016/10/17.*/public abstract class ThreadTask<T> extends Thread {@Overridepublic void run() {super.run();}/*** 任務開始之前調用,運行在主線程*/@MainThreadpublic void onStart(){ }/*** 子線程中調用,運行在子線程* @return*/@WorkerThreadpublic abstract T onDoInBackground() ;/*** 子線程返回的結果,運行在主線程* @param t*/@MainThreadpublic void onResult( T t ){ } }

另外子線程和主線程通信我們用的是Handler。Handler的初始化工作放在ThreadTask構造函數中完成。

private Handler handler ;public ThreadTask(){handler = new Handler( Looper.getMainLooper()){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//在這里接收子線程發過來的消息}} ;}

最后還需要一個execute() 方法啟動線程。在啟動的前一刻最好調用Onstart方法。

/*** 開始執行*/public void execute(){onStart();start();}

最后一個完整的ThreadTask類是這樣的

package com.zyj.app;import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread;/*** Created by ${zyj} on 2016/10/17.*/public abstract class ThreadTask<T> extends Thread {private Handler handler ;public ThreadTask(){handler = new Handler( Looper.getMainLooper()){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//在這里接收子線程發過來的消息onResult((T) msg.obj);}} ;}@Overridepublic void run() {super.run();Message message = Message.obtain() ;message.obj = onDoInBackground() ;handler.sendMessage( message ) ;}/*** 任務開始之前調用,運行在主線程*/@MainThreadpublic void onStart(){ }/*** 子線程中調用,運行在子線程* @return*/@WorkerThreadpublic abstract T onDoInBackground() ;/*** 子線程返回的結果,運行在主線程* @param t*/@MainThreadpublic void onResult( T t ){ }/*** 開始執行*/public void execute(){onStart();start();} }

如何使用我們寫好的框架?

new ThreadTask<String>(){@Overridepublic void onStart() {super.onStart();Log.d( "ThreadTask " , "onStart線程:" + Thread.currentThread().getName() ) ;}@Overridepublic String onDoInBackground() {Log.d( "ThreadTask " , "onDoInBackground線程: " + Thread.currentThread().getName() ) ;//模擬耗時操作try {Thread.sleep( 3000 );} catch (InterruptedException e) {e.printStackTrace();}return "結果返回了";}@Overridepublic void onResult(String s) {super.onResult(s);Log.d( "ThreadTask " , "onResult線程: " + Thread.currentThread().getName() + " 結果:" + s ) ;}}.execute();

運行的結果:

ThreadTask: onStart線程:main
ThreadTask: onDoInBackground線程: Thread-229
ThreadTask: onResult線程: main 結果:結果返回了

Handler優化

到目前為止我們的框架初步就封裝好了,但是有沒有缺點呢,肯定是有的。首先每次創建一個ThreadTask的時候都會創建一個Handler,這顯然不是我們想看到的。

  • 要保證Handler的實例的唯一性,可以用單例模式來獲取Handler
/*** 單例模式,保證handler只有一個實例* @return*/private static Handler getHandler(){if ( handler == null ){synchronized ( MHandler.class ){if ( handler == null ){handler= new MHandler( Looper.getMainLooper()) ;}}}return handler ;}
  • MHandler是我們自定義的一個Handler類
private static class MHandler extends Handler {public MHandler( Looper looper ){super( looper );}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//在這里接收子線程發過來的消息ResultData resultData = (ResultData) msg.obj;resultData.threadTask.onResult( resultData.data );}}
  • ResultData是一個消息實體
/*** handler發送數據的實體* @param <Data>*/private static class ResultData<Data>{ThreadTask threadTask ;Data data ;public ResultData( ThreadTask threadTask ,Data data ){this.threadTask = threadTask ;this.data = data ;}}
  • 一個完整的代碼實例
package com.zyj.app;import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread;/*** Created by ${zyj} on 2016/10/17.*/public abstract class ThreadTask<T> extends Thread {private static Handler handler ;public ThreadTask(){}@Overridepublic void run() {super.run();Message message = Message.obtain() ;message.obj = new ResultData<T>( this , onDoInBackground() ) ;getHandler().sendMessage( message ) ;}/*** 任務開始之前調用,運行在主線程*/@MainThreadpublic void onStart(){ }/*** 子線程中調用,運行在子線程* @return*/@WorkerThreadpublic abstract T onDoInBackground() ;/*** 子線程返回的結果,運行在主線程* @param t*/@MainThreadpublic void onResult( T t ){ }/*** 開始執行*/public void execute(){onStart();start();}/*** 單例模式,保證handler只有一個實例* @return*/private static Handler getHandler(){if ( handler == null ){synchronized ( MHandler.class ){if ( handler == null ){handler= new MHandler( Looper.getMainLooper()) ;}}}return handler ;}private static class MHandler extends Handler {public MHandler( Looper looper ){super( looper );}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//在這里接收子線程發過來的消息ResultData resultData = (ResultData) msg.obj;resultData.threadTask.onResult( resultData.data );}}/*** handler發送數據的實體* @param <Data>*/private static class ResultData<Data>{ThreadTask threadTask ;Data data ;public ResultData( ThreadTask threadTask ,Data data ){this.threadTask = threadTask ;this.data = data ;}} }

到現在已經解決了Handler多次創建的問題,那么這個ThreadTask本質上還是新建線程來運行異步任務,為了避免不斷的創建線程,所以還需要一個線程池。

線程優化

  • 首選定義一個線程池,默認最大10個線程。
/*** 線程池,創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。*/private static ExecutorService executorService = Executors.newFixedThreadPool( 15 ) ;
  • 修改run()方法。
private void run() {executorService.execute(new Runnable() {@Overridepublic void run() {Message message = Message.obtain() ;message.obj = new ResultData<T>( ThreadTask.this , onDoInBackground() ) ;getHandler().sendMessage( message ) ;}});}
  • execute() 方法
/*** 開始執行*/public void execute(){onStart();run();}
  • 完整的代碼實例
package com.zyj.app;import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** Created by ${zyj} on 2016/10/17.*/public abstract class ThreadTask<T> {private static Handler handler ;/*** 線程池,創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。*/private static ExecutorService executorService = Executors.newFixedThreadPool( 15 ) ;public ThreadTask(){}private void run() {executorService.execute(new Runnable() {@Overridepublic void run() {Message message = Message.obtain() ;message.obj = new ResultData<T>( ThreadTask.this , onDoInBackground() ) ;getHandler().sendMessage( message ) ;}});}/*** 任務開始之前調用,運行在主線程*/@MainThreadpublic void onStart(){ }/*** 子線程中調用,運行在子線程* @return*/@WorkerThreadpublic abstract T onDoInBackground() ;/*** 子線程返回的結果,運行在主線程* @param t*/@MainThreadpublic void onResult( T t ){ }/*** 開始執行*/public void execute(){onStart();run();}/*** 單例模式,保證handler只有一個實例* @return*/private static Handler getHandler(){if ( handler == null ){synchronized ( MHandler.class ){if ( handler == null ){handler= new MHandler( Looper.getMainLooper()) ;}}}return handler ;}private static class MHandler extends Handler {public MHandler( Looper looper ){super( looper );}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//在這里接收子線程發過來的消息ResultData resultData = (ResultData) msg.obj;resultData.threadTask.onResult( resultData.data );}}/*** handler發送數據的實體* @param <Data>*/private static class ResultData<Data>{ThreadTask threadTask ;Data data ;public ResultData( ThreadTask threadTask ,Data data ){this.threadTask = threadTask ;this.data = data ;}} }

框架使用

  • 方式1
new ThreadTask<String>(){@Overridepublic String onDoInBackground() {return "我是線程";}}.execute();
  • 方式2
new MyTask().execute();class MyTask extends ThreadTask<String> {@Overridepublic void onStart() {super.onStart();}@Overridepublic String onDoInBackground() {try {//模擬耗時操作Thread.sleep( 2000);} catch (InterruptedException e) {e.printStackTrace();}return "ThreadTask" ;}@Overridepublic void onResult(String s) {super.onResult(s);}}

參考資料

【1】Android AsyncTask 深度理解、簡單封裝、任務隊列分析、自定義線程池
【2】Android 自定義線程池的實戰
【3】Java 單例模式
【4】Android Handler、Loop 的簡單使用
【5】Android 更新UI的幾種方式

總結

以上是生活随笔為你收集整理的Android 从零开始打造异步处理框架的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。