編輯:關於Android編程
如果對於AndroidEventBus不了解的同學請移步 AndroidEventBus的設計與實現。AndroidEventBus庫的github地址在這裡。
關於Sticky事件有的同學可能不是很熟悉,Sticky的意思是粘性的。在Android開發中,Sticky事件只指事件消費者在事件發布之後才注冊的也能接收到該事件的特殊類型。Android中就有這樣的實例,也就是Sticky Broadcast,即粘性廣播。正常情況下如果發送者發送了某個廣播,而接收者在這個廣播發送後才注冊自己的Receiver,這時接收者便無法接收到剛才的廣播,為此Android引入了StickyBroadcast,在廣播發送結束後會保存剛剛發送的廣播(Intent),這樣當接收者注冊完Receiver後就可以接收到剛才已經發布的廣播。這就使得我們可以預先處理一些事件,讓有消費者時再把這些事件投遞給消費者。
AndroidEventBus也提供了這樣的功能,有所不同是AndroidEventBus會存儲所有的Sticky事件,如果某個事件在不需要再存儲則需要手動進行移除。用戶通過Sticky的形式發布事件,而消費者也需要通過Sticky的形式進行注冊,當然這種注冊除了可以接收Sticky事件之外和常規的注冊功能是一樣的,其他類型的事件也會被正常處理。發布、接收Sticky事件的步驟有如下幾步 :
1、發布Sticky事件;
EventBus.getDefault().postSticky("hello");
2、 某個時刻訂閱者以Sticky的形式注冊
public class MyReceiver {
public MyReceiver() {
EventBus.getDefault().registerSticky(this);
}
@Subscriber
private void onStickyEvent(String info) {
System.out.println("接收到事件 : " + info);
}
}
當在某個時刻構造MyReceiver時就會將MyReceiver對象以Sticky的形式注冊到EventBus中,此時先前發布的”hello”事件就會被MyReceiver對象接收到,因此就會執行onStickyEvent
函數,在該函數中實現具體的邏輯即可。當然,不要忘了在某個時刻將MyReceiver注銷,以弱引用的形式持有訂閱者的功能還沒有完成吶!整個過程就這樣結束了~
上文中我們簡單講述了Sticky事件的基本使用步驟,這裡我們以一個具體的示例來看看Sticky事件在開發中的使用場景。
在開發過程中,我們經常需要在Activity之間傳值,我們的做法就是將數據塞到Intent中,並且為每個數據設置一個key。當我們傳遞的數據是一個實體類時,我們的這個類還需要實現序列化接口,比如Parcelable或者Serializable。例如我們需要將一個用戶對象傳遞到用戶個人信息展示頁面。我們的常規做法是這樣的:
User.java類 :
// 實體類實現序列化
public class User implements Parcelable {
String name ;
String phoneNum;
// 其他字段省略
public User(String aName) {
name = aName ;
}
public User(Parcel in) {
super(in);
name = in.readString();
phoneNum = in.readString();
}
// 代碼省略
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(phoneNum);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
然後我們要在某個Activity中將這個用戶數據傳遞給個人信息界面ProfileActivity。代碼如下 :
public class MainActivity extends Activity {
// 某個點擊事件
@Override
public void onClick(View v) {
User aUser = new User("Mr.Simple");
aUser.phoneNum = "123456";
// 其他數據
Intent intent = new Intent(this, ProfileActivity.class);
intent.putParcelable("user", aUser);
startActivity(intent);
}
}
在某個點擊事件的處理函數中我們通過Intent將數據傳遞給ProfileActivity。我們再看看ProfileActivity從Intent中取出數據的代碼。
public class ProfileActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
// 從Bundle中獲取數據
Bundle extraBundle = getIntent().getExtras();
if (extraBundle != null) {
User user = extraBundle.getParcelable("user");
}
}
}
OK,至此整個過程才算結束了。
大哥,我只是需要傳個數據啊!何苦啊!
這種方式產生了很多的樣板代碼,也讓邏輯變得更復雜,容易出錯。我們再看看使用Sticky事件的實現方式。
User.java類 :
// 實體類實現序列化
public class User {
String name ;
String phoneNum;
// 其他字段省略
public User(String aName) {
name = aName ;
}
// 代碼省略
}
首先User類不需要實現序列化接口,避免了那些樣板代碼。然後在MainActivity中直接將User對象作為Sticky事件發布即可。
public class MainActivity extends Activity {
// 某個點擊事件
@Override
public void onClick(View v) {
User aUser = new User("Mr.Simple");
aUser.phoneNum = "123456";
// 其他數據
// 發布Sticky事件
EventBus.getDefault().postSticky(aUser);
// 跳轉到ProfileActivity頁面
Intent intent = new Intent(this, ProfileActivity.class);
startActivity(intent);
}
}
最後我們看看ProfileActivity如何接收數據。
public class ProfileActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
// 以Sticky的形式注冊
EventBus.getDefault().registerSticky(this);
}
@Subscriber
private void receiveUser(User info){
// 這裡實現你的邏輯即可, info即為傳遞過來的User對象
}
}
在ProfileActivity中我們將ProfileActivity自身作為訂閱者注冊到總線當中,此時ProfileActivity就會接收到上面發布的Sticky事件,這個事件對象就是User對象。此時就會觸發ProfileActivity 中的receiveUser函數,info參數就是Sticky事件的那個用戶信息對象,在receiveUser中實現自己的邏輯即可。
是的!我們並沒有在onDestory中對訂閱者進行注銷,也就是沒有調用EventBus的unregister()函數,這就是最新版的特性之一,也是目前唯一不需要手動注銷的事件總線庫。
問題是不是簡單了很多~ 還有什麼場景可以使用Sticky事件呢?Sticky事件是否應該消費完之後自動移除?這些問題大家可以自行思考或者給我留言([email protected]),謝謝。
最近寫博客的時間,都是在晚上圖書館學習回到宿捨後,大概是11點半開始寫,寫著寫著就1點多了,這還是我積累的比較充分了的情況下的,然後自己要看一遍再睡覺。第二天早上還要審稿
當我們第一次下載QQ並且打開的時候,會有一個新手引導,引導是幾張圖片,再加上一些文字說明,向右滑動,直到結束,今天一大早起來研究了一下關於此種效果的實現之ViewPage
(1)管理系統實現的功能主要是:學生、教師的注冊登錄,和選課,以及修改學生的成績等基本簡單的功能,最主要的是實現一些Dialog的使用。界面如下:(2)主要代碼如下:(個
在android 6.0中google終於給android系統加上了指紋識別的支持,這個功能在iPhone上早就已經實現了,並且在很多廠商的定制的ROM中也都自己內部實現