Android开发中数据变化监听的5种方式

一、Broadcast之BroadcastReciever

二、SharedPreferences 之 OnSharedPreferenceChangeListener()

三、ContentProvider 之 ContentObserver

四、Flutter 数据监听之 EventBus

五、Flutter 数据监听之 ChangeNotifier

日常Android开发中总会遇到数据变化监听的需求,譬如一个数据变化需要多个页面或者activity内容同时更新。 而Android中通知数据变化的方式有多种,具体使用哪种需要根据具体情况而定。

一、Broadcast之BroadcastReciever

顾名思义,这类数据变化的监听过程是,数据变化-> 发送广播->接收广播->处理广播

具体使用方法如下:

1、数据变化时发送广播

Intent intent = new Intent(“android.action..ZZZZZZZ”);

intent.putExtra("data", “zzzzzzz”);

mContext.sendBroadcast(intent);

2、数据使用方要注册receiver

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
   @Override
   public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      if (action.equals(“android.action..ZZZZZZZ”)) {
        ///ZZZZZ        
      }
   }
};


registerReceiver(mReceiver, new IntentFilter( “android.action..ZZZZZZZ”));

3、退出时要注销reciever

unregisterReceiver(mReceiver);

二、SharedPreferences 之 OnSharedPreferenceChangeListener()

SharedPreference 是一种简单的数值存储模式,实际上是存在一个 设备安装目录的shared_prefs路径下面的xml文件里

当文件内容变化时, 会回调 OnSharedPreferenceChangeListener()

1、通常情况下可能会这样写

PreferenceManager.getDefaultSharedPreferences(getApplicationContext())

  .registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() {

  @Override

  public void onSharedPreferenceChanged(

   SharedPreferences sharedPreferences, String key) {

   Log.i(LOGTAG, "testOnSharedPreferenceChangedWrong key =" + key);

  }

 });


2、但是这种方法因为弱引用的关系,一旦被垃圾回收回调就不会被调用

private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =

   new WeakHashMap<OnSharedPreferenceChangeListener, Object>();

//some code goes here

public void More ...registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {

 synchronized(this) {

  mListeners.put(listener, mContent);

 }

}

3、正确的解决方法是,在onResume里注册回调,在onPause里注销回调

@Override

protected void onResume() {

    super.onResume();  getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(mOnSharedPreferenceChangeListener);

    }

@Override

protected void onPause() {

    super.onPause();

    getPreferenceScreen().getSharedPreferences()

.unregisterOnSharedPreferenceChangeListener(mOnSharedPreferenceChangeListener);

    }


但是这个监听只能当前正在显示的activity里有效,其他activity里依然监听不到数据变化,因为其他activity处于onPause状态

三、ContentProvider 之 ContentObserver

通常情况下当android本地数据库发生变化时,会发出通知,然后对应的contentObserver 接收通知,并重新读取数据更新UI.

1、定义contentURI

public static final Uri CONTENT_URI = Uri.parse("content://ZZZZZZZZZ");

2、当对应数据库发生变化时,发出通知

context.getContentResolver().notifyChange(CONTENT_URI, null);

3、数据库使用方注册contentObserver

context.getApplicationContext().getContentResolver().registerContentObserver(CONTENT_URI, true, mContentObserver);

private ContentObserver mContentObserver = new ContentObserver(mHandler) {
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
       /ZZZZZZZZZZZZZZZZZZZ    }
};

上面三种是使用java 代码框架时的三种方式,下面两种是Flutter/dart 代码框架的两种数据监听方式

四、Flutter 数据监听之 EventBus

在flutter开发中经常会遇到子widget传递消息给父widget的场景,这时需要类似通知或者广播的方法,EventBus就是解决这类问题的。

具体使用方法如下:

1、封装一个eventBus 事件总线的文件

// 引入 eventBus 包文件

    import 'package:event_bus/event_bus.dart';

    // 创建EventBus

    EventBus eventBus = new EventBus();

    // event 监听

    class EventFn{

        // 想要接收的数据时什么类型的,就定义相同类型的变量

        final bool msg;

        EventFn(this.msg);

}

2、需要发送事件的文件中利用 eventBus.fire 发送事件

//引入封装的e vent_bus.dart 文件

    import 'package:new_flutter/utils/event_bus.dart';

    //数据发生变化后, 调用 eventBus.fire 发送事件信息,通知监听方

    eventBus.fire(EventFn({

               false

       }));

3、在需要监听的文件中,利用 eventBus.on< >().listen() 监听信息

    // 注册监听器,订阅 eventbus

    var eventBusFn = eventBus.on<EventFn>().listen((event) {

        // event.msg 就是传过来的监听数据

       });

4、 在组件销毁时,一定要销毁监听,防止内存泄漏

    @override

    void dispose() {

        super.dispose();

        //取消订阅

        eventBusFn.cancel();

    }

 五、Flutter 数据监听之 ChangeNotifier

Flutter 真正直接监听数据变化的是ChangeNotifier,使用者只要addListener就行了,

具体使用方法如下:

1、封装一个ChangeNotifier

class YkqInfo extends ChangeNotifier{

//要监控的数据类型,想定义什么类型就定义什么类型
  static String  ykqQr = "";
  static YkqInfo _instance;

  static YkqInfo getInstance(){
    if(_instance == null) {
      _instance = new YkqInfo();
    }
    return _instance;
  }



  setYkqUrl(String qrUrl){
    ykqQr = qrUrl;

//通知监听方数据更新
    notifyListeners();
  }

}

2、数据变化时,刷新ChangeNotifier里的数据

YkqInfo.getInstance().setYkqUrl(qrUrl);

3、数据监听方addListener,并实时回调刷新

YkqInfo.getInstance().addListener(() {
              // 监听数据发生变化并处理

         //有必要的话进行UI页面刷新

        setState(() {
        });
     });

上一篇:k8s实战之Service


下一篇:android插件化好处,网络相关+Android三方库的源码分析+数据结构与算法,看完没有不懂的