最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

andriod如何搭建自己的輪詢框架

 更新時間:2019年01月04日 15:12:45   作者:hankinghu  
很多時候Android應(yīng)用需要每間隔一段時間向服務(wù)器請求數(shù)據(jù),如果服務(wù)器數(shù)據(jù)有更新則通知界面變化。Android中最常用的紅點一般采用的就是輪詢,本文主要介紹了Android如何搭建自己的輪詢框架,感興趣的小伙伴們可以參考一下

很多時候Android應(yīng)用需要每間隔一段時間向服務(wù)器請求數(shù)據(jù),如果服務(wù)器數(shù)據(jù)有更新則通知界面變化。Android中最常用的紅點一般采用的就是輪詢,紅點是為了在數(shù)據(jù)有更新時及時的提醒用戶,比如朋友圈更新,當(dāng)用戶的朋友圈更新時就會顯示紅點,就是通過移動端不斷的向服務(wù)器查詢朋友圈的更新狀態(tài)。

相關(guān)知識點

在實現(xiàn)輪詢框架時會主要會要到下面兩個類,會結(jié)合輪詢框架對這三個類進(jìn)行講解,在應(yīng)用中分析會理解更加深刻。

1、IntentService IntentService是一種特殊的Service,繼承了Service并且是一個抽象類,必須創(chuàng)建它的子類才能用。IntentService可以用于執(zhí)行后臺耗時的任務(wù),當(dāng)任務(wù)執(zhí)行后會自動停止,IntentService的優(yōu)先級比一般的線程高,比較適合執(zhí)行一些優(yōu)先級高的后臺任務(wù)。

2、PendingIntent PendingIntent是延遲的intent,主要用來在某個事件完成后執(zhí)行特定的Action。PendingIntent包含了Intent及Context,所以就算Intent所屬程序結(jié)束,PendingIntent依然有效,可以在其他程序中使用。PendingIntent一般作為參數(shù)傳給某個實例,在該實例完成某個操作后自動執(zhí)行PendingIntent上的Action,也可以通過PendingIntent的send函數(shù)手動執(zhí)行,并可以在send函數(shù)中設(shè)置OnFinished表示send成功后執(zhí)行的動作。

輪詢框架實現(xiàn)

要實現(xiàn)輪詢,可以借鑒Handler中的looper機(jī)制,如下圖,維護(hù)一個消息隊列,循環(huán)的從消息隊列中取出消息來執(zhí)行,輪詢框架可以定時的向消息隊列中加入消息,然后循環(huán)中消息隊列中取出消息執(zhí)行。

可以自己實現(xiàn)一個Looper,但是IntentService中已經(jīng)包含了一個Looper和一個HandlerThread。因此輪詢框架中使用IntentService作為循環(huán)框架。繼承IntentService接口來實現(xiàn)處理消息訪問服務(wù)器。

PollingService 用于每次輪詢時向請求服務(wù)器接口數(shù)據(jù)。

public class PollingService extends IntentService {
	public static final String ACTION_CHECK_CIRCLE_UPDATE="ACTION_CHECK_CIRCLE_UPDATE";	
	public static final long DEFAULT_MIN_POLLING_INTERVAL = 60000;//最短輪詢間隔1分鐘
 public PollingService() {
  super("PollingService");
 }
	
 @Override
 protected void onHandleIntent(Intent intent) {
  if (intent == null)
   return;
  final String action = intent.getAction();
  if (ACTION_CHECK_Circle_UPDATE.equals(action)) {
   CheckCircleOfFriendsUpdate();//這個是訪問服務(wù)器獲取朋友圈是否更新
  }
 }
}

PollingService 用來處理接到輪詢的消息之后在 onHandleIntent(Intent intent) 中根據(jù)Intent所帶有的action不同來進(jìn)行訪問服務(wù)器不同的接口獲取數(shù)據(jù)。

PollingUtil 用于控制輪詢服務(wù)的開始和結(jié)束 使用PollingUtil中的startPollingService來根據(jù)action和context生成一個PendingIntent,并將PendingIntent交給PollingScheduler來處理。PollingScheduler是一個線程池控制類。

