久久久精品一区ed2k-女人被男人叉到高潮的视频-中文字幕乱码一区久久麻豆樱花-俄罗斯熟妇真实视频

android延遲,Android延遲廣播

Android廣播阻塞、延遲問題

? 最近項目中,多次碰到app研發(fā)人員反饋廣播從發(fā)送到接收器接收,間隔時間太長,要求系統(tǒng)進行優(yōu)化,特別是開機階段。對此,專門閱讀了一下廣播從發(fā)送到接收這個流程的源碼,以徹底搞明白怎樣讓自己發(fā)送的廣播盡快到達(dá)接收器。

專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站建設(shè)服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)南木林免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。

涉及到的源碼類不多,主要就是ActivityManagerService.java 和?BroadcastQueue.java。發(fā)送廣播進程調(diào)用發(fā)送接口,通過IPC到達(dá)AMS,AMS根據(jù)Intent是否配置Intent.FLAG_RECEIVER_FOREGROUND,選擇當(dāng)前廣播加入前臺廣播隊列還是后臺廣播隊列。根據(jù)當(dāng)前廣播是否有序,將廣播加入廣播隊列的串行列表還是并行列表。廣播隊列和廣播隊列中的廣播列表是影響廣播接收時間的主要因素。

BroadcastQueue廣播隊列,負(fù)責(zé)將廣播發(fā)送給廣播接收器。AMS中有兩個成員變量,?

BroadcastQueue mFgBroadcastQueue;//前臺廣播隊列

BroadcastQueue mBgBroadcastQueue;//后臺廣播隊列

前臺廣播隊列和后臺廣播隊列的區(qū)別有兩處:1 超時時間,前臺10s,后臺60s. 2 是否延遲廣播等待前一個廣播進程完成。這兩個區(qū)別已經(jīng)說明前臺廣播對廣播接收器要求更高,響應(yīng)時間更短,如果廣播要排隊,時間上前臺廣播更短。同時系統(tǒng)默認(rèn)使用后臺廣播隊列,所以前臺廣播隊列處理的廣播要少,避免了可能的大量廣播排隊情況。

廣播隊列中的列表

//存放無序并發(fā)送給動態(tài)廣播接收器的廣播任務(wù)

final ArrayListBroadcastRecord mParallelBroadcasts = new ArrayListBroadcastRecord();

//存放無序發(fā)送給靜態(tài)廣播接收器的廣播任務(wù)或者存放有序廣播任務(wù)

final ArrayListBroadcastRecord mOrderedBroadcasts = new ArrayListBroadcastRecord();

mParallelBroadcasts 此列表中存放的是無序廣播動態(tài)廣播接收器任務(wù),廣播隊列會在處理任務(wù)時通過嵌套循環(huán),把每個廣播通過ipc發(fā)送到關(guān)注它的所有進程。所有無序廣播+動態(tài)廣播接收器,廣播不需要排隊。這種情況是最快能讓廣播到達(dá)目標(biāo)進程的方式。

mOrderedBroadcasts存放的廣播任務(wù)特點:廣播有序,或者廣播接收器是靜態(tài)注冊的。此種類型的廣播全部要在mOrderedBroadcasts中排隊,廣播之間按時間先后,同一個廣播不同廣播接收器按優(yōu)先級。mOrderedBroadcasts存放的廣播必須等一個廣播任務(wù)處理完畢才能處理下一個,中間可能包含進程的啟動等。

由此可見,廣播最快的情況是前臺廣播、無序廣播、動態(tài)注冊廣播接收器。最糟糕的情況是:后臺廣播、有序或靜態(tài)注冊廣播接收器、廣播接收器優(yōu)先級低。如果一個應(yīng)用只是簡單的靠注冊一個靜態(tài)廣播接收器拉起進程,對應(yīng)的正是最糟糕的情況。如果又發(fā)生在開機階段,自然延遲嚴(yán)重。

如果必須注冊靜態(tài)廣播接收器,縮短時間的辦法為:配置Intent.FLAG_RECEIVER_FOREGROUND,加入前臺廣播隊列,設(shè)置廣播優(yōu)先級

源碼:

廣播發(fā)送:Context .sendBroadcast -ActivityManagerNative.broadcastIntent-ActivityManagerService.broadcastIntent-ActivityManagerService.broadcastIntentLocked.到此階段,跟發(fā)送廣播的進程通信結(jié)束。此階段AMS完成的工作主要是根據(jù)Intent查找該廣播對應(yīng)的動態(tài)廣播接收器、靜態(tài)廣播接收器、以此發(fā)送該廣播使用的廣播隊列。

private final int broadcastIntentLocked(

......//權(quán)限檢查

......//特殊系統(tǒng)廣播進行必要處理

if (sticky) {//粘性廣播處理

......

//查找靜態(tài)注冊的接收器

receivers = collectReceiverComponents(intent, resolvedType, users);

if (intent.getComponent() == null) {

// 查找動態(tài)廣播接收器

? ? ? ? registeredReceivers = mReceiverResolver.queryIntent(intent,

? ? ? ? ? ? ? ? resolvedType, false, userId);

? ? }

//動態(tài)廣播接收器

? ? int NR = registeredReceivers != null ? registeredReceivers.size() : 0;

? ? if (!ordered NR 0) {?

//確定隊列

? ? ? ? final BroadcastQueue queue = broadcastQueueForIntent(intent);

//創(chuàng)建廣播任務(wù)BroadcastRecord

? ? ? ? BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,

? ? ? ? ? ? ? ? callerPackage, callingPid, callingUid, resolvedType, requiredPermission,

? ? ? ? ? ? ? ? appOp, registeredReceivers, resultTo, resultCode, resultData, map,

? ? ? ? ? ? ? ? ordered, sticky, false, userId);

......

//廣播任務(wù)加入并行列表中

? ? ? ? ? ? queue.enqueueParallelBroadcastLocked(r);

//啟動異步發(fā)送廣播任務(wù)

? ? ? ? ? ? queue.scheduleBroadcastsLocked();

registeredReceivers = null;

? ? ? ? NR = 0;

......

while (it NT ir NR) {

......

//根據(jù)優(yōu)先級排序

? ? ? if (curt == null) {

? ? ? ? ? ? ? ? curt = (ResolveInfo)receivers.get(it);

? ? ? ? ? ? }

? ? ? ? ? ? if (curr == null) {

? ? ? ? ? ? ? ? curr = registeredReceivers.get(ir);

? ? ? ? ? ? }

? ? ? ? ? ? if (curr.getPriority() = curt.priority) {

? ? ? ? ? ? ? ? // Insert this broadcast record into the final list.

? ? ? ? ? ? ? ? receivers.add(it, curr);

//獲取廣播隊列

? ? ? ? BroadcastQueue queue = broadcastQueueForIntent(intent);

//創(chuàng)建廣播任務(wù)

? ? ? ? BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,

? ? ? ? ? ? ? ? callerPackage, callingPid, callingUid, resolvedType,

? ? ? ? ? ? ? ? requiredPermission, appOp, receivers, resultTo, resultCode,

? ? ? ? ? ? ? ? resultData, map, ordered, sticky, false, userId);

//加入到廣播隊列串行列表中

? ? ? ? ? ? queue.enqueueOrderedBroadcastLocked(r);

//啟動異步發(fā)送任務(wù)

? ? ? ? ? ? queue.scheduleBroadcastsLocked();

廣播隊列處理廣播:

final void processNextBroadcast(boolean fromMsg) {

......

//并行列表,遍歷廣播任務(wù)

? ? ? ? while (mParallelBroadcasts.size() 0) {

final int N = r.receivers.size();

//遍歷接收器

? ? ? ? ? ? for (int i=0; iN; i++) {

//IPC調(diào)用發(fā)送給目標(biāo)進程

deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);

}

}

//有串行廣播任務(wù)正在執(zhí)行

if (mPendingBroadcast != null) {

? ? ? ? ?//接收廣播的目標(biāo)進程正常

? ? ? ? ? ? if (!isDead) {

? ? ? ? ? ? ? ? // It's still alive, so keep waiting 繼續(xù)等待目前進程反饋

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

}

? ? ? ? ?//取出第一個廣播

? ? ? ? ? ? r = mOrderedBroadcasts.get(0);//判斷是否超時,

? ? ? ? ? ? ? ? if ((numReceivers 0) ?

? ? ? ? ? ? ? ? ? ? ? ? (now r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {

? ? ? ? ? ? ? ? ? ? ?//廣播超時

? ? ? ? ? ? ? ? ? ? ? broadcastTimeoutLocked(false);//超時處理,終止當(dāng)前廣播,啟動下一個任務(wù)。

? ? ? ? ? ? ? ? ? ? ? }

if (r.receivers == null || r.nextReceiver = numReceivers

? ? ? ? ? ? ? ? ? ? || r.resultAbort || forceReceive) {

? ? ? ? ? ? ?//所有廣播任務(wù)執(zhí)行完畢

}

int recIdx = r.nextReceiver++;//下一個廣播接收器

r.dispatchTime = r.receiverTime;//設(shè)置派發(fā)時間

setBroadcastTimeoutLocked(timeoutTime);//啟動超時計時

if (nextReceiver instanceof BroadcastFilter){//動態(tài)廣播接收器

deliverToRegisteredReceiverLocked(r, filter, r.ordered);//發(fā)送

return;

}

.//靜態(tài)廣播

? ? ? ? ResolveInfo info =

? ? ? ? ? ? (ResolveInfo)nextReceiver;

......

//檢查進程是否已啟動

? ? ? ? ProcessRecord app = mService.getProcessRecordLocked(targetProcess,

? ? ? ? ? ? ? ? info.activityInfo.applicationInfo.uid, false);

? ? ? ? if (app != null app.thread != null) { /進程啟動

? ? ? ? ? ?processCurBroadcastLocked(r, app);//發(fā)送靜態(tài)廣播

? ? ? ? ? ?return;

? ? ? ? }

?if ((r.curApp=mService.startProcessLocked(targetProcess,//啟動進程

? ? ? ? ? ? ? ? info.activityInfo.applicationInfo, true,

? ? ? ? ? ? ? ? r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,

? ? ? ? ? ? ? ? "broadcast", r.curComponent,

? ? ? ? ? ? ? ? (r.intent.getFlags()Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))

? ? ? ? ? ? ? ? ? ? ? ? == null) {

? ? ? ? ? ? ? ? ? //進程啟動失敗

? ? ? ? ? ? ? }

? ? ? ? ?//標(biāo)志正在發(fā)送的串行廣播

? ? ? ? mPendingBroadcast = r;

? ? ? ? mPendingBroadcastRecvIndex = recIdx;//正在發(fā)送的廣播任務(wù)對應(yīng)的接收器索引

}

android 開發(fā)中如何實現(xiàn)讓程序執(zhí)行一條語句后延時一段時間后再執(zhí)行下面的語句?

延時操作,可以用下列方案:

方案1:線程阻斷

try {

Thread.currentThread().sleep(2000);//阻斷2秒

} catch (InterruptedException e) {

e.printStackTrace();

}

方案2:使用Handler的postDelayed延遲操作。

mHandler .postDelayed(mRunnable, 3000); // 在Handler中執(zhí)行子線程并延遲3s。

private Runnable mRunnable = new Runnable() {

@Override

public void run() {

mHandler.sendEmptyMessage(1);

}

};

Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

//3s后執(zhí)行代碼

}

}。

如何解決android消息通知推送延遲的問題?

這是安卓的缺陷。蘋果因為系統(tǒng)封閉,所有推送由蘋果自己負(fù)責(zé)統(tǒng)一推送,所以程序不需要后臺,所有軟件都能及時推送。而安卓也有谷歌統(tǒng)一推送,但是由于一些因素國內(nèi)支持的很少,所以安卓很多軟件如果要及時推送就必須鎖定在后臺,少數(shù)幾個還好,如果需要推送的多了都鎖定后臺對性能續(xù)航都會有比較大影響。

所以目前大多采用第三方消息推送平臺,例如極光,個推等

文章題目:android延遲,Android延遲廣播
網(wǎng)址分享:http://sd-ha.com/article42/dsipphc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、網(wǎng)站內(nèi)鏈、Google、關(guān)鍵詞優(yōu)化、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站