編輯:關於Android編程
// ActivityA中注冊廣播接收器
class ActivityA extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
User person = intent.getParcelableExtra("user") ;
}
}, new IntentFilter("my_action")) ;
}
// ......
}
// ActivityB中發布廣播
class ActivityB extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent("my_action") ;
intent.putExtra("user", new User("mr.simple")) ;
sendBroadcast(intent);
}
// ......
}
// 實體類實現序列化
class User implements Parcelable {
String name ;
public User(String aName) {
name = aName ;
}
// 代碼省略
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
}
是不是有很麻煩的感覺!事件總線框架就是為了簡化這些操作,並且降低組件之間的耦合而出現的。
AndroidEventBus是一個Android平台輕量級的事件總線框架, 它簡化了Activity、Fragment、Service等組件之間的交互,很大程度上降低了它們之間的耦合,使得我們的代碼更加簡潔,耦合性更低,提升我們的代碼質量。
在往下看之前,你可以考慮這麼一個場景,兩個Fragment之間的通信你會怎麼實現?
按照Android官方給的建議的解決方法如下: Communicating with the Activity,思路就是Activity實現某個接口,然後在Fragment-A關聯上Activity之後將Activity強轉為接口類型,然後在某個時刻Fragment中回調這個接口,然後再從Activity中調用Fragment-B中方法。這個過程是不是有點復雜呢? 如果你也這麼覺得,那也就是你繼續看下去的理由了。
AndroidEventBus類似於觀察者模式,通過register函數將需要訂閱事件的對象注冊到事件總線中,然後根據@Subcriber注解來查找對象中的訂閱方法,並且將這些訂閱方法和訂閱對象存儲在map中。當用戶在某個地方發布一個事件時,事件總線根據事件的參數類型和tag找到對應的訂閱者對象,最後執行訂閱者對象中的方法。這些訂閱方法會執行在用戶指定的線程模型中,比如mode=ThreadMode.ASYNC則表示該訂閱方法執行在子線程中,更多細節請看下面的說明。
private void onEventMainThread(User aUser) {
// code
}
如果你有兩個同參數類型的接收函數,並且都要執行在主線程,那如何命名呢 ? 即使你有兩個符合要求的函數吧,那麼我實際上是添加用戶的事件,但是由於EventBus只根據事件參數類型來判斷接收函數,因此會導致兩個函數都會被執行。AndroidEventBus的策略是為每個事件添加一個tag,參數類型和tag共同標識一個事件的唯一性,這樣就確保了事件的精確投遞。
這就是AndroidEventBus和greenrobot的EventBus的不同,但是由於本人對greenrobot的EventBus並不是很了解,很可能上述我所說的有誤,如果是那樣,歡迎您指出。
AndroidEventBus起初只是為了學習,但是在學習了EventBus的實現之後,發現它在使用上有些不便之處,我想既然我有這些感覺,應該也是有同感之人,在開發群裡交流之後,發現確實有這樣的情況。因此才將正式地AndroidEventBus以開源庫的形式推出來,希望能夠幫助到一些需要的人。當然,這個庫的成長需要大家的支持與測試,歡迎大家發 pull request。
你可以按照下面幾個步驟來使用AndroidEventBus.
1 注冊事件接收對象public class YourActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// 注冊對象
EventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
// 不要忘記注銷!!!!
EventBus.getDefault().unregister(this);
super.onDestroy();
}
}
2 通過Subscriber注解來標識事件接收對象中的接收方法
public class YourActivity extends Activity {
// code ......
// 接收方法,默認的tag,執行在UI線程
@Subcriber
private void updateUser(User user) {
Log.e("", "### update user name = " + user.name);
}
// 含有my_tag,當用戶post事件時,只有指定了"my_tag"的事件才會觸發該函數,執行在UI線程
@Subcriber(tag = "my_tag")
private void updateUserWithTag(User user) {
Log.e("", "### update user with my_tag, name = " + user.name);
}
// 含有my_tag,當用戶post事件時,只有指定了"my_tag"的事件才會觸發該函數,
// post函數在哪個線程執行,該函數就執行在哪個線程
@Subcriber(tag = "my_tag", mode=ThreadMode.POST)
private void updateUserWithMode(User user) {
Log.e("", "### update user with my_tag, name = " + user.name);
}
// 含有my_tag,當用戶post事件時,只有指定了"my_tag"的事件才會觸發該函數,執行在一個獨立的線程
@Subcriber(tag = "my_tag", mode = ThreadMode.ASYNC)
private void updateUserAsync(User user) {
Log.e("", "### update user async , name = " + user.name + ", thread name = " + Thread.currentThread().getName());
}
}
接收函數使用tag來標識可接收的事件類型,與BroadcastReceiver中指定action是一樣的,這樣可以精准的投遞消息。mode可以指定目標函數執行在哪個線程,默認會執行在UI線程,方便用戶更新UI。目標方法執行耗時操作時,可以設置mode為ASYNC,使之執行在子線程中。
3 在其他組件,例如Activity, Fragment,Service中發布事件 EventBus.getDefault().post(new User("android"));
// post a event with tag, the tag is like broadcast's action
EventBus.getDefault().post(new User("mr.simple"), "my_tag");
發布事件之後,注冊了該事件類型的對象就會接收到響應的事件.
歡迎star和fork, AndroidEventBus框架 。
引言接Android變形(Transform)之Matrix,來總結下Camera的使用,Camera主要實現3D的變形,有轉動,旋轉等,Camera的源碼是由Nativ
GridView網格視圖,網格視圖組件,九宮圖顯示數據表格(一種控件)ScrollView滾動視圖是一個單一容器,只能包含一個組件。ViewPager左右滑動SlideM
1,創建dialog的布局,如 2,在style中聲明如下風格 1
ACdream 1210 Chinese Girls' Amusement (規律+數學)【題意】: 求最大的k<=n/2使得gcd(n,k)=1。&nbs