public class PollingUtil {
 /**
  * 開始輪詢服務(wù)
  */
 public static void startPollingService(final Context context, String action) {
   //包裝需要執(zhí)行Service的Intent
   Intent intent = new Intent(context, PollingService.class);
   intent.setAction(action);
   PendingIntent pendingIntent = PendingIntent.getService(context, 0,
     intent, PendingIntent.FLAG_UPDATE_CURRENT);
   PollingScheduler.getInstance().addScheduleTask(pendingIntent, 0, PollingService.DEFAULT_MIN_POLLING_INTERVAL);
  }
 }
 /**
  * 停止輪詢服務(wù)
  *
  * @param context
  */
 public static void stopPollingServices(Context context, String action) {
   PollingScheduler.getInstance().clearScheduleTasks();
  }
 }

PollingScheduler實現(xiàn)定時向IntentService的Looper中加入消息 PollingScheduler中生成一個單線程池,addScheduleTask中定時的執(zhí)行pendingIntent.send(),其中PendingIntent是由 PendingIntent pendingIntent = PendingIntent.getService(context, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT); 生成的,pendingIntent.send()函數(shù)會調(diào)用Service.startService()來開啟一個服務(wù)。

public class PollingScheduler {
 private static PollingScheduler sInstance;
 private ScheduledExecutorService mScheduler;

 private PollingScheduler() {
  mScheduler = Executors.newSingleThreadScheduledExecutor();
 }

 public static synchronized PollingScheduler getInstance() {
  if (sInstance == null) {
   sInstance = new PollingScheduler();
  }
  if (sInstance.mScheduler.isShutdown()) {
   sInstance.mScheduler = Executors.newSingleThreadScheduledExecutor();
  }
  return sInstance;
 }
	
 public void addScheduleTask(final PendingIntent pendingIntent, long initialDelay, long period) {
  Runnable command = new Runnable() {
   @Override
   public void run() {
    try {
     pendingIntent.send();
    } catch (PendingIntent.CanceledException e) {
     e.printStackTrace();
    }
   }
  };
  mScheduler.scheduleAtFixedRate(command, initialDelay, period, TimeUnit.MILLISECONDS);
 }

 public void clearScheduleTasks() {
  mScheduler.shutdownNow();
 }
}

代碼分析

先給出類圖之間的關(guān)系如下:

 

PollingService繼承了IntentService,并且在PollingUtil的startPollingService方法中通過 Intent intent = new Intent(context, PollingService.class); 和將PendingIntent 與PollingService關(guān)聯(lián)起來,并將PendingIntent加入到定時執(zhí)行的線程池中,在PollingScheduler 中使用 pendingIntent.send();

由于PendingIntent與PollingService關(guān)聯(lián),所以執(zhí)行pendingIntent.send()的時候會調(diào)用PollingIntentServide中的onStart()方法。onStart()方法是IntentService中的方法,代碼如下:

 @Override
 public void onStart(@Nullable Intent intent, int startId) {
  Message msg = mServiceHandler.obtainMessage();
  msg.arg1 = startId;
  msg.obj = intent;
  mServiceHandler.sendMessage(msg);
 }

在onstart()中有一個 mServiceHandler.sendMessage(msg); ,找到mServiceHandler的生成位置:

 @Override
 public void onCreate() {
  super.onCreate();
  HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
  thread.start();

  mServiceLooper = thread.getLooper();
  mServiceHandler = new ServiceHandler(mServiceLooper);
 }

在IntentService的onCreate方法中生成了一個HandlerThread,一個mServiceLooper,一個mServiceHandler,其中mServiceHandler.sendMessage(msg)中的msg都會放到mServiceLooper,執(zhí)行時從mServiceLooper中取出執(zhí)行,其中ServiceHandler 的代碼如下

 private final class ServiceHandler extends Handler {
  public ServiceHandler(Looper looper) {
   super(looper);
  }

  @Override
  public void handleMessage(Message msg) {
   onHandleIntent((Intent)msg.obj);
   stopSelf(msg.arg1);
  }
 }

handleMessage(Message msg)中會調(diào)用onHandleIntent((Intent)msg.obj);方法,也就是在PollingService中重寫的onHandleIntent方法。 因此我們在addScheduleTask中不斷的執(zhí)行pending.send()方法,會不斷的調(diào)用IntentService中的onStart方法中的mServiceHandler.sendMessage(msg);不斷的向消息隊列中發(fā)消息,然后在onHandleIntent處理消息。 這樣一個輪詢框架就完成了。

總結(jié)

