綁定Android點擊事件有三種方式:
創(chuàng)新互聯(lián)是一家專業(yè)提供湛江企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站制作、H5網(wǎng)站設(shè)計、小程序制作等業(yè)務(wù)。10年已為湛江眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進(jìn)行中。
一、匿名內(nèi)部類
1、通過資源ID找到對應(yīng)的Android控件,比如R.id.button1
Button button1 = (Button)findViewById(R.id.button1);
2、調(diào)用setOnClickListener方法,將點擊事件與之綁定
button1.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
//這里放點擊事件的邏輯
}
});
二、XML申明式
1、在對應(yīng)的布局文件中添加一個按鈕,即Button
2、在Button中添加 onClick="foo()" 屬性
3、在對應(yīng)的Activity中編寫對應(yīng)的foo()方法,如下:
public void foo(View v){
//這里放點擊事件的邏輯
//這里的 " v " 是指當(dāng)前組件,就是你點擊的這個按鈕
}
三、統(tǒng)一處理式
1、使對應(yīng)的Activity類實現(xiàn)View.OnClickListener 接口,也就是這樣寫:
public class xxActivity implement View.OnClickListener {
2、在方法中重載onClick(View v)方法
public void onClick(View v){
3、通過 v.getId() 來判斷,來源是哪一個按鈕,這里可以放一個switch開關(guān)語句,來進(jìn)行邏輯的分工。
}
}
純手打,希望上文能對你起到一定的輔助作用。
在Android Studio 2.1 Preview 3之后,官方開始支持雙向綁定了。
可惜目前Google并沒有在Data Binding指南里面加入這個教程,并且在整個互聯(lián)網(wǎng)之中只有 這篇文章 介紹了如何使用反向綁定。
在閱讀一下文章之前,我假設(shè)你已經(jīng)知道如何正向綁定。
在正向綁定中,我們在Layout里面的綁定表達(dá)式是這樣的:
當(dāng)user.name的數(shù)據(jù)改動時,我們的TextView都會同步改變文字。
現(xiàn)在假設(shè)一種情況,當(dāng)你更換成EditText時,如果你的用戶名User.name已經(jīng)綁定到 EditText 中,當(dāng)用戶輸入文字的時候,你原來的user.name數(shù)據(jù)并沒有同步改動,因此我們需要修改成:
看出微小的差別了嗎?對,就是"@{}"改成了"@={}",是不是很簡單?
同樣你也可以在別的View上引用屬性:
當(dāng)CheckBox的狀態(tài)發(fā)生改變的時候,ImageView也會同時發(fā)生改變。在復(fù)雜情況下,這個特性沒什么卵用,因為邏輯部分我們是不建議寫在XML中。
開啟雙向綁定,需要在項目的build.gradle中設(shè)置:
同樣,你需要在你Module的build.gradle中設(shè)置:
我們剛才的例子里面只顯示了系統(tǒng)自帶的應(yīng)用,那么如果是自定義控件,或者是我們更細(xì)顆粒度的 Observable 呢?等下就揭曉如何自定義自己的雙向綁定,我們來看看目前Android支持的控件:
設(shè)想一下我們使用了下拉刷新 SwipeRefreshLayout 控件,這個時候我們希望在加載數(shù)據(jù)的時候能控制refreshing的狀態(tài),所以我們加入了 ObservableBoolean 的變量swipeRefreshViewRefreshing來正向綁定數(shù)據(jù),并且能夠在用戶手動下拉刷新的時候同步更新swipeRefreshViewRefreshing數(shù)據(jù):
接下來我們需要告訴框架,我們需要將 SwipeRefreshLayout 的isRefreshing的值反向綁定到 swipeRefreshViewRefreshing :
這是一種簡單的定義,其中event和method都不是必須的,因為系統(tǒng)會自動生成,寫出來是為了更好地了解如何綁定的,可以參考官方文檔 InverseBindingMethod 。
當(dāng)然你也可以使用另外一種寫法,并且如果你的值并不是直接對應(yīng) Observable 的值的時候,就可以在這里進(jìn)行轉(zhuǎn)換:
上面的event同樣也不是必須的。以上的定義都是為了讓我們能夠在布局文件中使用"@={}"這個雙向綁定的特性。接下來你需要告訴框架如何處理refreshingAttrChanged事件,就像處理一般的監(jiān)聽事件一樣:
一般情況下,我們都需要設(shè)置正常的OnRefreshListener,所以我們可以合并寫成:
現(xiàn)在我們終于可以使用雙向綁定的技術(shù)啦。但是要注意,需要設(shè)置 requireAll = false ,否則系統(tǒng)將識別不了refreshingAttrChanged屬性,前文提到的文章例子里并沒有設(shè)置這個。
在ViewModel中,我們的數(shù)據(jù)是這樣的:
在布局文件中是這樣設(shè)置的:
最后我們還有一個小問題,就是雙向綁定有可能會出現(xiàn)死循環(huán),因為當(dāng)你通過Listener反向設(shè)置數(shù)據(jù)時,數(shù)據(jù)也會再次發(fā)送事件給View。所以我們需要在設(shè)置一下避免死循環(huán):
這樣就沒問題啦。
最近封裝了幾個View,都和生命周期有關(guān),比如BannerView、和我們公司的ARView,那他們的生命周期怎么綁定呢?剛開始我是直接告訴別人,你自己在哪個activity使用的,就在哪個activity綁定,結(jié)果使用的時候被甲方對接人員打回來說這是低級處理方式,wtm這暴脾氣,誰tm低級了,但是沒辦法別人是甲方只能聽他的,直接將生命周期的綁定綁在view里面。下面就介紹幾個常用的生命周期綁定。
Application.ActivityLifecycleCallbacks是Android自帶的生命周期綁定接口,他有注冊與解除方法,當(dāng)我們進(jìn)入一個activity的時候就可以注冊綁定他了。
簡單demo。比如我們要講一個自定義的View綁定生命周期。
1、先定義一個Application.ActivityLifecycleCallbacks的實現(xiàn)類,為什么這樣呢?是因為用戶可以要什么選什么,就不用被迫每次都實現(xiàn)全部。
2、定義一個測試用的view,在構(gòu)造方法綁定注冊生命周期,
((Activity)context).getApplication().registerActivityLifecycleCallbacks(lifecycleCallbacks);這句話是注冊生命周期當(dāng)然他也對應(yīng)了一個((Activity)context).getApplication().unregisterActivityLifecycleCallbacks(lifecycleCallbacks);解綁方法。
在ActivityLifecycleCallbacks 的實現(xiàn)中判斷了返回的activity是否為這個view所在的acrivity因為很多activity都會走這個方法,如果不做判斷,其他activity的生命周期也會影響這個view,所以加判斷是個好習(xí)慣。
這次我們模擬一個普通類綁定生命周期這個類名叫Test,哈哈,是不是很高大上?但是寫Test類之前先定義我們要綁定的生命周期接口LifecycleListener
這里我們監(jiān)聽下常用的onResume、onPause、onDestroy。
然后是Test類
然后寫LifecycleDetector,嘗試將test類的實例與fragment綁定
定義沒有布局的fragment實例
然后保存fragment和Requestmanager關(guān)系
還有一個遺漏的接口
上面這些完成后,就可以使用了,我們隨便搞個activity試試名字就叫LeftDemoActivity非常好聽了有沒有!
當(dāng)你運(yùn)行起來的時候,就是成功的時候。
有個東西忘啦,getSnapshot是做保存的,直接把源碼拿過來的。
還有其他的方法我沒試過,但是這樣的生命周期綁定可以解決挺多bug的,玩過嗶哩嗶哩的應(yīng)該會遇到他們的一個bug,就是進(jìn)入一個視頻播放頁,然后還沒加載完成就息屏,他這個時候異步回調(diào)回來視頻數(shù)據(jù)了就會在息屏或鎖屏界面播出音頻來,這是典型的生命周期bug,我遇到過幾次了,如果加入這個綁定輕松就能解決問題啦。
我們已經(jīng)了解了BroadcastReceiver的原理,我們再來看看四大組件之一的Service是怎么啟動的,以及怎么運(yùn)行的原理。
如果遇到什么問題可以來到 本文下進(jìn)行交流
啟動Service的入口就是startService和bindService方法。我們先來看看startService在ContextImpl中做了什么。
文件:/ frameworks / base / core / java / android / app / ContextImpl.java
此時調(diào)用的就是AMS的startService方法。
mServices是一個ActiveServices對象。這個對象是在AMS的構(gòu)造函數(shù)中初始化好的。
這里調(diào)用了ActiveServices的startServiceLocked。
文件:/ frameworks / base / services / core / java / com / android / server / am / ActiveServices.java
核心流程有如下三個:
注意這里addToStarting是一個比較關(guān)鍵的判斷,addToStarting默認(rèn)為false。
如果此時不是啟動前臺服務(wù),則需要進(jìn)一步進(jìn)行處理。如果ProcessRecord為空或者curProcState大于PROCESS_STATE_RECEIVER這個優(yōu)先級數(shù)值;也就是優(yōu)先級更小。
為了避免此時App應(yīng)用是沒有任何的前臺ui,或者App應(yīng)用還沒有聲明。避免有的App通過startService進(jìn)行應(yīng)用的包活或者拉起應(yīng)用。就會進(jìn)行如下能夠存在的最大后臺服務(wù)數(shù)量,則放入mDelayedStartList中進(jìn)行延時啟動后臺服務(wù),現(xiàn)在直接返回了。
不然則說明能夠允許啟動后臺服務(wù), 就設(shè)置為addToStarting為true。
通過ComponentName也就是包名和類名查找ServiceRecord;通過Intent意圖過濾找到ServiceRecord。·
核心方法是bringUpServiceLocked。如果bringUpServiceLocked返回了異常,就返回一個特殊的ComponentName對象。
addToStarting為true,說明此時是一個能夠啟動的后臺服務(wù),則ServiceRecord添加到mStartingBackground中。如果mStartingBackground的數(shù)量為0,則直接調(diào)用ServiceMap的rescheduleDelayedStartsLocked啟動后臺服務(wù)。
這幾個關(guān)鍵的步驟,讓我們依次的考察,先來看看scheduleCreateService中做了什么。
如果第一次啟動就走第一個if的分支:
能看到和BroadcastReceiver的ANR思路一樣,通過一個延時的Handler,如果達(dá)到時間了還沒有移除這個Handler消息則報ANR異常。
這里根據(jù)啟動前臺和后臺分為兩種超時時間:
前臺分別是10秒,后臺服務(wù)不屬于后臺進(jìn)程組(判斷adj是否在SCHED_GROUP_BACKGROUND)是20秒,后臺服務(wù)屬于后臺進(jìn)程組 200秒。
把數(shù)據(jù)封裝成CreateServiceData后,通過Handler調(diào)用如下方法:
透三點的核心原理可以看我寫的的Application創(chuàng)建和BroadcastReceiver原理兩篇文章。來看看Service中都做了什么?
很簡單就是保存了傳遞過來的參數(shù),值得注意的是這個IBinder對象其實就是指ServiceRecord對象。
接著執(zhí)行Service.onCreate這個空實現(xiàn)的方法。
本質(zhì)上還是調(diào)用了ActiveServices的serviceDoneExecutingLocked方法。
type是SERVICE_DONE_EXECUTING_ANON,所不會做更多的處理。 最后執(zhí)行了serviceDoneExecutingLocked方法。
這個方法不斷的循環(huán)遍歷ListServiceStartArgs分發(fā)SERVICE_ARGS消息,這個消息通過主線程的Looper調(diào)用handleServiceArgs。
bindService在開發(fā)中用的不是很多,這里稍微提一下他的使用。
首先申明一個ServiceConnection對象,用于綁定服務(wù)端的Service。
調(diào)用bindService的方法綁定到某個Service中。當(dāng)服務(wù)端的service成功回調(diào)onBind方法,我們只需要返回對應(yīng)的Binder對象。就能使用調(diào)用bindService的客戶端在ServiceConnection的onServiceConnected的回調(diào)中獲得Binder對象。
之后就能通過這個Binder調(diào)用本進(jìn)程或者其他進(jìn)程的的方法了。實際上我們可以把這個過程看成一個多對多的服務(wù)-客戶端模型。多個客戶端通過Binder向多服務(wù)端Service通信,每一次我們都可以通過ComponentName判斷不同服務(wù)返回來的Binder對象。
這里面很簡單,和BroadcastReceiver的思路很像。動態(tài)注冊的BroadcastReceiver會封裝成一個ReceiverDispatcher,而這里把ServiceConnection封裝成LoadedApk.ServiceDispatcher對象。
并且會把ServiceDispatcher作為value,ServiceConnection作為key緩存一個map中。并且以context為key,把這個臨時的map作為value緩存起來。這樣一個Context就映射有了多個ServiceDispatcher對象,也就可以注冊多個監(jiān)聽被綁定Service狀態(tài)的監(jiān)聽者了。
CoAP(Constrained Application Protocol)也叫做“受限應(yīng)用協(xié)議”是一種在物聯(lián)網(wǎng)世界的類web協(xié)議,它的詳細(xì)規(guī)范定義在 RFC 7252。參考如下兩篇博客學(xué)習(xí)更多關(guān)于CoAP信息。
CoAP簡介
CoAP協(xié)議使用
Andlink是中國移動提出的一套設(shè)備接入和管理的協(xié)議,實現(xiàn)方式復(fù)雜,在此不做過多描述,該協(xié)議可進(jìn)行設(shè)備與網(wǎng)關(guān)之間通信,從而實現(xiàn)設(shè)備綁定和管控。Andlink采用CoAP或MQTT作為通信協(xié)議。
1、APP進(jìn)入網(wǎng)關(guān)綁定頁面,確認(rèn)wifi是否開啟(如果未開啟,提示用戶開啟wifi并綁定到與網(wǎng)關(guān)相同wifi下
2、進(jìn)入網(wǎng)關(guān)綁定頁后,APP在局域網(wǎng)中每隔1秒發(fā)送/qlink/searchdevice的廣播,同時調(diào)用全屋平臺startBind接口
3、收到網(wǎng)關(guān)反饋,確認(rèn)產(chǎn)品id與網(wǎng)關(guān)一致后,向網(wǎng)關(guān)發(fā)送配網(wǎng)信息,注意這里"CGW"地址隨開發(fā)測試環(huán)境不同改變
4、網(wǎng)關(guān)入網(wǎng)成功后,會發(fā)送/qlink/success的廣播消息
5、網(wǎng)關(guān)綁定成功后,會發(fā)送/qlink/regist的廣播消息,包含設(shè)備ID
6、后臺給APP推送一條網(wǎng)關(guān)綁定成功的消息,接收到該消息后,跳出綁定成功界面
分享名稱:android綁定,android綁定qt庫
文章轉(zhuǎn)載:http://chinadenli.net/article34/dsicppe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司、建站公司、搜索引擎優(yōu)化、Google、小程序開發(fā)、網(wǎng)站排名
聲明:本網(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)