本文的輪詢框架利用了IntentService中的handler和Looper機(jī)制來實現(xiàn)循環(huán)的處理消息,由于IntentService具有服務(wù)的特性因此特別適合后臺輪詢訪問服務(wù)器數(shù)據(jù)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android如何使用Flow封裝一個FlowBus工具類

    Android如何使用Flow封裝一個FlowBus工具類

    本文介紹了如何在Android中使用Flow封裝一個FlowBus工具類,以替代EvenutBus、Rxbus、LiveDataBus、LiveData等第三方依賴包,作者提供了在Activity、Fragment、Service和Websock中使用FlowBus的具體代碼,并解釋了實現(xiàn)的效果,文章最后還提供了項目demo源碼的下載鏈接
    2024-09-09
  • Android開發(fā)自學(xué)筆記(六):聲明權(quán)限和Activity

    Android開發(fā)自學(xué)筆記(六):聲明權(quán)限和Activity

    這篇文章主要介紹了Android開發(fā)自學(xué)筆記(六):聲明權(quán)限和Activity,本文是上一篇的補(bǔ)充,需要的朋友可以參考下
    2015-04-04
  • PopupWindow?RecyclerView實現(xiàn)下拉選擇Spinner示例解析

    PopupWindow?RecyclerView實現(xiàn)下拉選擇Spinner示例解析

    這篇文章主要介紹了PopupWindow?RecyclerView實現(xiàn)下拉選擇Spinner示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Kotlin 與 Jetpack Compose 參數(shù)設(shè)計完全指南(最新推薦)

    Kotlin 與 Jetpack Compose 參數(shù)設(shè)計完全指南(最新推薦)

    作為 Kotlin 和 Jetpack Compose 開發(fā)者,合理的參數(shù)設(shè)計能顯著提升代碼的可讀性和易用性,本文將系統(tǒng)整理各類參數(shù)規(guī)則,幫助您編寫更優(yōu)雅的 API,感興趣的朋友一起看看吧
    2025-04-04
  • Android自定義播放器控件VideoView

    Android自定義播放器控件VideoView

    這篇文章主要介紹了Android自定義播放器控件VideoView的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • Android實現(xiàn)生成二維碼并保存到相冊

    Android實現(xiàn)生成二維碼并保存到相冊

    這篇文章主要介紹了如何利用Android實現(xiàn)二維碼的生成,并且保存到本地相冊。文中的示例代碼講解詳細(xì),感興趣的小伙伴快跟隨小編學(xué)習(xí)一下
    2022-04-04
  • Android添加水印的正確方法 只要三步!

    Android添加水印的正確方法 只要三步!

    這篇文章主要介紹了Android添加水印的正確方法,僅僅三步輕松實現(xiàn)為圖片添加水印功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android中判斷是否聯(lián)網(wǎng)實現(xiàn)代碼

    Android中判斷是否聯(lián)網(wǎng)實現(xiàn)代碼

    這篇文章主要介紹了Android中判斷是否聯(lián)網(wǎng)實現(xiàn)代碼,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下
    2015-06-06
  • Android中自定義Checkbox組件實例

    Android中自定義Checkbox組件實例

    這篇文章主要介紹了Android中自定義Checkbox控件實例,本文使用兩張圖片來美化Checkbox組件,需要的朋友可以參考下
    2015-01-01
  • Android 如何使用SQLite保存數(shù)據(jù)

    Android 如何使用SQLite保存數(shù)據(jù)

    對于重復(fù)數(shù)據(jù)或結(jié)構(gòu)化數(shù)據(jù)(例如聯(lián)系信息),將數(shù)據(jù)保存到數(shù)據(jù)庫是理想選擇,SQL 數(shù)據(jù)庫的主要原則之一是架構(gòu),即數(shù)據(jù)庫組織方式的正式聲明,本篇文章介紹在 Android 上使用 SQLite 數(shù)據(jù)庫,感興趣的朋友一起看看吧
    2024-03-03

最新評論

酉阳| 阿拉善盟| 宁南县| 抚州市| 花莲市| 庆元县| 凤阳县| 乌拉特前旗| 高青县| 安图县| 六枝特区| 靖西县| 镇安县| 德昌县| 洛浦县| 汨罗市| 拜泉县| 内江市| 聂拉木县| 会昌县| 囊谦县| 兰溪市| 合山市| 姚安县| 卢龙县| 舒城县| 桃源县| 沂水县| 江北区| 会宁县| 通州区| 镇安县| 宁陵县| 施秉县| 香港| 南江县| 泸水县| 东辽县| 印江| 德江县| 吉安市|